diff --git a/DEPS b/DEPS index 2dbff98..067bcc2 100644 --- a/DEPS +++ b/DEPS
@@ -52,7 +52,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': 'fd8b469ebc8f63d0579cb62da94fe5d393503a78', + 'angle_revision': 'c1a5d16e964ad524487eac9d2e4b5a65d837ff27', # 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. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '95bec8046a28928df627ce4d48eee8b209b3e36e', + 'pdfium_revision': '341b5c2c1cbd310d29ef3db2dbea1ec9b1b981ec', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '1e05d2f8401ce9b112c2f0e21269f1d7493ce88b', + 'catapult_revision': 'fe2fa4bc83c5a2ffbc1be54ebbdece0db8473335', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/common/wm_shell.cc b/ash/common/wm_shell.cc index 075d6d2b..0674f7a 100644 --- a/ash/common/wm_shell.cc +++ b/ash/common/wm_shell.cc
@@ -293,13 +293,13 @@ base::MakeUnique<WindowSelectorController>()) { session_controller_->AddSessionStateObserver(this); - prefs::mojom::PreferencesManagerPtr pref_manager_ptr; + prefs::mojom::PreferencesFactoryPtr pref_factory_ptr; // Can be null in tests. if (!delegate_->GetShellConnector()) return; delegate_->GetShellConnector()->BindInterface(prefs::mojom::kServiceName, - &pref_manager_ptr); - pref_store_ = new preferences::PrefObserverStore(std::move(pref_manager_ptr)); + &pref_factory_ptr); + pref_store_ = new preferences::PrefObserverStore(std::move(pref_factory_ptr)); } RootWindowController* WmShell::GetPrimaryRootWindowController() {
diff --git a/ash/content/keyboard_overlay/keyboard_overlay_delegate.cc b/ash/content/keyboard_overlay/keyboard_overlay_delegate.cc index 14af0f5..bc79aca67 100644 --- a/ash/content/keyboard_overlay/keyboard_overlay_delegate.cc +++ b/ash/content/keyboard_overlay/keyboard_overlay_delegate.cc
@@ -78,10 +78,9 @@ // Show the widget at the bottom of the work area. gfx::Size size; GetDialogSize(&size); - const gfx::Rect& rect = - display::Screen::GetScreen() - ->GetDisplayNearestWindow(widget_->GetNativeView()) - .work_area(); + const gfx::Rect rect = display::Screen::GetScreen() + ->GetDisplayNearestWindow(widget_->GetNativeView()) + .work_area(); gfx::Rect bounds(rect.x() + (rect.width() - size.width()) / 2, rect.y() + (rect.height() - size.height()) / 2, size.width(), size.height());
diff --git a/ash/frame/caption_buttons/frame_size_button_unittest.cc b/ash/frame/caption_buttons/frame_size_button_unittest.cc index a14c83d6..7674b9b 100644 --- a/ash/frame/caption_buttons/frame_size_button_unittest.cc +++ b/ash/frame/caption_buttons/frame_size_button_unittest.cc
@@ -331,9 +331,9 @@ EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon()); EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon()); - const gfx::Rect& kWorkAreaBoundsInScreen = + const gfx::Rect work_area_bounds_in_screen = display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); - generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left()); + generator.MoveMouseTo(work_area_bounds_in_screen.bottom_left()); // None of the buttons should be pressed because we are really far away from // any of the caption buttons. The minimize and close button icons should @@ -382,9 +382,9 @@ // Moving the mouse far away from the caption buttons and then moving it over // the close button (snap right button) should hover the close button and // keep the size button pressed. - const gfx::Rect& kWorkAreaBoundsInScreen = + const gfx::Rect work_area_bounds_in_screen = display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); - generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left()); + generator.MoveMouseTo(work_area_bounds_in_screen.bottom_left()); EXPECT_TRUE(AllButtonsInNormalState()); generator.MoveMouseTo(CenterPointInScreen(close_button())); EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
diff --git a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc index d40daa8..3ae5f22f 100644 --- a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc +++ b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
@@ -71,7 +71,7 @@ } Position GetPositionInDisplay(const gfx::Point& point) { - const gfx::Rect& work_area = + const gfx::Rect work_area = display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); const gfx::Point center_point = work_area.CenterPoint(); if (work_area.x() > point.x() || work_area.y() > point.y() ||
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py index 31eba17..2aaf88b 100644 --- a/build/android/pylib/local/device/local_device_environment.py +++ b/build/android/pylib/local/device/local_device_environment.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import contextlib import datetime import functools import logging @@ -20,6 +21,8 @@ from devil.utils import parallelizer from pylib import constants from pylib.base import environment +from py_trace_event import trace_event +from tracing_build import trace2html def _DeviceCachePath(device): @@ -90,6 +93,7 @@ self._skip_clear_data = args.skip_clear_data self._target_devices_file = args.target_devices_file self._tool_name = args.tool + self._trace_output = args.trace_output #override def SetUp(self): @@ -144,6 +148,15 @@ self.parallel_devices.pMap(prepare_device) + @staticmethod + def _JsonToTrace(json_path, html_path, delete_json=True): + # First argument is call site. + cmd = [__file__, json_path, '--title', 'Android Test Runner Trace', + '--output', html_path] + trace2html.Main(cmd) + if delete_json: + os.remove(json_path) + @property def blacklist(self): return self._blacklist @@ -178,6 +191,10 @@ def tool(self): return self._tool_name + @property + def trace_output(self): + return self._trace_output + #override def TearDown(self): if self._devices is None: @@ -231,3 +248,24 @@ with self._devices_lock: self._devices = [d for d in self._devices if str(d) != device_serial] + def DisableTracing(self): + if not trace_event.trace_is_enabled(): + logging.warning('Tracing is not running.') + else: + trace_event.trace_disable() + self._JsonToTrace(self._trace_output + '.json', + self._trace_output) + + def EnableTracing(self): + if trace_event.trace_is_enabled(): + logging.warning('Tracing is already running.') + else: + trace_event.trace_enable(self._trace_output + '.json') + + @contextlib.contextmanager + def Tracing(self): + try: + self.EnableTracing() + yield + finally: + self.DisableTracing()
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py index b25b1762..e99c4a55 100644 --- a/build/android/pylib/local/device/local_device_gtest_run.py +++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -19,6 +19,8 @@ from pylib.local import local_test_server_spawner from pylib.local.device import local_device_environment from pylib.local.device import local_device_test_run +from py_trace_event import trace_event +from py_utils import contextlib_ext import tombstones _MAX_INLINE_FLAGS_LENGTH = 50 # Arbitrarily chosen. @@ -371,29 +373,35 @@ #override def _RunTest(self, device, test): # Run the test. - timeout = (self._test_instance.shard_timeout - * self.GetTool(device).GetTimeoutScale()) - if self._test_instance.store_tombstones: - tombstones.ClearAllTombstones(device) - with device_temp_file.DeviceTempFile( - adb=device.adb, - dir=self._delegate.ResultsDirectory(device), - suffix='.xml') as device_tmp_results_file: + with contextlib_ext.Optional( + self._env.Tracing(), + self._env.trace_output): + timeout = (self._test_instance.shard_timeout + * self.GetTool(device).GetTimeoutScale()) + if self._test_instance.store_tombstones: + tombstones.ClearAllTombstones(device) + with device_temp_file.DeviceTempFile( + adb=device.adb, + dir=self._delegate.ResultsDirectory(device), + suffix='.xml') as device_tmp_results_file: - flags = self._test_instance.test_arguments or '' - if self._test_instance.enable_xml_result_parsing: - flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name - if self._test_instance.gtest_also_run_disabled_tests: - flags += ' --gtest_also_run_disabled_tests' + flags = self._test_instance.test_arguments or '' + if self._test_instance.enable_xml_result_parsing: + flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name + if self._test_instance.gtest_also_run_disabled_tests: + flags += ' --gtest_also_run_disabled_tests' - output = self._delegate.Run( - test, device, flags=flags, - timeout=timeout, retries=0) + with contextlib_ext.Optional( + trace_event.trace(str(test)), + self._env.trace_output): + output = self._delegate.Run( + test, device, flags=flags, + timeout=timeout, retries=0) - if self._test_instance.enable_xml_result_parsing: - gtest_xml = device.ReadFile( - device_tmp_results_file.name, - as_root=True) + if self._test_instance.enable_xml_result_parsing: + gtest_xml = device.ReadFile( + device_tmp_results_file.name, + as_root=True) for s in self._servers[str(device)]: s.Reset()
diff --git a/build/android/pylib/local/device/local_device_perf_test_run.py b/build/android/pylib/local/device/local_device_perf_test_run.py index b34c360..77f1a4e 100644 --- a/build/android/pylib/local/device/local_device_perf_test_run.py +++ b/build/android/pylib/local/device/local_device_perf_test_run.py
@@ -102,7 +102,7 @@ with contextlib_ext.Optional( trace_event.trace(test), - self._test_instance.trace_output): + self._env.trace_output): exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout( cmd, timeout, cwd=cwd, shell=True) end_time = time.time() @@ -424,14 +424,6 @@ #override def RunTests(self): - # Affinitize the tests. - if self._test_instance.trace_output: - assert not trace_event.trace_is_enabled(), 'Tracing already running.' - trace_event.trace_enable(self._test_instance.trace_output + '.json') - self._SplitTestsByAffinity() - if not self._test_buckets and not self._no_device_tests: - raise local_device_test_run.NoTestsError() - def run_no_devices_tests(): if not self._no_device_tests: return [] @@ -463,14 +455,17 @@ device_shard_helper) return [x for x in shards.pGet(self._timeout) if x is not None] - host_test_results, device_test_results = reraiser_thread.RunAsync( - [run_no_devices_tests, run_devices_tests]) - if self._test_instance.trace_output: - assert trace_event.trace_is_enabled(), 'Tracing not running.' - trace_event.trace_disable() - local_device_test_run.LocalDeviceTestRun._JsonToTrace( - self._test_instance.trace_output + '.json', - self._test_instance.trace_output) + # Run the tests. + with contextlib_ext.Optional( + self._env.Tracing(), + self._env.trace_output): + # Affinitize the tests. + self._SplitTestsByAffinity() + if not self._test_buckets and not self._no_device_tests: + raise local_device_test_run.NoTestsError() + host_test_results, device_test_results = reraiser_thread.RunAsync( + [run_no_devices_tests, run_devices_tests]) + return host_test_results + device_test_results # override
diff --git a/build/android/pylib/local/device/local_device_test_run.py b/build/android/pylib/local/device/local_device_test_run.py index 2b82c8e..1d7ebdf8 100644 --- a/build/android/pylib/local/device/local_device_test_run.py +++ b/build/android/pylib/local/device/local_device_test_run.py
@@ -5,7 +5,6 @@ import fnmatch import imp import logging -import os import posixpath import signal import thread @@ -17,7 +16,6 @@ from pylib.base import test_run from pylib.base import test_collection from pylib.local.device import local_device_environment -from tracing_build import trace2html _SIGTERM_TEST_LOG = ( @@ -205,15 +203,6 @@ def _ShouldShard(self): raise NotImplementedError - @staticmethod - def _JsonToTrace(json_path, html_path, delete_json=True): - # First argument is call site. - cmd = [__file__, json_path, '--title', 'Android Test Runner Trace', - '--output', html_path] - trace2html.Main(cmd) - if delete_json: - os.remove(json_path) - class NoTestsError(Exception): """Error for when no tests are found."""
diff --git a/build/android/pylib/perf/perf_test_instance.py b/build/android/pylib/perf/perf_test_instance.py index 3ccc8d3..c897f18 100644 --- a/build/android/pylib/perf/perf_test_instance.py +++ b/build/android/pylib/perf/perf_test_instance.py
@@ -81,7 +81,6 @@ ' '.join(args.single_step_command) if args.single_step else None) self._steps = args.steps self._test_filter = args.test_filter - self._trace_output = args.trace_output self._write_buildbot_json = args.write_buildbot_json #override @@ -266,10 +265,6 @@ def test_filter(self): return self._test_filter - @property - def trace_output(self): - return self._trace_output - class PersistentDataError(base_error.BaseError): def __init__(self, message):
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index b5b4da12..37d565a 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -110,6 +110,10 @@ dest='json_results_file', type=os.path.realpath, help='If set, will dump results in JSON form ' 'to specified file.') + group.add_argument('--trace-output', metavar='FILENAME', + type=os.path.realpath, + help='Path to save test_runner trace data to. This option ' + 'has been implemented for gtest and perf test.') logcat_output_group = group.add_mutually_exclusive_group() logcat_output_group.add_argument( @@ -537,10 +541,6 @@ group.add_argument( '--write-buildbot-json', action='store_true', help='Whether to output buildbot json.') - # TODO(rnephew): Move up to top level options when implemented on all tests. - group.add_argument( - '--trace-output', metavar='FILENAME', type=os.path.realpath, - help='Path to save test_runner trace data to.') AddCommonOptions(parser) AddDeviceOptions(parser)
diff --git a/chrome/android/java/res/layout/custom_tabs_bottombar.xml b/chrome/android/java/res/layout/custom_tabs_bottombar.xml index 18f99ecd..d322e86 100644 --- a/chrome/android/java/res/layout/custom_tabs_bottombar.xml +++ b/chrome/android/java/res/layout/custom_tabs_bottombar.xml
@@ -4,7 +4,6 @@ found in the LICENSE file. --> <org.chromium.chrome.browser.widget.BoundedLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:chrome="http://schemas.android.com/apk/res-auto" - android:id="@+id/bottombar" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" @@ -14,7 +13,6 @@ android:id="@+id/bottombar_shadow" android:layout_width="match_parent" android:layout_height="4dp" - android:background="@drawable/toolbar_shadow_normal" - android:scaleY="-1" /> + android:background="@drawable/infobar_shadow_top" /> </org.chromium.chrome.browser.widget.BoundedLinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/main.xml b/chrome/android/java/res/layout/main.xml index 15801a3..0cec21d 100644 --- a/chrome/android/java/res/layout/main.xml +++ b/chrome/android/java/res/layout/main.xml
@@ -21,6 +21,15 @@ android:layout_height="match_parent" /> <ViewStub + android:id="@+id/bottombar_stub" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="-4dp" + android:layout_gravity="start|bottom" + android:inflatedId="@+id/bottombar" + android:layout="@layout/custom_tabs_bottombar" /> + + <ViewStub android:id="@+id/omnibox_results_container_stub" android:layout_width="match_parent" android:layout_height="match_parent" @@ -65,12 +74,6 @@ android:fillViewport="true" android:scrollbars="none" android:visibility="gone" /> - - <ViewStub - android:id="@+id/bottombar_stub" - android:layout_width="match_parent" - android:layout_marginTop="-4dp" - android:layout_height="wrap_content" /> </LinearLayout> <!-- This empty view is used as the anchor for custom menu -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 936ea13..593dcc21 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -100,7 +100,6 @@ private View mAccessibilityView; private CompositorAccessibilityProvider mNodeProvider; private float mLastContentOffset; - private float mLastVisibleContentOffset; /** The toolbar control container. **/ private ControlContainer mControlContainer; @@ -443,7 +442,6 @@ public void onStart() { if (mFullscreenManager != null) { mLastContentOffset = mFullscreenManager.getContentOffset(); - mLastVisibleContentOffset = mFullscreenManager.getTopVisibleContentOffset(); mFullscreenManager.addListener(this); } requestRender(); @@ -463,8 +461,7 @@ } @Override - public void onVisibleContentOffsetChanged(float offset, boolean needsAnimate) { - mLastVisibleContentOffset = offset; + public void onControlsOffsetChanged(float topOffset, float bottomOffset, boolean needsAnimate) { onViewportChanged(); if (needsAnimate) requestRender(); } @@ -662,7 +659,6 @@ mFullscreenManager = fullscreen; if (mFullscreenManager != null) { mLastContentOffset = mFullscreenManager.getContentOffset(); - mLastVisibleContentOffset = mFullscreenManager.getTopVisibleContentOffset(); mFullscreenManager.addListener(this); } onViewportChanged(); @@ -704,7 +700,7 @@ public float getOverlayTranslateY() { return areBrowserControlsPermanentlyHidden() ? getTopControlsHeightPixels() - : mLastVisibleContentOffset; + : mFullscreenManager.getTopVisibleContentOffset(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java index 765210e6..1e622413 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
@@ -153,9 +153,4 @@ * @param pageUrl URL of the current page. */ void onOpenInChrome(String linkUrl, String pageUrl); - - /** - * Called to queue a task to sometime later make an offline page for this url. - */ - void onSavePageLater(String linkUrl); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 0a7e2e0..dc3c7dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -173,6 +173,8 @@ public void didAddTab(Tab tab, TabLaunchType type) { PageLoadMetrics.addObserver(mMetricsObserver); tab.addObserver(mTabObserver); + getFullscreenManager().setBottomControlsHeight(mBottomBarDelegate.getBottomBarHeight()); + getFullscreenManager().addListener(mBottomBarDelegate); } @Override @@ -433,6 +435,7 @@ finishAndClose(false); } }); + getFullscreenManager().setBottomControlsHeight(mBottomBarDelegate.getBottomBarHeight()); mCustomTabContentHandler = new CustomTabContentHandler() { @Override @@ -689,7 +692,9 @@ return new CustomTabAppMenuPropertiesDelegate(this, mIntentDataProvider.getMenuTitles(), mIntentDataProvider.shouldShowShareMenuItem(), mIntentDataProvider.isOpenedByChrome(), - mIntentDataProvider.isMediaViewer()); + mIntentDataProvider.isMediaViewer(), + mIntentDataProvider.shouldShowStarButton(), + mIntentDataProvider.shouldShowDownloadButton()); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java index e264a259..706fbcf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
@@ -35,6 +35,8 @@ private final boolean mShowShare; private final boolean mIsMediaViewer; + private final boolean mShowStar; + private final boolean mShowDownload; private final List<String> mMenuEntries; private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>(); @@ -47,11 +49,13 @@ */ public CustomTabAppMenuPropertiesDelegate(final ChromeActivity activity, List<String> menuEntries, boolean showShare, final boolean isOpenedByChrome, - final boolean isMediaViewer) { + final boolean isMediaViewer, boolean showStar, boolean showDownload) { super(activity); mMenuEntries = menuEntries; mShowShare = showShare; mIsMediaViewer = isMediaViewer; + mShowStar = showStar; + mShowDownload = showDownload; mDefaultBrowserFetcher = new AsyncTask<Void, Void, String>() { @Override @@ -123,7 +127,8 @@ } updateBookmarkMenuItem(bookmarkItem, currentTab); } - + bookmarkItem.setVisible(mShowStar); + downloadItem.setVisible(mShowDownload); if (!FirstRunStatus.getFirstRunFlowComplete()) { openInChromeItem.setVisible(false); bookmarkItem.setVisible(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index e1df0422..3332351 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -25,6 +25,7 @@ import org.chromium.base.metrics.CachedMetrics; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; import org.chromium.chrome.browser.tab.Tab; import org.chromium.ui.interpolators.BakedBezierInterpolator; @@ -33,7 +34,7 @@ /** * Delegate that manages bottom bar area inside of {@link CustomTabActivity}. */ -class CustomTabBottomBarDelegate { +class CustomTabBottomBarDelegate implements FullscreenListener { private static final String TAG = "CustomTab"; private static final CachedMetrics.ActionEvent REMOTE_VIEWS_SHOWN = new CachedMetrics.ActionEvent("CustomTabsRemoteViewsShown"); @@ -138,12 +139,22 @@ } /** + * @return The height of the bottom bar, excluding its top shadow. + */ + public int getBottomBarHeight() { + if (!mDataProvider.shouldShowBottomBar() || mBottomBarView == null + || mBottomBarView.getChildCount() < 2) { + return 0; + } + return mBottomBarView.getChildAt(1).getHeight(); + } + + /** * Gets the {@link ViewGroup} of the bottom bar. If it has not been inflated, inflate it first. */ private ViewGroup getBottomBarView() { if (mBottomBarView == null) { ViewStub bottomBarStub = ((ViewStub) mActivity.findViewById(R.id.bottombar_stub)); - bottomBarStub.setLayoutResource(R.layout.custom_tabs_bottombar); mBottomBarView = (ViewGroup) bottomBarStub.inflate(); } return mBottomBarView; @@ -199,4 +210,17 @@ Log.e(TAG, "CanceledException when sending pending intent."); } } + + // FullscreenListener methods + @Override + public void onControlsOffsetChanged(float topOffset, float bottomOffset, + boolean needsAnimate) { + if (mBottomBarView != null) mBottomBarView.setTranslationY(bottomOffset); + } + + @Override + public void onContentOffsetChanged(float offset) { } + + @Override + public void onToggleOverlayVideoMode(boolean enabled) { } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index d262fd9..4e474fa5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -66,6 +66,14 @@ public static final String EXTRA_INITIAL_BACKGROUND_COLOR = "org.chromium.chrome.browser.customtabs.EXTRA_INITIAL_BACKGROUND_COLOR"; + /** Extra that enables the client to disable the star button in menu. */ + public static final String EXTRA_DISABLE_STAR_BUTTON = + "org.chromium.chrome.browser.customtabs.EXTRA_DISABLE_STAR_BUTTON"; + + /** Extra that enables the client to disable the download button in menu. */ + public static final String EXTRA_DISABLE_DOWNLOAD_BUTTON = + "org.chromium.chrome.browser.customtabs.EXTRA_DISABLE_DOWNLOAD_BUTTON"; + //TODO(yusufo): Move this to CustomTabsIntent. /** Signals custom tabs to favor sending initial urls to external handler apps if possible. */ public static final String EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER = @@ -87,6 +95,8 @@ private final boolean mIsMediaViewer; private final boolean mIsInfoPage; private final int mInitialBackgroundColor; + private final boolean mDisableStar; + private final boolean mDisableDownload; private int mToolbarColor; private int mBottomBarColor; @@ -169,6 +179,9 @@ && IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_MEDIA_VIEWER, false); mIsInfoPage = mIsTrustedIntent && IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_INFO_PAGE, false); + mDisableStar = IntentUtils.safeGetBooleanExtra(intent, EXTRA_DISABLE_STAR_BUTTON, false); + mDisableDownload = IntentUtils.safeGetBooleanExtra(intent, EXTRA_DISABLE_DOWNLOAD_BUTTON, + false); } /** @@ -484,4 +497,18 @@ int getInitialBackgroundColor() { return mInitialBackgroundColor; } + + /** + * @return Whether there should be a star button in the menu. + */ + boolean shouldShowStarButton() { + return !mDisableStar; + } + + /** + * @return Whether there should be a download button in the menu. + */ + boolean shouldShowDownloadButton() { + return !mDisableDownload; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java index 518d9d44..94e1e69 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
@@ -83,11 +83,13 @@ public void onContentOffsetChanged(float offset); /** - * Called whenever the content's visible offset changes. - * @param offset The new offset of the visible content from the top of the screen. + * Called whenever the controls' offset changes. + * @param topOffset The new value of the offset from the top of the top control. + * @param bottomOffset The new value of the offset from the top of the bottom control. * @param needsAnimate Whether the caller is driving an animation with further updates. */ - public void onVisibleContentOffsetChanged(float offset, boolean needsAnimate); + public void onControlsOffsetChanged(float topOffset, float bottomOffset, + boolean needsAnimate); /** * Called when a ContentVideoView is created/destroyed. @@ -312,6 +314,13 @@ return getBrowserControlHiddenRatio() > 0; } + /** + * Sets the height of the bottom controls. + */ + public void setBottomControlsHeight(int bottomControlsHeight) { + mBottomControlContainerHeight = bottomControlsHeight; + } + @Override public int getTopControlsHeight() { return mTopControlContainerHeight; @@ -462,11 +471,8 @@ // scrolling. boolean needsAnimate = shouldShowAndroidControls(); for (int i = 0; i < mListeners.size(); i++) { - // Since, in the case of bottom controls, the view is never translated, we don't - // need to change the information passed into this method. - // getTopVisibleContentOffset will return 0 which is the expected result. - mListeners.get(i).onVisibleContentOffsetChanged( - getTopVisibleContentOffset(), needsAnimate); + mListeners.get(i).onControlsOffsetChanged( + getTopControlOffset(), getBottomControlOffset(), needsAnimate); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java index 40fc5277..4db9f8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; +import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageNotificationBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; @@ -186,6 +187,7 @@ } private void saveUrlForOffline(String url) { + OfflinePageNotificationBridge.showDownloadingToast(mActivity); OfflinePageBridge.getForProfile(mProfile).savePageLater( url, "ntp_suggestions", true /* userRequested */); }
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 14643a02..9dac7b19 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
@@ -1691,11 +1691,11 @@ new TabContextMenuPopulator( mDelegateFactory.createContextMenuPopulator(this), this)); - final ViewGroup bottomContainer = (ViewGroup) getActivity() - .findViewById(R.id.bottom_container); // In the case where restoring a Tab or showing a prerendered one we already have a // valid infobar container, no need to recreate one. if (mInfoBarContainer == null) { + ViewGroup bottomContainer = (ViewGroup) getActivity() + .findViewById(R.id.bottom_container); // The InfoBarContainer needs to be created after the ContentView has been natively // initialized. mInfoBarContainer = new InfoBarContainer(mThemedApplicationContext, bottomContainer, @@ -2821,6 +2821,15 @@ } /** + * Sets the TabRedirectHandler for the tab. + * + * @param tabRedirectHandler the TabRedirectHandler + */ + public void setTabRedirectHandler(TabRedirectHandler tabRedirectHandler) { + mTabRedirectHandler = tabRedirectHandler; + } + + /** * @return the AppBannerManager. */ public AppBannerManager getAppBannerManager() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index f61ce4b..0d26479 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; @@ -232,12 +231,6 @@ } } - @Override - public void onSavePageLater(String linkUrl) { - OfflinePageBridge.getForProfile(mTab.getProfile()) - .savePageLater(linkUrl, "async_loading", true /* userRequested */); - } - /** * Checks if spdy proxy is enabled for input url. * @param url Input url to check for spdy setting.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 905b8f8..5ad5b770 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.WebContentsFactory; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabRedirectHandler; import org.chromium.content.browser.ContentView; import org.chromium.content.browser.ContentViewCore; import org.chromium.content_public.browser.WebContents; @@ -81,6 +82,8 @@ private boolean mReprojectedRendering; + private TabRedirectHandler mNonVrTabRedirectHandler; + public VrShellImpl(Activity activity) { super(activity); mActivity = activity; @@ -123,6 +126,15 @@ mContentCVC = mTab.getContentViewCore(); mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay); + // Make sure we are not redirecting to another app, i.e. out of VR mode. + mNonVrTabRedirectHandler = mTab.getTabRedirectHandler(); + mTab.setTabRedirectHandler(new TabRedirectHandler(mActivity) { + @Override + public boolean shouldStayInChrome(boolean hasExternalProtocol) { + return true; + } + }); + mUiVrWindowAndroid = new VrWindowAndroid(mActivity, mUiVirtualDisplay); mUiContents = WebContentsFactory.createWebContents(true, false); mUiCVC = new ContentViewCore(mActivity, ChromeVersionInfo.getProductVersion()); @@ -251,6 +263,7 @@ nativeDestroy(mNativeVrShell); mNativeVrShell = 0; } + mTab.setTabRedirectHandler(mNonVrTabRedirectHandler); mTab.updateWindowAndroid(mOriginalWindowAndroid); mContentCVC.onSizeChanged(mContentCVC.getContainerView().getWidth(), mContentCVC.getContainerView().getHeight(), 0, 0);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java index 448fda67..ba1d73ba 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
@@ -420,8 +420,9 @@ fullscreenManager.addListener(new FullscreenListener() { @Override - public void onVisibleContentOffsetChanged(float offset, boolean needsAnimate) { - if (offset != initialVisibleContentOffset) { + public void onControlsOffsetChanged(float topOffset, float bottomOffset, + boolean needsAnimate) { + if (fullscreenManager.getTopVisibleContentOffset() != initialVisibleContentOffset) { contentMovedCallback.notifyCalled(); fullscreenManager.removeListener(this); }
diff --git a/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.cc b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.cc index 32c57a3..5f6daed 100644 --- a/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.cc +++ b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.cc
@@ -32,7 +32,6 @@ constexpr int kPointMoveDurationLongInMs = 500; const SkColor kExitLabelColor = SkColorSetARGBInline(255, 96, 96, 96); -const SkColor kExitLabelShadowColor = SkColorSetARGBInline(255, 11, 11, 11); constexpr int kExitLabelWidth = 300; constexpr int kExitLabelHeight = 20; @@ -414,10 +413,9 @@ exit_label_->SetBounds((display_.bounds().width() - kExitLabelWidth) / 2, display_.bounds().height() * 3.f / 4, kExitLabelWidth, kExitLabelHeight); + exit_label_->SetAutoColorReadabilityEnabled(false); exit_label_->SetEnabledColor(kExitLabelColor); exit_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); - exit_label_->SetShadows(gfx::ShadowValues( - 1, gfx::ShadowValue(gfx::Vector2d(1, 1), 1, kExitLabelShadowColor))); exit_label_->SetSubpixelRenderingEnabled(false); exit_label_->SetVisible(false);
diff --git a/chrome/browser/component_updater/origin_trials_component_installer.cc b/chrome/browser/component_updater/origin_trials_component_installer.cc index 08712ea..9378dcf 100644 --- a/chrome/browser/component_updater/origin_trials_component_installer.cc +++ b/chrome/browser/component_updater/origin_trials_component_installer.cc
@@ -44,11 +44,11 @@ static const char kManifestDisabledFeaturesPath[] = "origin-trials.disabled-features"; -// Extension id is kfoklmclfodeliojeaekpoflbkkhojea -const uint8_t kSha256Hash[] = {0xa5, 0xea, 0xbc, 0x2b, 0x5e, 0x34, 0xb8, 0xe9, - 0x40, 0x4a, 0xfe, 0x5b, 0x1a, 0xa7, 0xe9, 0x40, - 0xa8, 0xc5, 0xef, 0xa1, 0x9e, 0x20, 0x5a, 0x39, - 0x73, 0x98, 0x98, 0x0f, 0x7a, 0x76, 0x62, 0xfa}; +// Extension id is llkgjffcdpffmhiakmfcdcblohccpfmo +const uint8_t kSha256Hash[] = {0xbb, 0xa6, 0x95, 0x52, 0x3f, 0x55, 0xc7, 0x80, + 0xac, 0x52, 0x32, 0x1b, 0xe7, 0x22, 0xf5, 0xce, + 0x6a, 0xfd, 0x9c, 0x9e, 0xa9, 0x2a, 0x0b, 0x50, + 0x60, 0x2b, 0x7f, 0x6c, 0x64, 0x80, 0x09, 0x04}; } // namespace
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc index 9d2923b..b6dd2d3 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc
@@ -19,6 +19,9 @@ namespace extensions { namespace { + +const char kEasyUnlockFeatureName[] = "easy_unlock"; + api::easy_unlock_private::ConnectionStatus ToApiConnectionStatus( Connection::Status status) { switch (status) { @@ -31,6 +34,7 @@ } return api::easy_unlock_private::CONNECTION_STATUS_NONE; } + } // namespace EasyUnlockPrivateConnectionManager::EasyUnlockPrivateConnectionManager( @@ -98,7 +102,8 @@ const std::string& payload) { Connection* connection = GetConnection(extension->id(), connection_id); if (connection && connection->IsConnected()) { - connection->SendMessage(base::MakeUnique<WireMessage>(payload)); + connection->SendMessage(base::MakeUnique<WireMessage>( + payload, std::string(kEasyUnlockFeatureName))); return true; } return false; @@ -123,6 +128,11 @@ void EasyUnlockPrivateConnectionManager::OnMessageReceived( const Connection& connection, const WireMessage& message) { + if (message.feature() != std::string(kEasyUnlockFeatureName)) { + // Only process messages received as part of EasyUnlock. + return; + } + std::string event_name = api::easy_unlock_private::OnDataReceived::kEventName; events::HistogramValue histogram_value = events::EASY_UNLOCK_PRIVATE_ON_DATA_RECEIVED; @@ -137,6 +147,11 @@ const Connection& connection, const WireMessage& message, bool success) { + if (message.feature() != std::string(kEasyUnlockFeatureName)) { + // Only process messages sent as part of EasyUnlock. + return; + } + std::string event_name = api::easy_unlock_private::OnSendCompleted::kEventName; events::HistogramValue histogram_value =
diff --git a/chrome/browser/metrics/perf/cpu_identity.cc b/chrome/browser/metrics/perf/cpu_identity.cc index 24330011..db0e1d2 100644 --- a/chrome/browser/metrics/perf/cpu_identity.cc +++ b/chrome/browser/metrics/perf/cpu_identity.cc
@@ -47,8 +47,10 @@ {"06_46", "Haswell"}, {"06_47", "Broadwell"}, // Broadwell-H {"06_4C", "Airmont"}, // Braswell + {"06_4D", "Silvermont"}, // Avoton/Rangely {"06_4E", "Skylake"}, {"06_56", "Broadwell"}, // Broadwell-DE + {"06_5E", "Skylake"}, {"0F_03", "Prescott"}, {"0F_04", "Prescott"}, {"0F_06", "Presler"},
diff --git a/chrome/browser/metrics/perf/perf_provider_chromeos.cc b/chrome/browser/metrics/perf/perf_provider_chromeos.cc index f7b32db..fa4e484 100644 --- a/chrome/browser/metrics/perf/perf_provider_chromeos.cc +++ b/chrome/browser/metrics/perf/perf_provider_chromeos.cc
@@ -121,6 +121,11 @@ const char kPerfRecordLBRCmd[] = "perf record -a -e r20c4 -b -c 200011"; +// Silvermont, Airmont, Goldmont don't have a branches taken event. Therefore, +// we sample on the branches retired event. +const char kPerfRecordLBRCmdAtom[] = + "perf record -a -e rc4 -b -c 300001"; + const char kPerfRecordInstructionTLBMissesCmd[] = "perf record -a -e iTLB-misses -c 2003"; @@ -142,18 +147,26 @@ if (intel_uarch == "IvyBridge" || intel_uarch == "Haswell" || intel_uarch == "Broadwell") { - cmds.push_back(WeightAndValue(60.0, kPerfRecordCyclesCmd)); + cmds.push_back(WeightAndValue(50.0, kPerfRecordCyclesCmd)); cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); - cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); + cmds.push_back(WeightAndValue(15.0, kPerfRecordLBRCmd)); cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); cmds.push_back(WeightAndValue(5.0, kPerfStatMemoryBandwidthCmd)); return cmds; } - if (intel_uarch == "SandyBridge") { - cmds.push_back(WeightAndValue(65.0, kPerfRecordCyclesCmd)); + if (intel_uarch == "SandyBridge" || intel_uarch == "Skylake") { + cmds.push_back(WeightAndValue(55.0, kPerfRecordCyclesCmd)); cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); - cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); + cmds.push_back(WeightAndValue(15.0, kPerfRecordLBRCmd)); + cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); + cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); + return cmds; + } + if (intel_uarch == "Silvermont" || intel_uarch == "Airmont") { + cmds.push_back(WeightAndValue(55.0, kPerfRecordCyclesCmd)); + cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); + cmds.push_back(WeightAndValue(15.0, kPerfRecordLBRCmdAtom)); cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); return cmds;
diff --git a/chrome/browser/payments/payment_request_web_contents_manager_browsertest.cc b/chrome/browser/payments/payment_request_web_contents_manager_browsertest.cc deleted file mode 100644 index ccf23dd..0000000 --- a/chrome/browser/payments/payment_request_web_contents_manager_browsertest.cc +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <vector> - -#include "base/command_line.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/payments/payment_request.h" -#include "components/payments/payment_request_web_contents_manager.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/content_switches.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "url/gurl.h" - -namespace payments { - -class PaymentRequestWebContentsManagerBrowserTest - : public InProcessBrowserTest { - public: - PaymentRequestWebContentsManagerBrowserTest() {} - ~PaymentRequestWebContentsManagerBrowserTest() override {} - - void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); - command_line->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - } - - void SetUpOnMainThread() override { - https_server_.reset( - new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)); - ASSERT_TRUE(https_server_->InitializeAndListen()); - https_server_->ServeFilesFromSourceDirectory("chrome/test/data/payments"); - https_server_->StartAcceptingConnections(); - } - - // Convenience method to get a list of PaymentRequest associated with - // |web_contents|. - const std::vector<PaymentRequest*> GetPaymentRequests( - content::WebContents* web_contents) { - PaymentRequestWebContentsManager* manager = - PaymentRequestWebContentsManager::GetOrCreateForWebContents( - web_contents); - if (!manager) - return std::vector<PaymentRequest*>(); - - std::vector<PaymentRequest*> payment_requests_ptrs; - for (const auto& p : manager->payment_requests_) { - payment_requests_ptrs.push_back(p.first); - } - return payment_requests_ptrs; - } - - std::unique_ptr<net::EmbeddedTestServer> https_server_; - - private: - DISALLOW_COPY_AND_ASSIGN(PaymentRequestWebContentsManagerBrowserTest); -}; - -IN_PROC_BROWSER_TEST_F(PaymentRequestWebContentsManagerBrowserTest, - MultiplePaymentRequests) { - GURL url = https_server_->GetURL("/payment_request_multiple_requests.html"); - ui_test_utils::NavigateToURL(browser(), url); - - const std::vector<PaymentRequest*> payment_requests = - GetPaymentRequests(browser()->tab_strip_model()->GetActiveWebContents()); - EXPECT_EQ(5U, payment_requests.size()); -} - -} // namespace payments
diff --git a/chrome/browser/prefs/preferences_connection_manager.cc b/chrome/browser/prefs/preferences_connection_manager.cc index 16627130..5eb57be 100644 --- a/chrome/browser/prefs/preferences_connection_manager.cc +++ b/chrome/browser/prefs/preferences_connection_manager.cc
@@ -47,16 +47,17 @@ mojo::StrongBindingPtr<prefs::mojom::PreferencesManager> binding) { if (!binding) return; - for (auto it = std::begin(bindings_); it != std::end(bindings_); ++it) { + for (auto it = manager_bindings_.begin(); it != manager_bindings_.end(); + ++it) { if (it->get() == binding.get()) { - bindings_.erase(it); + manager_bindings_.erase(it); return; } } } void PreferencesConnectionManager::OnProfileDestroyed() { - for (auto& it : bindings_) { + for (auto& it : manager_bindings_) { // Shutdown any PreferenceManager that is still alive. if (it) it->Close(); @@ -66,8 +67,8 @@ } void PreferencesConnectionManager::Create( - const service_manager::Identity& remote_identity, - prefs::mojom::PreferencesManagerRequest request) { + prefs::mojom::PreferencesObserverPtr observer, + prefs::mojom::PreferencesManagerRequest manager) { // Certain tests have no profiles to connect to, and static initializers // which block the creation of test profiles. if (!g_browser_process->profile_manager()->GetNumberOfProfiles()) @@ -75,13 +76,20 @@ Profile* profile = ProfileManager::GetActiveUserProfile(); mojo::StrongBindingPtr<prefs::mojom::PreferencesManager> binding = - mojo::MakeStrongBinding(base::MakeUnique<PreferencesManager>(profile), - std::move(request)); + mojo::MakeStrongBinding( + base::MakeUnique<PreferencesManager>(std::move(observer), profile), + std::move(manager)); // Copying the base::WeakPtr for future deletion. binding->set_connection_error_handler( base::Bind(&PreferencesConnectionManager::OnConnectionError, base::Unretained(this), binding)); - bindings_.push_back(std::move(binding)); + manager_bindings_.push_back(std::move(binding)); +} + +void PreferencesConnectionManager::Create( + const service_manager::Identity& remote_identity, + prefs::mojom::PreferencesFactoryRequest request) { + factory_bindings_.AddBinding(this, std::move(request)); } void PreferencesConnectionManager::OnStart() { @@ -101,6 +109,6 @@ bool PreferencesConnectionManager::OnConnect( const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) { - registry->AddInterface<prefs::mojom::PreferencesManager>(this); + registry->AddInterface<prefs::mojom::PreferencesFactory>(this); return true; }
diff --git a/chrome/browser/prefs/preferences_connection_manager.h b/chrome/browser/prefs/preferences_connection_manager.h index 0f9e8df..ebc85a27 100644 --- a/chrome/browser/prefs/preferences_connection_manager.h +++ b/chrome/browser/prefs/preferences_connection_manager.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "components/keyed_service/core/keyed_service_shutdown_notifier.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/preferences/public/interfaces/preferences.mojom.h" #include "services/service_manager/public/cpp/interface_factory.h" @@ -23,8 +24,9 @@ // TODO(jonross): Observe profile switching and update PreferenceManager // connections. class PreferencesConnectionManager - : public NON_EXPORTED_BASE( - service_manager::InterfaceFactory<prefs::mojom::PreferencesManager>), + : public NON_EXPORTED_BASE(prefs::mojom::PreferencesFactory), + public NON_EXPORTED_BASE( + service_manager::InterfaceFactory<prefs::mojom::PreferencesFactory>), public NON_EXPORTED_BASE(service_manager::Service) { public: PreferencesConnectionManager(); @@ -39,18 +41,24 @@ // the active PrefService is being destroyed. void OnProfileDestroyed(); - // service_manager::InterfaceFactory<PreferencesManager>: + // prefs::mojom::PreferencesFactory: + void Create(prefs::mojom::PreferencesObserverPtr observer, + prefs::mojom::PreferencesManagerRequest manager) override; + + // service_manager::InterfaceFactory<PreferencesFactory>: void Create(const service_manager::Identity& remote_identity, - prefs::mojom::PreferencesManagerRequest request) override; + prefs::mojom::PreferencesFactoryRequest request) override; // service_manager::Service: void OnStart() override; bool OnConnect(const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) override; + mojo::BindingSet<prefs::mojom::PreferencesFactory> factory_bindings_; + // Bindings that automatically cleanup during connection errors. std::vector<mojo::StrongBindingPtr<prefs::mojom::PreferencesManager>> - bindings_; + manager_bindings_; // Observes shutdown, when PrefService is being destroyed. std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
diff --git a/chrome/browser/prefs/preferences_manager.cc b/chrome/browser/prefs/preferences_manager.cc index 13eb402d..caf40d2 100644 --- a/chrome/browser/prefs/preferences_manager.cc +++ b/chrome/browser/prefs/preferences_manager.cc
@@ -12,10 +12,14 @@ #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" -PreferencesManager::PreferencesManager(Profile* profile) +PreferencesManager::PreferencesManager( + prefs::mojom::PreferencesObserverPtr client, + Profile* profile) : preferences_change_registrar_(new PrefChangeRegistrar), + client_(std::move(client)), setting_preferences_(false) { DCHECK(profile); + DCHECK(client_.is_bound()); service_ = profile->GetPrefs(); preferences_change_registrar_->Init(service_); } @@ -33,18 +37,8 @@ client_->OnPreferencesChanged(std::move(dictionary)); } -void PreferencesManager::AddObserver( - prefs::mojom::PreferencesObserverPtr client) { - // TODO(jonross): once service_manager::Connector supports enforcing two-way - // binding at connection time, update PreferencesManager to use that approach. - // After which enforcing bind checks will not be needed (crbug.com/674140) - client_ = std::move(client); -} - void PreferencesManager::SetPreferences( std::unique_ptr<base::DictionaryValue> preferences) { - if (!client_.is_bound()) - return; DCHECK(!setting_preferences_); // We ignore preference changes caused by us. base::AutoReset<bool> setting_preferences(&setting_preferences_, true); @@ -65,8 +59,6 @@ void PreferencesManager::Subscribe( const std::vector<std::string>& preferences) { - if (!client_.is_bound()) - return; std::unique_ptr<base::DictionaryValue> dictionary = base::MakeUnique<base::DictionaryValue>(); for (auto& it : preferences) {
diff --git a/chrome/browser/prefs/preferences_manager.h b/chrome/browser/prefs/preferences_manager.h index 9ffc67a..8f2272a 100644 --- a/chrome/browser/prefs/preferences_manager.h +++ b/chrome/browser/prefs/preferences_manager.h
@@ -25,7 +25,8 @@ // the requested preferences, notifying the client of all changes. class PreferencesManager : public prefs::mojom::PreferencesManager { public: - explicit PreferencesManager(Profile* profile); + PreferencesManager(prefs::mojom::PreferencesObserverPtr client, + Profile* profile); ~PreferencesManager() override; private: @@ -35,7 +36,6 @@ void PreferenceChanged(const std::string& preference_name); // mojom::PreferencesManager: - void AddObserver(prefs::mojom::PreferencesObserverPtr client) override; void SetPreferences( std::unique_ptr<base::DictionaryValue> preferences) override; void Subscribe(const std::vector<std::string>& preferences) override;
diff --git a/chrome/browser/prefs/preferences_manager_unittest.cc b/chrome/browser/prefs/preferences_manager_unittest.cc index f722949..73302cc 100644 --- a/chrome/browser/prefs/preferences_manager_unittest.cc +++ b/chrome/browser/prefs/preferences_manager_unittest.cc
@@ -162,9 +162,8 @@ ASSERT_NE(nullptr, profile_->GetPrefs()); observer_.reset(new TestPreferencesObserver(mojo::MakeRequest(&proxy_))); - manager_ = base::MakeUnique<PreferencesManager>(profile_); + manager_ = base::MakeUnique<PreferencesManager>(std::move(proxy_), profile_); ASSERT_TRUE(manager_->preferences_change_registrar_->IsEmpty()); - manager_->AddObserver(std::move(proxy_)); } void PreferencesManagerTest::TearDown() {
diff --git a/chrome/browser/prefs/preferences_manifest.json b/chrome/browser/prefs/preferences_manifest.json index 37b790ad..0ce32ca 100644 --- a/chrome/browser/prefs/preferences_manifest.json +++ b/chrome/browser/prefs/preferences_manifest.json
@@ -4,7 +4,7 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { - "preferences_manager": [ "prefs::mojom::PreferencesManager" ] + "preferences_manager": [ "prefs::mojom::PreferencesFactory" ] }, "requires": { }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js index acdf95a..ac9318b 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js
@@ -705,6 +705,11 @@ return; } + // Events don't propagate correctly because blur places focus on body. + if (Panel.mode_ == Panel.Mode.FULLSCREEN_TUTORIAL && + !Panel.tutorial_.onKeyDown(event)) + return; + if (!Panel.activeMenu_) return;
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/tutorial.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/tutorial.js index b72d3b2c..b829712 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/tutorial.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/tutorial.js
@@ -25,6 +25,7 @@ this.page = sessionStorage['tutorial_page_pos'] !== undefined ? sessionStorage['tutorial_page_pos'] : 0; }; + /** * @param {Node} container * @private @@ -117,6 +118,26 @@ ]; Tutorial.prototype = { + /** + * Handles key down events. + * @param {Event} evt + * @return {boolean} + */ + onKeyDown: function(evt) { + if (document.activeElement && + (document.activeElement.id == 'tutorial_previous' || + document.activeElement.id == 'tutorial_next')) + return true; + + if (evt.key == 'Enter') + this.nextPage(); + else if (evt.key == 'Backspace') + this.previousPage(); + else + return true; + return false; + }, + /** Open the last viewed page in the tutorial. */ lastViewedPage: function() { this.page = sessionStorage['tutorial_page_pos'] !== undefined ?
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd index 24b0a496..d306c82 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -2530,8 +2530,8 @@ <message desc="Introductory text for the 'ChromeVox Next' tutorial" name="IDS_CHROMEVOX_TUTORIAL_WELCOME_TEXT"> Are you using ChromeVox Next spoken feedback for the first time? This quick tutorial explains the essentials for getting started with ChromeVox Next. </message> - <message desc="Text that tells users to press the enter key to move to the next page in the tutorial" name="IDS_CHROMEVOX_TUTORIAL_ENTER_TO_ADVANCE"> - To advance, press Enter. + <message desc="Text that tells users to press the enter key to move to the next page or backspace to move to the previous page in the tutorial" name="IDS_CHROMEVOX_TUTORIAL_ENTER_TO_ADVANCE"> + To advance, press enter; to go back, press backspace. </message> <message desc="Heading that talks about turning ChromeVox on, off, and stopping it from speaking" name="IDS_CHROMEVOX_TUTORIAL_ON_OFF_HEADING"> On, Off, and Stop
diff --git a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html index 64f6453..4b7642e7 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html +++ b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html
@@ -32,6 +32,10 @@ <dom-module id="pin-keyboard"> <template> <style> + :host { + outline: none; + } + #root { direction: ltr; display: flex;
diff --git a/chrome/browser/task_manager/providers/browser_process_task.cc b/chrome/browser/task_manager/providers/browser_process_task.cc index cc6f606..d12a0e1 100644 --- a/chrome/browser/task_manager/providers/browser_process_task.cc +++ b/chrome/browser/task_manager/providers/browser_process_task.cc
@@ -4,13 +4,9 @@ #include "chrome/browser/task_manager/providers/browser_process_task.h" -#include "base/command_line.h" #include "chrome/browser/task_manager/task_manager_observer.h" -#include "chrome/common/chrome_switches.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" -#include "content/public/common/content_switches.h" -#include "net/proxy/proxy_resolver_v8.h" #include "third_party/sqlite/sqlite3.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -32,13 +28,6 @@ return g_default_icon; } -bool ReportsV8Stats() { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - return !command_line->HasSwitch(switches::kWinHttpProxyResolver) && - !command_line->HasSwitch(switches::kSingleProcess); -} - } // namespace BrowserProcessTask::BrowserProcessTask() @@ -46,10 +35,7 @@ "Browser Process", GetDefaultIcon(), base::GetCurrentProcessHandle()), - allocated_v8_memory_(-1), - used_v8_memory_(-1), - used_sqlite_memory_(-1), - reports_v8_stats_(ReportsV8Stats()) { + used_sqlite_memory_(-1) { } BrowserProcessTask::~BrowserProcessTask() { @@ -68,13 +54,6 @@ int64_t refresh_flags) { Task::Refresh(update_interval, refresh_flags); - if (reports_v8_stats_ && (refresh_flags & REFRESH_TYPE_V8_MEMORY) != 0) { - allocated_v8_memory_ = - static_cast<int64_t>(net::ProxyResolverV8::GetTotalHeapSize()); - used_v8_memory_ = - static_cast<int64_t>(net::ProxyResolverV8::GetUsedHeapSize()); - } - if ((refresh_flags & REFRESH_TYPE_SQLITE_MEMORY) != 0) used_sqlite_memory_ = static_cast<int64_t>(sqlite3_memory_used()); } @@ -91,12 +70,4 @@ return used_sqlite_memory_; } -int64_t BrowserProcessTask::GetV8MemoryAllocated() const { - return allocated_v8_memory_; -} - -int64_t BrowserProcessTask::GetV8MemoryUsed() const { - return used_v8_memory_; -} - } // namespace task_manager
diff --git a/chrome/browser/task_manager/providers/browser_process_task.h b/chrome/browser/task_manager/providers/browser_process_task.h index 0d0653f..53ef16c7 100644 --- a/chrome/browser/task_manager/providers/browser_process_task.h +++ b/chrome/browser/task_manager/providers/browser_process_task.h
@@ -26,14 +26,9 @@ Type GetType() const override; int GetChildProcessUniqueID() const override; int64_t GetSqliteMemoryUsed() const override; - int64_t GetV8MemoryAllocated() const override; - int64_t GetV8MemoryUsed() const override; private: - int64_t allocated_v8_memory_; - int64_t used_v8_memory_; int64_t used_sqlite_memory_; - bool reports_v8_stats_; DISALLOW_COPY_AND_ASSIGN(BrowserProcessTask); };
diff --git a/chrome/browser/task_manager/sampling/task_group.cc b/chrome/browser/task_manager/sampling/task_group.cc index a7a0d11..d7fab26 100644 --- a/chrome/browser/task_manager/sampling/task_group.cc +++ b/chrome/browser/task_manager/sampling/task_group.cc
@@ -26,11 +26,12 @@ const int kBackgroundRefreshTypesMask = REFRESH_TYPE_CPU | REFRESH_TYPE_MEMORY | REFRESH_TYPE_IDLE_WAKEUPS | #if defined(OS_WIN) - REFRESH_TYPE_START_TIME | REFRESH_TYPE_CPU_TIME | + REFRESH_TYPE_START_TIME | REFRESH_TYPE_CPU_TIME | #endif // defined(OS_WIN) #if defined(OS_LINUX) - REFRESH_TYPE_FD_COUNT | + REFRESH_TYPE_FD_COUNT | #endif // defined(OS_LINUX) + REFRESH_TYPE_NACL || REFRESH_TYPE_PRIORITY; #if defined(OS_WIN) @@ -176,7 +177,8 @@ } #endif // defined(OS_WIN) - // 4- Refresh the NACL debug stub port (if enabled). +// 4- Refresh the NACL debug stub port (if enabled). This calls out to +// NaClBrowser on the browser's IO thread, completing asynchronously. #if !defined(DISABLE_NACL) if (TaskManagerObserver::IsResourceRefreshEnabled(REFRESH_TYPE_NACL, refresh_flags) && @@ -255,14 +257,25 @@ #endif // defined(OS_WIN) } -void TaskGroup::RefreshNaClDebugStubPort(int child_process_unique_id) { #if !defined(DISABLE_NACL) +void TaskGroup::RefreshNaClDebugStubPort(int child_process_unique_id) { nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance(); - nacl_debug_stub_port_ = - nacl_browser->GetProcessGdbDebugStubPort(child_process_unique_id); -#endif // !defined(DISABLE_NACL) + content::BrowserThread::PostTaskAndReplyWithResult( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&nacl::NaClBrowser::GetProcessGdbDebugStubPort, + base::Unretained(nacl_browser), child_process_unique_id), + base::Bind(&TaskGroup::OnRefreshNaClDebugStubPortDone, + weak_ptr_factory_.GetWeakPtr())); } +void TaskGroup::OnRefreshNaClDebugStubPortDone(int nacl_debug_stub_port) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + nacl_debug_stub_port_ = nacl_debug_stub_port; + OnBackgroundRefreshTypeFinished(REFRESH_TYPE_NACL); +} +#endif // !defined(DISABLE_NACL) + void TaskGroup::OnCpuRefreshDone(double cpu_usage) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/task_manager/sampling/task_group.h b/chrome/browser/task_manager/sampling/task_group.h index 288c54f..7768367 100644 --- a/chrome/browser/task_manager/sampling/task_group.h +++ b/chrome/browser/task_manager/sampling/task_group.h
@@ -107,8 +107,11 @@ void RefreshWindowsHandles(); +#if !defined(DISABLE_NACL) // |child_process_unique_id| see Task::GetChildProcessUniqueID(). void RefreshNaClDebugStubPort(int child_process_unique_id); + void OnRefreshNaClDebugStubPortDone(int port); +#endif void OnCpuRefreshDone(double cpu_usage);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 154b5cff..d535c11 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3467,6 +3467,8 @@ if (toolkit_views && (!is_mac || mac_views_browser)) { sources += [ "views/find_bar_host_unittest_util_views.cc", + "views/payments/test_chrome_payment_request_delegate.cc", + "views/payments/test_chrome_payment_request_delegate.h", "views/toolbar/browser_action_test_util_views.cc", ] if (!is_mac) {
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h index b26cfb3..2890c9a 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h
@@ -49,12 +49,6 @@ BROWSER_ACTIONS_INVALID_KEY_ACTION = 3, }; -class BrowserActionsContainerViewSizeDelegate { - public: - virtual CGFloat GetMaxAllowedWidth() = 0; - virtual ~BrowserActionsContainerViewSizeDelegate() {} -}; - // The view that encompasses the Browser Action buttons in the toolbar and // provides mechanisms for resizing. @interface BrowserActionsContainerView : NSView<NSAnimationDelegate> { @@ -62,13 +56,8 @@ // The frame encompasing the grippy used for resizing the container. NSRect grippyRect_; - // Used to cache the original position within the container that initiated the - // drag. - NSPoint initialDragPoint_; - - // The maximum width the container could want; i.e., the width required to - // display all the icons. - CGFloat maxDesiredWidth_; + // Remember where in the grippy the drag began. + CGFloat dragOffset_; // Whether the container is currently being resized by the user. BOOL userIsResizing_; @@ -83,15 +72,6 @@ // app menu. BOOL isOverflow_; - // Whether the user is allowed to drag the grippy to the left. NO if all - // extensions are shown or the location bar has hit its minimum width (handled - // within toolbar_controller.mm). - BOOL canDragLeft_; - - // Whether the user is allowed to drag the grippy to the right. NO if all - // extensions are hidden. - BOOL canDragRight_; - // When the left grippy is pinned, resizing the window has no effect on its // position. This prevents it from overlapping with other elements as well // as letting the container expand when the window is going from super small @@ -101,10 +81,6 @@ // The nine-grid of the highlight to paint, if any. std::unique_ptr<ui::NinePartImageIds> highlight_; - // The size delegate, if any. - // Weak; delegate is responsible for adding/removing itself. - BrowserActionsContainerViewSizeDelegate* sizeDelegate_; - base::scoped_nsobject<NSViewAnimation> resizeAnimation_; } @@ -130,12 +106,10 @@ // Stops any animation in progress. - (void)stopAnimation; -@property(nonatomic) BOOL canDragLeft; -@property(nonatomic) BOOL canDragRight; +@property(nonatomic) CGFloat minWidth; +@property(nonatomic) CGFloat maxWidth; @property(nonatomic) BOOL grippyPinned; -@property(nonatomic) CGFloat maxDesiredWidth; @property(readonly, nonatomic) BOOL userIsResizing; -@property(nonatomic) BrowserActionsContainerViewSizeDelegate* delegate; @end
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm index 3bf1e04..251d337 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
@@ -32,26 +32,20 @@ namespace { const CGFloat kAnimationDuration = 0.2; const CGFloat kGrippyWidth = 3.0; -const CGFloat kMinimumContainerWidth = 3.0; } // namespace @interface BrowserActionsContainerView(Private) // Returns the cursor that should be shown when hovering over the grippy based // on |canDragLeft_| and |canDragRight_|. - (NSCursor*)appropriateCursorForGrippy; - -// Returns the maximum allowed size for the container. -- (CGFloat)maxAllowedWidth; @end @implementation BrowserActionsContainerView -@synthesize canDragLeft = canDragLeft_; -@synthesize canDragRight = canDragRight_; +@synthesize minWidth = minWidth_; +@synthesize maxWidth = maxWidth_; @synthesize grippyPinned = grippyPinned_; -@synthesize maxDesiredWidth = maxDesiredWidth_; @synthesize userIsResizing = userIsResizing_; -@synthesize delegate = delegate_; #pragma mark - #pragma mark Overridden Class Functions @@ -62,8 +56,6 @@ if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) grippyRect_.origin.x = NSWidth(frameRect) - NSWidth(grippyRect_); - canDragLeft_ = YES; - canDragRight_ = YES; resizable_ = YES; resizeAnimation_.reset([[NSViewAnimation alloc] init]); @@ -179,12 +171,15 @@ } - (void)mouseDown:(NSEvent*)theEvent { - initialDragPoint_ = [self convertPoint:[theEvent locationInWindow] - fromView:nil]; - if (!resizable_ || - !NSMouseInRect(initialDragPoint_, grippyRect_, [self isFlipped])) + NSPoint location = + [self convertPoint:[theEvent locationInWindow] fromView:nil]; + if (!resizable_ || !NSMouseInRect(location, grippyRect_, [self isFlipped])) return; + dragOffset_ = location.x - (cocoa_l10n_util::ShouldDoExperimentalRTLLayout() + ? NSWidth(self.frame) + : 0); + userIsResizing_ = YES; [[self appropriateCursorForGrippy] push]; @@ -215,37 +210,14 @@ if (!userIsResizing_) return; - NSPoint location = [self convertPoint:[theEvent locationInWindow] - fromView:nil]; - NSRect containerFrame = [self frame]; - CGFloat dX = [theEvent deltaX]; - CGFloat withDelta = location.x - dX; - BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout(); + const CGFloat translation = + [self convertPoint:[theEvent locationInWindow] fromView:nil].x - + dragOffset_; + const CGFloat targetWidth = (cocoa_l10n_util::ShouldDoExperimentalRTLLayout() + ? translation + : NSWidth(self.frame) - translation); - CGFloat maxAllowedWidth = [self maxAllowedWidth]; - - const CGFloat maxWidth = std::min(maxAllowedWidth, maxDesiredWidth_); - CGFloat newWidth = NSWidth(containerFrame) + (isRTL ? dX : -dX); - newWidth = std::min(std::max(newWidth, kMinimumContainerWidth), maxWidth); - - BOOL canGrow = NSWidth(containerFrame) < maxWidth; - BOOL canShrink = NSWidth(containerFrame) > kMinimumContainerWidth; - - canDragLeft_ = - withDelta <= initialDragPoint_.x && (isRTL ? canShrink : canGrow); - canDragRight_ = - (withDelta >= initialDragPoint_.x) && (isRTL ? canGrow : canShrink); - if ((dX < 0.0 && !canDragLeft_) || (dX > 0.0 && !canDragRight_) || - fabs(dX) < FLT_EPSILON) - return; - - grippyPinned_ = newWidth >= maxAllowedWidth; - if (!isRTL) - containerFrame.origin.x += dX; - containerFrame.size.width = newWidth; - - [self setFrame:containerFrame]; - [self setNeedsDisplay:YES]; + [self resizeToWidth:targetWidth animate:NO]; [[NSNotificationCenter defaultCenter] postNotificationName:kBrowserActionGrippyDraggingNotification @@ -282,21 +254,14 @@ #pragma mark Public Methods - (void)resizeToWidth:(CGFloat)width animate:(BOOL)animate { - width = std::max(width, kMinimumContainerWidth); + width = std::min(std::max(width, minWidth_), maxWidth_); + NSRect newFrame = [self frame]; + if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) + newFrame.origin.x += NSWidth(newFrame) - width; + newFrame.size.width = width; - CGFloat maxAllowedWidth = [self maxAllowedWidth]; - width = std::min(maxAllowedWidth, width); - - if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) { - newFrame.size.width = width; - } else { - CGFloat dX = NSWidth(newFrame) - width; - newFrame.size.width = width; - newFrame.origin.x += dX; - } - - grippyPinned_ = width == maxAllowedWidth; + grippyPinned_ = width == maxWidth_; [self stopAnimation]; @@ -343,21 +308,20 @@ // Returns the cursor to display over the grippy hover region depending on the // current drag state. - (NSCursor*)appropriateCursorForGrippy { - NSCursor* retVal; - if (!resizable_ || (!canDragLeft_ && !canDragRight_)) { - retVal = [NSCursor arrowCursor]; - } else if (!canDragLeft_) { - retVal = [NSCursor resizeRightCursor]; - } else if (!canDragRight_) { - retVal = [NSCursor resizeLeftCursor]; - } else { - retVal = [NSCursor resizeLeftRightCursor]; - } - return retVal; -} + if (resizable_) { + const CGFloat width = NSWidth(self.frame); + const BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout(); + const BOOL canDragLeft = width != (isRTL ? minWidth_ : maxWidth_); + const BOOL canDragRight = width != (isRTL ? maxWidth_ : minWidth_); -- (CGFloat)maxAllowedWidth { - return delegate_ ? delegate_->GetMaxAllowedWidth() : CGFLOAT_MAX; + if (canDragLeft && canDragRight) + return [NSCursor resizeLeftRightCursor]; + if (canDragLeft) + return [NSCursor resizeLeftCursor]; + if (canDragRight) + return [NSCursor resizeRightCursor]; + } + return [NSCursor arrowCursor]; } @end
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm index dca3226..7f26cab 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm
@@ -15,18 +15,6 @@ const CGFloat kMinimumContainerWidth = 3.0; const CGFloat kMaxAllowedWidthForTest = 50.0; -class BrowserActionsContainerTestDelegate - : public BrowserActionsContainerViewSizeDelegate { - public: - BrowserActionsContainerTestDelegate() {} - ~BrowserActionsContainerTestDelegate() override {} - - CGFloat GetMaxAllowedWidth() override { return kMaxAllowedWidthForTest; } - - private: - DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainerTestDelegate); -}; - class BrowserActionsContainerViewTest : public CocoaTest { public: void SetUp() override { @@ -39,13 +27,14 @@ }; TEST_F(BrowserActionsContainerViewTest, BasicTests) { - EXPECT_TRUE([view_ canDragLeft]); - EXPECT_TRUE([view_ canDragRight]); EXPECT_TRUE([view_ isHidden]); } TEST_F(BrowserActionsContainerViewTest, SetWidthTests) { - // Try setting below the minimum width (10 pixels). + [view_ setMinWidth:kMinimumContainerWidth]; + [view_ setMaxWidth:kMaxAllowedWidthForTest]; + + // Try setting below the minimum width. [view_ resizeToWidth:kMinimumContainerWidth - 1 animate:NO]; EXPECT_EQ(kMinimumContainerWidth, NSWidth([view_ frame])) << "Frame width is " << "less than the minimum allowed."; @@ -73,11 +62,8 @@ EXPECT_EQ(35.0, NSWidth([view_ frame])); EXPECT_EQ(35.0, NSWidth([view_ animationEndFrame])); - BrowserActionsContainerTestDelegate delegate; - [view_ setDelegate:&delegate]; [view_ resizeToWidth:kMaxAllowedWidthForTest + 10.0 animate:NO]; EXPECT_EQ(kMaxAllowedWidthForTest, NSWidth([view_ frame])); - [view_ setDelegate:nil]; } } // namespace
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h index 26802e1b..1c8ebe7 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
@@ -60,6 +60,7 @@ NSInteger focusedViewIndex_; } +@property(nonatomic) CGFloat maxWidth; @property(readonly, nonatomic) BrowserActionsContainerView* containerView; @property(readonly, nonatomic) Browser* browser; @property(readonly, nonatomic) BOOL isOverflow;
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm index 60d3c42..17cadc0 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -135,9 +135,6 @@ // Handles clicks for BrowserActionButtons. - (BOOL)browserActionClicked:(BrowserActionButton*)button; -// Updates the container's grippy cursor based on the number of hidden buttons. -- (void)updateGrippyCursors; - // Returns the associated ToolbarController. - (ToolbarController*)toolbarController; @@ -249,6 +246,7 @@ @implementation BrowserActionsController +@synthesize maxWidth = maxWidth_; @synthesize containerView = containerView_; @synthesize browser = browser_; @synthesize isOverflow = isOverflow_; @@ -275,6 +273,7 @@ mainBar)); containerView_ = container; + [containerView_ setMinWidth:toolbarActionsBar_->GetMinimumWidth()]; [containerView_ setPostsFrameChangedNotifications:YES]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -314,7 +313,6 @@ buttons_.reset([[NSMutableArray alloc] init]); toolbarActionsBar_->CreateActions(); - [self updateGrippyCursors]; [container setIsOverflow:isOverflow_]; focusedViewIndex_ = -1; @@ -405,6 +403,17 @@ return [self preferredSize]; } +- (void)updateMaxWidth { + const CGFloat ownMaxWidth = toolbarActionsBar_->GetMaximumWidth(); + containerView_.maxWidth = + (maxWidth_ ? std::min(maxWidth_, ownMaxWidth) : ownMaxWidth); +} + +- (void)setMaxWidth:(CGFloat)maxWidth { + maxWidth_ = maxWidth; + [self updateMaxWidth]; +} + - (void)addViewForAction:(ToolbarActionViewController*)action withIndex:(NSUInteger)index { NSRect buttonFrame = NSMakeRect(NSMaxX([containerView_ bounds]), @@ -420,13 +429,12 @@ [newButton setAction:@selector(browserActionClicked:)]; [buttons_ insertObject:newButton atIndex:index]; + [self updateMaxWidth]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(actionButtonDragging:) name:kBrowserActionButtonDraggingNotification object:newButton]; - - [containerView_ setMaxDesiredWidth:toolbarActionsBar_->GetMaximumWidth()]; } - (void)redraw { @@ -505,9 +513,8 @@ [button removeFromSuperview]; [buttons_ removeObject:button]; + [self updateMaxWidth]; [button onRemoved]; - - [containerView_ setMaxDesiredWidth:toolbarActionsBar_->GetMaximumWidth()]; } - (void)removeAllViews { @@ -537,7 +544,7 @@ object:self]; } [self redraw]; - [self updateGrippyCursors]; + [[containerView_ window] invalidateCursorRectsForView:containerView_]; } - (BOOL)updateContainerVisibility { @@ -622,27 +629,8 @@ } - (void)containerDragFinished:(NSNotification*)notification { - for (BrowserActionButton* button in buttons_.get()) { - NSRect buttonFrame = [button frame]; - if (NSContainsRect([containerView_ bounds], buttonFrame)) - continue; - - CGFloat intersectionWidth = - NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); - // Hide the button if it's not "mostly" visible. "Mostly" here equates to - // having three or fewer pixels hidden. - if (([containerView_ grippyPinned] && intersectionWidth > 0) || - (intersectionWidth <= NSWidth(buttonFrame) - 3.0)) { - [button setAlphaValue:0.0]; - [button removeFromSuperview]; - } - } - - toolbarActionsBar_->OnResizeComplete( - toolbarActionsBar_->IconCountToWidth([self visibleButtonCount])); - - [self updateGrippyCursors]; - [self resizeContainerToWidth:toolbarActionsBar_->GetPreferredSize().width()]; + toolbarActionsBar_->OnResizeComplete(NSWidth(containerView_.bounds)); + [[containerView_ window] invalidateCursorRectsForView:containerView_]; } - (void)containerAnimationEnded:(NSNotification*)notification { @@ -786,20 +774,6 @@ return [button viewController]->ExecuteAction(true); } -- (void)updateGrippyCursors { - BOOL canClose = [self visibleButtonCount] > 0; - BOOL canOpen = toolbarActionsBar_->GetIconCount() != [buttons_ count]; - [containerView_ - setCanDragLeft:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() - ? canClose - : canOpen]; - [containerView_ - setCanDragRight:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() - ? canOpen - : canClose]; - [[containerView_ window] invalidateCursorRectsForView:containerView_]; -} - - (ToolbarController*)toolbarController { return [[BrowserWindowController browserWindowControllerForWindow: browser_->window()->GetNativeWindow()] toolbarController];
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h index cf0c6a0..62b049a 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
@@ -21,7 +21,6 @@ @class BackForwardMenuController; class Browser; @class BrowserActionsContainerView; -class BrowserActionsContainerViewSizeDelegate; @class BrowserActionsController; class CommandUpdater; class LocationBarViewMac; @@ -71,8 +70,6 @@ base::scoped_nsobject<BackForwardMenuController> backMenuController_; base::scoped_nsobject<BackForwardMenuController> forwardMenuController_; base::scoped_nsobject<BrowserActionsController> browserActionsController_; - std::unique_ptr<BrowserActionsContainerViewSizeDelegate> - browserActionsContainerDelegate_; // Lazily-instantiated menu controller. base::scoped_nsobject<AppMenuController> appMenuController_;
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm index 9206e9e..4b3458fa 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
@@ -103,42 +103,6 @@ // The minimum width of the location bar in pixels. const CGFloat kMinimumLocationBarWidth = 100.0; -class BrowserActionsContainerDelegate : - public BrowserActionsContainerViewSizeDelegate { - public: - BrowserActionsContainerDelegate( - AutocompleteTextField* location_bar, - BrowserActionsContainerView* browser_actions_container_view); - ~BrowserActionsContainerDelegate() override; - - private: - // BrowserActionsContainerSizeDelegate: - CGFloat GetMaxAllowedWidth() override; - - AutocompleteTextField* location_bar_; - BrowserActionsContainerView* browser_actions_container_; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainerDelegate); -}; - -BrowserActionsContainerDelegate::BrowserActionsContainerDelegate( - AutocompleteTextField* location_bar, - BrowserActionsContainerView* browser_actions_container_view) - : location_bar_(location_bar), - browser_actions_container_(browser_actions_container_view) { - [browser_actions_container_ setDelegate:this]; -} - -BrowserActionsContainerDelegate::~BrowserActionsContainerDelegate() { - [browser_actions_container_ setDelegate:nil]; -} - -CGFloat BrowserActionsContainerDelegate::GetMaxAllowedWidth() { - CGFloat location_bar_flex = - NSWidth([location_bar_ frame]) - kMinimumLocationBarWidth; - return NSWidth([browser_actions_container_ frame]) + location_bar_flex; -} - } // namespace @interface ToolbarController() @@ -528,7 +492,6 @@ // Destroy owned objects that hold a weak Browser*. locationBarView_.reset(); - browserActionsContainerDelegate_.reset(); browser_ = nullptr; } @@ -786,9 +749,6 @@ - (void)createBrowserActionButtons { if (!browserActionsController_.get()) { - browserActionsContainerDelegate_.reset( - new BrowserActionsContainerDelegate(locationBar_, - browserActionsContainerView_)); browserActionsController_.reset([[BrowserActionsController alloc] initWithBrowser:browser_ containerView:browserActionsContainerView_ @@ -814,8 +774,7 @@ name:NSWindowDidBecomeKeyNotification object:[[self view] window]]; } - if (![browserActionsContainerView_ isHidden]) - [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO]; + [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO]; } - (void)updateVisibility:(BOOL)visible withAnimation:(BOOL)animate { @@ -875,10 +834,7 @@ } } - if (delta != 0.0) - [self adjustLocationSizeBy:delta animate:animate]; - else - [locationBar_ stopAnimation]; + [self adjustLocationSizeBy:delta animate:animate]; } - (void)maintainMinimumLocationBarWidth { @@ -979,13 +935,23 @@ } - (void)adjustLocationSizeBy:(CGFloat)dX animate:(BOOL)animate { - // Ensure that the location bar is in its proper place. NSRect locationFrame = [locationBar_ frame]; + + CGFloat location_bar_flex = NSWidth(locationFrame) - kMinimumLocationBarWidth; + [browserActionsController_ + setMaxWidth:NSWidth(browserActionsContainerView_.frame) + + location_bar_flex]; + + [locationBar_ stopAnimation]; + + if (dX == 0) + return; + + // Ensure that the location bar is in its proper place. locationFrame.size.width += dX; if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) locationFrame.origin.x -= dX; - [locationBar_ stopAnimation]; if (animate) [locationBar_ animateToFrame:locationFrame]; else
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog.cc b/chrome/browser/ui/views/payments/payment_request_dialog.cc index 58af72fb..99a2871 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog.cc +++ b/chrome/browser/ui/views/payments/payment_request_dialog.cc
@@ -21,8 +21,9 @@ namespace chrome { void ShowPaymentRequestDialog(payments::PaymentRequest* request) { - constrained_window::ShowWebModalDialogViews( - new payments::PaymentRequestDialog(request), request->web_contents()); + payments::PaymentRequestDialog::ShowWebModalPaymentDialog( + new payments::PaymentRequestDialog(request, /* no observer */ nullptr), + request); } } // namespace chrome @@ -48,8 +49,10 @@ } // namespace -PaymentRequestDialog::PaymentRequestDialog(PaymentRequest* request) - : request_(request) { +PaymentRequestDialog::PaymentRequestDialog( + PaymentRequest* request, + PaymentRequestDialog::ObserverForTest* observer) + : request_(request), observer_(observer) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); SetLayoutManager(new views::FillLayout()); @@ -109,10 +112,19 @@ GetWidget()->Close(); } +// static +void PaymentRequestDialog::ShowWebModalPaymentDialog( + PaymentRequestDialog* dialog, + PaymentRequest* request) { + constrained_window::ShowWebModalDialogViews(dialog, request->web_contents()); +} + void PaymentRequestDialog::ShowInitialPaymentSheet() { view_stack_.Push(CreateViewAndInstallController<PaymentSheetViewController>( &controller_map_, request_, this), false); + if (observer_) + observer_->OnDialogOpened(); } gfx::Size PaymentRequestDialog::GetPreferredSize() const {
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog.h b/chrome/browser/ui/views/payments/payment_request_dialog.h index d11f41312..e4f2ed16 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog.h +++ b/chrome/browser/ui/views/payments/payment_request_dialog.h
@@ -28,7 +28,16 @@ // the WebPayments flow and managing the transition between those states. class PaymentRequestDialog : public views::DialogDelegateView { public: - explicit PaymentRequestDialog(PaymentRequest* request); + class ObserverForTest { + public: + virtual void OnDialogOpened() = 0; + }; + + // Build a Dialog around the PaymentRequest object. |observer| is used to + // be notified of dialog events as they happen (but may be NULL) and should + // outlive this object. + PaymentRequestDialog(PaymentRequest* request, + PaymentRequestDialog::ObserverForTest* observer); ~PaymentRequestDialog() override; // views::WidgetDelegate @@ -44,6 +53,9 @@ void ShowPaymentMethodSheet(); void CloseDialog(); + static void ShowWebModalPaymentDialog(PaymentRequestDialog* dialog, + PaymentRequest* request); + private: void ShowInitialPaymentSheet(); @@ -57,6 +69,8 @@ // always be valid even though there is no direct ownership relationship // between the two. PaymentRequest* request_; + // May be null. + ObserverForTest* observer_; ControllerMap controller_map_; ViewStack view_stack_;
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc new file mode 100644 index 0000000..f4838628 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h" +#include "components/payments/payment_request.h" +#include "components/payments/payment_request_web_contents_manager.h" + +namespace payments { + +class PaymentRequestWebContentsManagerTest + : public PaymentRequestInteractiveTestBase { + protected: + PaymentRequestWebContentsManagerTest() + : PaymentRequestInteractiveTestBase( + "/payment_request_multiple_requests.html") {} +}; + +// If the page creates multiple PaymentRequest objects, it should not crash. +IN_PROC_BROWSER_TEST_F(PaymentRequestWebContentsManagerTest, MultipleRequests) { + const std::vector<PaymentRequest*> payment_requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(5U, payment_requests.size()); +} + +class PaymentRequestNoShippingTest : public PaymentRequestInteractiveTestBase { + protected: + PaymentRequestNoShippingTest() + : PaymentRequestInteractiveTestBase( + "/payment_request_no_shipping_test.html") {} +}; + +IN_PROC_BROWSER_TEST_F(PaymentRequestNoShippingTest, OpenPaymentRequestSheet) { + InvokePaymentRequestUI(); +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc new file mode 100644 index 0000000..b1e7f27 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc
@@ -0,0 +1,133 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h" + +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/payments/payment_request.h" +#include "components/payments/payment_request_web_contents_manager.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test_utils.h" +#include "services/service_manager/public/cpp/interface_registry.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace payments { + +PaymentRequestInteractiveTestBase::PaymentRequestInteractiveTestBase( + const std::string& test_file_path) + : test_file_path_(test_file_path) {} +PaymentRequestInteractiveTestBase::~PaymentRequestInteractiveTestBase() {} + +void PaymentRequestInteractiveTestBase::SetUpCommandLine( + base::CommandLine* command_line) { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures); +} + +void PaymentRequestInteractiveTestBase::SetUpOnMainThread() { + https_server_ = base::MakeUnique<net::EmbeddedTestServer>( + net::EmbeddedTestServer::TYPE_HTTPS); + ASSERT_TRUE(https_server_->InitializeAndListen()); + https_server_->ServeFilesFromSourceDirectory("chrome/test/data/payments"); + https_server_->StartAcceptingConnections(); + + GURL url = https_server()->GetURL(test_file_path_); + ui_test_utils::NavigateToURL(browser(), url); + + // Starting now, PaymentRequest Mojo messages sent by the renderer will + // create PaymentRequest objects via this test's CreatePaymentRequestForTest, + // allowing the test to inject itself as a dialog observer. + content::WebContents* web_contents = GetActiveWebContents(); + service_manager::InterfaceRegistry* registry = + web_contents->GetMainFrame()->GetInterfaceRegistry(); + registry->RemoveInterface(payments::mojom::PaymentRequest::Name_); + registry->AddInterface(base::Bind( + &PaymentRequestInteractiveTestBase::CreatePaymentRequestForTest, + base::Unretained(this), web_contents)); +} + +void PaymentRequestInteractiveTestBase::OnDialogOpened() { + if (event_observer_) + event_observer_->Observe(DialogEvent::DIALOG_OPENED); +} + +void PaymentRequestInteractiveTestBase::InvokePaymentRequestUI() { + event_observer_.reset(new DialogEventObserver(DialogEvent::DIALOG_OPENED)); + + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_buy_button_js = + "(function() { document.getElementById('buy').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_buy_button_js)); + + event_observer_->Wait(); + + // The web-modal dialog should be open. + web_modal::WebContentsModalDialogManager* web_contents_modal_dialog_manager = + web_modal::WebContentsModalDialogManager::FromWebContents(web_contents); + EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive()); +} + +content::WebContents* +PaymentRequestInteractiveTestBase::GetActiveWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); +} + +const std::vector<PaymentRequest*> +PaymentRequestInteractiveTestBase::GetPaymentRequests( + content::WebContents* web_contents) { + PaymentRequestWebContentsManager* manager = + PaymentRequestWebContentsManager::GetOrCreateForWebContents(web_contents); + if (!manager) + return std::vector<PaymentRequest*>(); + + std::vector<PaymentRequest*> payment_requests_ptrs; + for (const auto& p : manager->payment_requests_) + payment_requests_ptrs.push_back(p.first); + return payment_requests_ptrs; +} + +void PaymentRequestInteractiveTestBase::CreatePaymentRequestForTest( + content::WebContents* web_contents, + mojo::InterfaceRequest<payments::mojom::PaymentRequest> request) { + DCHECK(web_contents); + PaymentRequestWebContentsManager::GetOrCreateForWebContents(web_contents) + ->CreatePaymentRequest(web_contents, + base::MakeUnique<TestChromePaymentRequestDelegate>( + web_contents, this /* observer */), + std::move(request)); +} + +PaymentRequestInteractiveTestBase::DialogEventObserver::DialogEventObserver( + PaymentRequestInteractiveTestBase::DialogEvent event) + : event_(event), seen_(false) {} +PaymentRequestInteractiveTestBase::DialogEventObserver::~DialogEventObserver() { +} + +void PaymentRequestInteractiveTestBase::DialogEventObserver::Wait() { + if (seen_) + return; + + DCHECK(!run_loop_.running()); + run_loop_.Run(); +} + +void PaymentRequestInteractiveTestBase::DialogEventObserver::Observe( + PaymentRequestInteractiveTestBase::DialogEvent event) { + seen_ = true; + if (event == event_ && run_loop_.running()) + run_loop_.Quit(); +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h new file mode 100644 index 0000000..0e2fe7bf --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h
@@ -0,0 +1,106 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_ +#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_ + +#include <vector> + +#include "base/command_line.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "chrome/browser/ui/views/payments/payment_request_dialog.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/payments/payment_request.mojom.h" +#include "net/test/embedded_test_server/embedded_test_server.h" + +namespace content { +class WebContents; +} // namespace content + +namespace payments { + +class PaymentRequest; + +// Base class for any interactive PaymentRequest test that will need to open +// the UI and interact with it. +class PaymentRequestInteractiveTestBase + : public InProcessBrowserTest, + public PaymentRequestDialog::ObserverForTest { + protected: + // Test will open a browser window to |test_file_path| (relative to + // chrome/test/data/payments). + explicit PaymentRequestInteractiveTestBase(const std::string& test_file_path); + ~PaymentRequestInteractiveTestBase() override; + + void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUpOnMainThread() override; + + // PaymentRequestDialog::ObserverForTest + void OnDialogOpened() override; + + // Will call JavaScript to invoke the PaymentRequest dialog and verify that + // it's open. + void InvokePaymentRequestUI(); + + // Convenience method to get a list of PaymentRequest associated with + // |web_contents|. + const std::vector<PaymentRequest*> GetPaymentRequests( + content::WebContents* web_contents); + + content::WebContents* GetActiveWebContents(); + + void CreatePaymentRequestForTest( + content::WebContents* web_contents, + mojo::InterfaceRequest<payments::mojom::PaymentRequest> request); + + net::EmbeddedTestServer* https_server() { return https_server_.get(); } + + private: + // Various events that can be waited on by the DialogEventObserver. + enum DialogEvent { + DIALOG_OPENED, + }; + + // DialogEventObserver is used to wait on specific events that may have + // occured before the call to Wait(), or after, in which case a RunLoop is + // used. + // + // Usage: + // observer_.reset(new DialogEventObserver([DialogEvent])); + // + // Do stuff, which (a)synchronously calls observer_->Observe([DialogEvent]). + // + // observer_->Wait(); <- Will either return right away if event was observed, + // <- or use a RunLoop's Run/Quit to wait for the event. + class DialogEventObserver { + public: + explicit DialogEventObserver(DialogEvent event); + ~DialogEventObserver(); + + // Either returns right away if the event was observed between this object's + // construction and this call to Wait(), or use a RunLoop to wait for it. + void Wait(); + + // Observes the event (quits the RunLoop if it was running). + void Observe(DialogEvent event); + + private: + DialogEvent event_; + bool seen_; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(DialogEventObserver); + }; + + const std::string test_file_path_; + std::unique_ptr<net::EmbeddedTestServer> https_server_; + std::unique_ptr<DialogEventObserver> event_observer_; + + DISALLOW_COPY_AND_ASSIGN(PaymentRequestInteractiveTestBase); +}; + +} // namespace payments + +#endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_
diff --git a/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.cc b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.cc new file mode 100644 index 0000000..09c6877 --- /dev/null +++ b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.cc
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h" + +#include "content/public/browser/web_contents.h" + +namespace payments { + +TestChromePaymentRequestDelegate::TestChromePaymentRequestDelegate( + content::WebContents* web_contents, + PaymentRequestDialog::ObserverForTest* observer) + : ChromePaymentRequestDelegate(web_contents), observer_(observer) {} + +void TestChromePaymentRequestDelegate::ShowPaymentRequestDialog( + PaymentRequest* request) { + PaymentRequestDialog::ShowWebModalPaymentDialog( + new PaymentRequestDialog(request, observer_), request); +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h new file mode 100644 index 0000000..adccc37 --- /dev/null +++ b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_TEST_CHROME_PAYMENT_REQUEST_DELEGATE_H_ +#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_TEST_CHROME_PAYMENT_REQUEST_DELEGATE_H_ + +#include "base/macros.h" +#include "chrome/browser/payments/chrome_payment_request_delegate.h" +#include "chrome/browser/ui/views/payments/payment_request_dialog.h" + +namespace content { +class WebContents; +} + +namespace payments { + +class PaymentRequest; + +// Implementation of the Payment Request delegate used in tests. +class TestChromePaymentRequestDelegate : public ChromePaymentRequestDelegate { + public: + TestChromePaymentRequestDelegate( + content::WebContents* web_contents, + PaymentRequestDialog::ObserverForTest* observer); + + void ShowPaymentRequestDialog(PaymentRequest* request) override; + + private: + PaymentRequestDialog::ObserverForTest* observer_; + + DISALLOW_COPY_AND_ASSIGN(TestChromePaymentRequestDelegate); +}; + +} // namespace payments + +#endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_TEST_CHROME_PAYMENT_REQUEST_DELEGATE_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index fb2ed5a2..6f5f7d2 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -480,7 +480,7 @@ } void CoreOobeHandler::UpdateClientAreaSize() { - const gfx::Size& size = + const gfx::Size size = display::Screen::GetScreen()->GetPrimaryDisplay().size(); SetClientAreaSize(size.width(), size.height()); }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index bd701a7..897e3c38 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -568,6 +568,15 @@ "base/interactive_test_utils_views.cc", ] } + if (is_win || is_linux) { + # TODO(crbug.com/679127): Enable these tests on "mac_views_browser" once + # it is supported. + sources += [ + "../browser/ui/views/payments/payment_request_interactive_uitest.cc", + "../browser/ui/views/payments/payment_request_interactive_uitest_base.cc", + "../browser/ui/views/payments/payment_request_interactive_uitest_base.h", + ] + } if (is_linux) { if (!is_chromeos) { # Desktop linux. @@ -2001,10 +2010,8 @@ # TODO(crbug.com/679127): Enable these tests on "mac_views_browser" once it # is supported. if (is_linux || is_win) { - sources += [ - "../browser/payments/payment_request_web_contents_manager_browsertest.cc", - "../browser/payments/site_per_process_payments_browsertest.cc", - ] + sources += + [ "../browser/payments/site_per_process_payments_browsertest.cc" ] } if (!enable_one_click_signin) {
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc index 12702868..e569609 100644 --- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
@@ -293,6 +293,8 @@ DCHECK(web_data_backend_); scoped_observer_.Add(web_data_backend_); + + LoadMetadata(); } AutocompleteSyncBridge::~AutocompleteSyncBridge() { @@ -390,6 +392,55 @@ callback.Run(std::move(batch)); } +void AutocompleteSyncBridge::ActOnLocalChanges( + const AutofillChangeList& changes) { + if (!change_processor()->IsTrackingMetadata()) { + return; + } + + auto metadata_change_list = base::MakeUnique<AutofillMetadataChangeList>( + GetAutofillTable(), syncer::AUTOFILL); + for (const auto& change : changes) { + const std::string storage_key = GetStorageKeyFromModel(change.key()); + switch (change.type()) { + case AutofillChange::ADD: + case AutofillChange::UPDATE: { + base::Time date_created, date_last_used; + bool success = GetAutofillTable()->GetAutofillTimestamps( + change.key().name(), change.key().value(), &date_created, + &date_last_used); + if (!success) { + change_processor()->ReportError( + FROM_HERE, "Failed reading autofill entry from WebDatabase."); + return; + } + + const AutofillEntry entry(change.key(), date_created, date_last_used); + change_processor()->Put(storage_key, CreateEntityData(entry), + metadata_change_list.get()); + break; + } + case AutofillChange::REMOVE: { + change_processor()->Delete(storage_key, metadata_change_list.get()); + break; + } + } + } + + if (Optional<ModelError> error = metadata_change_list->TakeError()) + change_processor()->ReportError(error.value()); +} + +void AutocompleteSyncBridge::LoadMetadata() { + auto batch = base::MakeUnique<syncer::MetadataBatch>(); + if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL, batch.get())) { + change_processor()->ReportError( + FROM_HERE, "Failed reading autofill metadata from WebDatabase."); + return; + } + change_processor()->ModelReadyToSync(std::move(batch)); +} + std::string AutocompleteSyncBridge::GetClientTag( const EntityData& entity_data) { DCHECK(entity_data.specifics.has_autofill()); @@ -411,6 +462,7 @@ void AutocompleteSyncBridge::AutofillEntriesChanged( const AutofillChangeList& changes) { DCHECK(thread_checker_.CalledOnValidThread()); + ActOnLocalChanges(changes); } AutofillTable* AutocompleteSyncBridge::GetAutofillTable() const {
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h index 9629858..cd350be 100644 --- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h +++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
@@ -42,7 +42,7 @@ static AutocompleteSyncBridge* FromWebDataService( AutofillWebDataService* web_data_service); - // syncer::ModelTypeService implementation. + // syncer::ModelTypeSyncBridge implementation. std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() override; base::Optional<syncer::ModelError> MergeSyncData( @@ -70,11 +70,13 @@ // Returns the table associated with the |web_data_backend_|. AutofillTable* GetAutofillTable() const; - std::string GetStorageKeyFromAutofillEntry( - const autofill::AutofillEntry& entry); + // Respond to local autofill entries changing by notifying sync of the + // changes. + void ActOnLocalChanges(const AutofillChangeList& changes); - static std::string FormatStorageKey(const std::string& name, - const std::string& value); + // Synchronously load sync metadata from the autofill table and pass it to the + // processor so that it can start tracking changes. + void LoadMetadata(); base::ThreadChecker thread_checker_;
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc index 515b8748..b12d0ef 100644 --- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -16,18 +16,22 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h" #include "components/sync/model/data_batch.h" -#include "components/sync/model/fake_model_type_change_processor.h" #include "components/sync/model/metadata_batch.h" #include "components/sync/model/model_error.h" +#include "components/sync/model/recording_model_type_change_processor.h" #include "components/webdata/common/web_database.h" #include "testing/gtest/include/gtest/gtest.h" +using base::UTF8ToUTF16; using base::ScopedTempDir; using base::Time; +using base::TimeDelta; using sync_pb::AutofillSpecifics; using sync_pb::EntitySpecifics; using syncer::DataBatch; @@ -79,16 +83,9 @@ EXPECT_TRUE(expected.empty()); } -std::unique_ptr<ModelTypeChangeProcessor> CreateModelTypeChangeProcessor( - ModelType type, - ModelTypeSyncBridge* bridge) { - return base::MakeUnique<FakeModelTypeChangeProcessor>(); -} - -AutofillEntry CreateAutofillEntry( - const sync_pb::AutofillSpecifics& autofill_specifics) { - AutofillKey key(base::UTF8ToUTF16(autofill_specifics.name()), - base::UTF8ToUTF16(autofill_specifics.value())); +AutofillEntry CreateAutofillEntry(const AutofillSpecifics& autofill_specifics) { + AutofillKey key(UTF8ToUTF16(autofill_specifics.name()), + UTF8ToUTF16(autofill_specifics.value())); Time date_created, date_last_used; const google::protobuf::RepeatedField<int64_t>& timestamps = autofill_specifics.usage_timestamp(); @@ -99,7 +96,6 @@ return AutofillEntry(key, date_created, date_last_used); } -// Creates an EntityData/EntityDataPtr around a copy of the given specifics. EntityDataPtr SpecificsToEntity(const AutofillSpecifics& specifics) { EntityData data; data.client_tag_hash = "ignored"; @@ -135,15 +131,19 @@ db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase")); backend_.SetWebDatabase(&db_); + sync_pb::ModelTypeState model_type_state; + model_type_state.set_initial_sync_done(true); + table_.UpdateModelTypeState(syncer::AUTOFILL, model_type_state); + bridge_.reset(new AutocompleteSyncBridge( - &backend_, base::Bind(&CreateModelTypeChangeProcessor))); + &backend_, + base::Bind( + &AutocompleteSyncBridgeTest::CreateModelTypeChangeProcessor, + base::Unretained(this)))); } } ~AutocompleteSyncBridgeTest() override {} - protected: - AutocompleteSyncBridge* bridge() { return bridge_.get(); } - void SaveSpecificsToTable( const std::vector<AutofillSpecifics>& specifics_list) { std::vector<AutofillEntry> new_entries; @@ -217,13 +217,49 @@ bridge()->GetAllData(base::Bind(&VerifyDataBatch, ExpectedMap(expected))); } + void VerifyProcessorRecordedPut(const AutofillSpecifics& specifics, + int position = 0) { + const std::string storage_key = GetStorageKey(specifics); + auto recorded_specifics_iterator = + processor()->put_multimap().find(storage_key); + + EXPECT_NE(processor()->put_multimap().end(), recorded_specifics_iterator); + while (position > 0) { + recorded_specifics_iterator++; + EXPECT_NE(processor()->put_multimap().end(), recorded_specifics_iterator); + position--; + } + + AutofillSpecifics recorded_specifics = + recorded_specifics_iterator->second->specifics.autofill(); + VerifyEqual(recorded_specifics, specifics); + } + + AutocompleteSyncBridge* bridge() { return bridge_.get(); } + + syncer::RecordingModelTypeChangeProcessor* processor() { return processor_; } + + AutofillTable* table() { return &table_; } + private: + std::unique_ptr<syncer::ModelTypeChangeProcessor> + CreateModelTypeChangeProcessor(syncer::ModelType type, + syncer::ModelTypeSyncBridge* bridge) { + auto processor = + base::MakeUnique<syncer::RecordingModelTypeChangeProcessor>(); + processor_ = processor.get(); + return std::move(processor); + } + ScopedTempDir temp_dir_; base::MessageLoop message_loop_; FakeAutofillBackend backend_; AutofillTable table_; WebDatabase db_; std::unique_ptr<AutocompleteSyncBridge> bridge_; + // A non-owning pointer to the processor given to the bridge. Will be null + // before being given to the bridge, to make ownership easier. + syncer::RecordingModelTypeChangeProcessor* processor_ = nullptr; DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncBridgeTest); }; @@ -426,4 +462,63 @@ // making db calls and verify the errors are propagated up. } +TEST_F(AutocompleteSyncBridgeTest, LocalEntriesAdded) { + const AutofillSpecifics added_specifics1 = CreateSpecifics(1, {2, 3}); + const AutofillSpecifics added_specifics2 = CreateSpecifics(2, {2, 3}); + + const AutofillEntry added_entry1 = CreateAutofillEntry(added_specifics1); + const AutofillEntry added_entry2 = CreateAutofillEntry(added_specifics2); + + table()->UpdateAutofillEntries({added_entry1, added_entry2}); + + bridge()->AutofillEntriesChanged( + {AutofillChange(AutofillChange::ADD, added_entry1.key()), + AutofillChange(AutofillChange::ADD, added_entry2.key())}); + + EXPECT_EQ(2u, processor()->put_multimap().size()); + + VerifyProcessorRecordedPut(added_specifics1); + VerifyProcessorRecordedPut(added_specifics2); +} + +TEST_F(AutocompleteSyncBridgeTest, LocalEntryAddedThenUpdated) { + const AutofillSpecifics added_specifics = CreateSpecifics(1, {2, 3}); + const AutofillEntry added_entry = CreateAutofillEntry(added_specifics); + table()->UpdateAutofillEntries({added_entry}); + + bridge()->AutofillEntriesChanged( + {AutofillChange(AutofillChange::ADD, added_entry.key())}); + + EXPECT_EQ(1u, processor()->put_multimap().size()); + + VerifyProcessorRecordedPut(added_specifics); + + const AutofillSpecifics updated_specifics = CreateSpecifics(1, {2, 4}); + const AutofillEntry updated_entry = CreateAutofillEntry(updated_specifics); + table()->UpdateAutofillEntries({updated_entry}); + + bridge()->AutofillEntriesChanged( + {AutofillChange(AutofillChange::UPDATE, updated_entry.key())}); + + VerifyProcessorRecordedPut(updated_specifics, 1); +} + +TEST_F(AutocompleteSyncBridgeTest, LocalEntryDeleted) { + const AutofillSpecifics deleted_specifics = CreateSpecifics(1, {2, 3}); + const AutofillEntry deleted_entry = CreateAutofillEntry(deleted_specifics); + const std::string storage_key = GetStorageKey(deleted_specifics); + + bridge()->AutofillEntriesChanged( + {AutofillChange(AutofillChange::REMOVE, deleted_entry.key())}); + + EXPECT_EQ(1u, processor()->delete_set().size()); + EXPECT_NE(processor()->delete_set().end(), + processor()->delete_set().find(storage_key)); +} + +TEST_F(AutocompleteSyncBridgeTest, LoadMetadataCalled) { + EXPECT_NE(processor()->metadata(), nullptr); + EXPECT_TRUE(processor()->metadata()->GetModelTypeState().initial_sync_done()); +} + } // namespace autofill
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index bccbad7..adb1b1ed 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -1446,6 +1446,7 @@ void ProfileSyncService::OnConfigureStart() { DCHECK(thread_checker_.CalledOnValidThread()); sync_configure_start_time_ = base::Time::Now(); + engine_->StartConfiguration(); NotifyObservers(); }
diff --git a/components/cryptauth/BUILD.gn b/components/cryptauth/BUILD.gn index 6093685..e8e14798 100644 --- a/components/cryptauth/BUILD.gn +++ b/components/cryptauth/BUILD.gn
@@ -132,6 +132,7 @@ ":cryptauth", ":test_support", "//base/test:test_support", + "//components/cryptauth/ble:unit_tests", "//components/gcm_driver:test_support", "//components/prefs:test_support", "//google_apis:test_support",
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc index c8b69df..e0dc88d1 100644 --- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc +++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -40,6 +40,8 @@ namespace cryptauth { namespace { +const std::string kTestFeature = "testFeature"; + class MockBluetoothThrottler : public BluetoothThrottler { public: MockBluetoothThrottler() {} @@ -175,10 +177,11 @@ void SetMaxPacketSize(uint16_t size) override { max_packet_size_ = size; } std::vector<Packet> EncodeDataMessage(std::string message) override { - if (message == kSmallMessage && max_packet_size_ == kDefaultMaxPacketSize) { + if (message == (kTestFeature + "," + kSmallMessage) + && max_packet_size_ == kDefaultMaxPacketSize) { return kSmallPackets; - } else if (message == kLargeMessage && - max_packet_size_ == kLargeMaxPacketSize) { + } else if (message == (kTestFeature + "," + kLargeMessage) + && max_packet_size_ == kLargeMaxPacketSize) { return kLargePackets; } else { NOTREACHED(); @@ -350,7 +353,6 @@ notify_session_alias_(NULL), bluetooth_throttler_(new NiceMock<MockBluetoothThrottler>), task_runner_(new base::TestSimpleTaskRunner), - last_completed_wire_message_(""), generator_factory_( new MockBluetoothLowEnergyWeavePacketGeneratorFactory()), receiver_factory_( @@ -599,7 +601,6 @@ std::unique_ptr<MockBluetoothThrottler> bluetooth_throttler_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; base::MessageLoop message_loop_; - WireMessage last_completed_wire_message_; bool last_wire_message_success_; std::shared_ptr<MockBluetoothLowEnergyWeavePacketGeneratorFactory> generator_factory_; @@ -806,7 +807,8 @@ SaveArg<1>(&write_remote_characteristic_success_callback_), SaveArg<2>(&write_remote_characteristic_error_callback_))); - connection->SendMessage(base::MakeUnique<FakeWireMessage>(kSmallMessage)); + connection->SendMessage( + base::MakeUnique<FakeWireMessage>(kSmallMessage, kTestFeature)); EXPECT_EQ(last_value_written_on_tx_characteristic_, kSmallPackets0); @@ -832,7 +834,8 @@ SaveArg<1>(&write_remote_characteristic_success_callback_), SaveArg<2>(&write_remote_characteristic_error_callback_))); - connection->SendMessage(base::MakeUnique<FakeWireMessage>(kLargeMessage)); + connection->SendMessage( + base::MakeUnique<FakeWireMessage>(kLargeMessage, kTestFeature)); EXPECT_EQ(last_value_written_on_tx_characteristic_, kLargePackets0); std::vector<uint8_t> bytes_received( @@ -873,7 +876,8 @@ SaveArg<1>(&write_remote_characteristic_success_callback_), SaveArg<2>(&write_remote_characteristic_error_callback_))); - connection->SendMessage(base::MakeUnique<FakeWireMessage>(kSmallMessage)); + connection->SendMessage( + base::MakeUnique<FakeWireMessage>(kSmallMessage, kTestFeature)); for (int i = 0; i < kMaxNumberOfTries; i++) { EXPECT_EQ(last_value_written_on_tx_characteristic_, kSmallPackets0); @@ -949,7 +953,8 @@ SaveArg<1>(&write_remote_characteristic_success_callback_), SaveArg<2>(&write_remote_characteristic_error_callback_))); - connection->SendMessage(base::MakeUnique<FakeWireMessage>(kLargeMessage)); + connection->SendMessage( + base::MakeUnique<FakeWireMessage>(kLargeMessage, kTestFeature)); connection->GattCharacteristicValueChanged( adapter_.get(), rx_characteristic_.get(), kErroneousPacket);
diff --git a/components/cryptauth/ble/fake_wire_message.cc b/components/cryptauth/ble/fake_wire_message.cc index 31ea442..8853299 100644 --- a/components/cryptauth/ble/fake_wire_message.cc +++ b/components/cryptauth/ble/fake_wire_message.cc
@@ -12,18 +12,12 @@ namespace cryptauth { -FakeWireMessage::FakeWireMessage(const std::string& payload) - : WireMessage(payload) {} - -std::unique_ptr<FakeWireMessage> FakeWireMessage::Deserialize( - const std::string& serialized_message, - bool* is_incomplete_message) { - *is_incomplete_message = false; - return std::unique_ptr<FakeWireMessage>( - new FakeWireMessage(serialized_message)); -} +FakeWireMessage::FakeWireMessage( + const std::string& payload, const std::string& feature) + : WireMessage(payload, feature) {} std::string FakeWireMessage::Serialize() const { - return std::string(payload()); + return feature() + "," + payload(); } + }
diff --git a/components/cryptauth/ble/fake_wire_message.h b/components/cryptauth/ble/fake_wire_message.h index 85cb82b..aa179e0 100644 --- a/components/cryptauth/ble/fake_wire_message.h +++ b/components/cryptauth/ble/fake_wire_message.h
@@ -15,17 +15,15 @@ class FakeWireMessage : public WireMessage { public: - FakeWireMessage(const std::string& payload); + FakeWireMessage(const std::string& payload, const std::string& feature); - static std::unique_ptr<FakeWireMessage> Deserialize( - const std::string& serialized_message, - bool* is_incomplete_message); - + // WireMessage: std::string Serialize() const override; private: DISALLOW_COPY_AND_ASSIGN(FakeWireMessage); }; -} + +} // namespace cryptauth #endif // COMPONENTS_CRYPTAUTH_WIRE_MESSAGE_H
diff --git a/components/cryptauth/connection_unittest.cc b/components/cryptauth/connection_unittest.cc index 82e09c2..4d66fc4 100644 --- a/components/cryptauth/connection_unittest.cc +++ b/components/cryptauth/connection_unittest.cc
@@ -78,7 +78,7 @@ // Unlike WireMessage, offers a public constructor. class TestWireMessage : public WireMessage { public: - TestWireMessage() : WireMessage(std::string()) {} + TestWireMessage() : WireMessage("payload", "feature") {} ~TestWireMessage() override {} private:
diff --git a/components/cryptauth/fake_connection.cc b/components/cryptauth/fake_connection.cc index 650f62e..c5008fce 100644 --- a/components/cryptauth/fake_connection.cc +++ b/components/cryptauth/fake_connection.cc
@@ -11,6 +11,10 @@ namespace cryptauth { +namespace { +const char kFakeFeatureName[] = "fakeFeature"; +} // namespace + FakeConnection::FakeConnection(const cryptauth::RemoteDevice& remote_device) : Connection(remote_device) { Connect(); @@ -50,7 +54,8 @@ std::unique_ptr<WireMessage> FakeConnection::DeserializeWireMessage( bool* is_incomplete_message) { *is_incomplete_message = false; - return base::MakeUnique<WireMessage>(pending_payload_); + return base::MakeUnique<WireMessage>( + pending_payload_, std::string(kFakeFeatureName)); } } // namespace cryptauth
diff --git a/components/cryptauth/wire_message.cc b/components/cryptauth/wire_message.cc index 7b26d7d..b91b943 100644 --- a/components/cryptauth/wire_message.cc +++ b/components/cryptauth/wire_message.cc
@@ -33,7 +33,14 @@ const int kMessageFormatVersionThree = 3; const char kPayloadKey[] = "payload"; -const char kPermitIdKey[] = "permit_id"; +const char kFeatureKey[] = "feature"; + +// The default feature value. This is the default for backward compatibility +// reasons; previously, the protocol did not transmit the feature in the +// message, but because EasyUnlock was the only feature used, it didn't matter. +// So, if a message is received without a feature, it is assumed to be +// EasyUnlock by default. +const char kDefaultFeature[] = "easy_unlock"; // Parses the |serialized_message|'s header. Returns |true| iff the message has // a valid header, is complete, and is well-formed according to the header. Sets @@ -83,29 +90,24 @@ const std::string& serialized_message, bool* is_incomplete_message) { if (!ParseHeader(serialized_message, is_incomplete_message)) - return std::unique_ptr<WireMessage>(); + return nullptr; std::unique_ptr<base::Value> body_value = base::JSONReader::Read(serialized_message.substr(kHeaderLength)); if (!body_value || !body_value->IsType(base::Value::Type::DICTIONARY)) { PA_LOG(WARNING) << "Error: Unable to parse message as JSON."; - return std::unique_ptr<WireMessage>(); + return nullptr; } base::DictionaryValue* body; bool success = body_value->GetAsDictionary(&body); DCHECK(success); - // The permit ID is optional. In the Easy Unlock protocol, only the first - // message includes this field. - std::string permit_id; - body->GetString(kPermitIdKey, &permit_id); - std::string payload_base64; if (!body->GetString(kPayloadKey, &payload_base64) || payload_base64.empty()) { PA_LOG(WARNING) << "Error: Missing payload."; - return std::unique_ptr<WireMessage>(); + return nullptr; } std::string payload; @@ -113,10 +115,15 @@ base::Base64UrlDecodePolicy::REQUIRE_PADDING, &payload)) { PA_LOG(WARNING) << "Error: Invalid base64 encoding for payload."; - return std::unique_ptr<WireMessage>(); + return nullptr; } - return base::WrapUnique(new WireMessage(payload, permit_id)); + std::string feature; + if (!body->GetString(kFeatureKey, &feature) || feature.empty()) { + feature = std::string(kDefaultFeature); + } + + return base::WrapUnique(new WireMessage(payload, feature)); } std::string WireMessage::Serialize() const { @@ -127,13 +134,12 @@ // Create JSON body containing permit id and payload. base::DictionaryValue body; - if (!permit_id_.empty()) - body.SetString(kPermitIdKey, permit_id_); std::string base64_payload; base::Base64UrlEncode(payload_, base::Base64UrlEncodePolicy::INCLUDE_PADDING, &base64_payload); body.SetString(kPayloadKey, base64_payload); + body.SetString(kFeatureKey, feature_); std::string json_body; if (!base::JSONWriter::Write(body, &json_body)) { @@ -161,11 +167,7 @@ return header_string + json_body; } -WireMessage::WireMessage(const std::string& payload) - : WireMessage(payload, std::string()) {} - -WireMessage::WireMessage(const std::string& payload, - const std::string& permit_id) - : payload_(payload), permit_id_(permit_id) {} +WireMessage::WireMessage(const std::string& payload, const std::string& feature) + : payload_(payload), feature_(feature) {} } // namespace cryptauth
diff --git a/components/cryptauth/wire_message.h b/components/cryptauth/wire_message.h index b691462..cbb34054 100644 --- a/components/cryptauth/wire_message.h +++ b/components/cryptauth/wire_message.h
@@ -14,18 +14,15 @@ class WireMessage { public: - // Creates a WireMessage containing |payload|. - explicit WireMessage(const std::string& payload); - - // Creates a WireMessage containing |payload| and |permit_id| in the metadata. - WireMessage(const std::string& payload, const std::string& permit_id); - + // Creates a WireMessage containing |payload| for feature |feature|. + explicit WireMessage(const std::string& payload, const std::string& feature); virtual ~WireMessage(); - // Returns the deserialized message from |serialized_message|, or NULL if the - // message is malformed. Sets |is_incomplete_message| to true if the message - // does not have enough data to parse the header, or if the message length - // encoded in the message header exceeds the size of the |serialized_message|. + // Returns the deserialized message from |serialized_message|, or nullptr if + // the message is malformed. Sets |is_incomplete_message| to true if the + // message does not have enough data to parse the header, or if the message + // length encoded in the message header exceeds the size of the + // |serialized_message|. static std::unique_ptr<WireMessage> Deserialize( const std::string& serialized_message, bool* is_incomplete_message); @@ -34,18 +31,15 @@ virtual std::string Serialize() const; const std::string& payload() const { return payload_; } - const std::string& permit_id() const { return permit_id_; } + const std::string& feature() const { return feature_; } private: // The message payload. const std::string payload_; - // Identifier of the permit being used. A permit contains the credentials used - // to authenticate a device. For example, when sending a WireMessage to the - // remote device the |permit_id_| indexes a permit possibly containing the - // public key - // of the local device or a symmetric key shared between the devices. - const std::string permit_id_; + // The feature which sends or intends to receive this message (e.g., + // EasyUnlock). + const std::string feature_; DISALLOW_COPY_AND_ASSIGN(WireMessage); };
diff --git a/components/cryptauth/wire_message_unittest.cc b/components/cryptauth/wire_message_unittest.cc index 84dc625..7c7caca3 100644 --- a/components/cryptauth/wire_message_unittest.cc +++ b/components/cryptauth/wire_message_unittest.cc
@@ -11,7 +11,16 @@ namespace cryptauth { -TEST(ProximityAuthWireMessage, Deserialize_EmptyMessage) { +class CryptAuthWireMessageTest : public testing::Test { + protected: + CryptAuthWireMessageTest() {} + ~CryptAuthWireMessageTest() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(CryptAuthWireMessageTest); +}; + +TEST(CryptAuthWireMessageTest, Deserialize_EmptyMessage) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(std::string(), &is_incomplete); @@ -19,7 +28,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_IncompleteHeader) { +TEST(CryptAuthWireMessageTest, Deserialize_IncompleteHeader) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize("\3", &is_incomplete); @@ -27,7 +36,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_UnexpectedMessageFormatVersion) { +TEST(CryptAuthWireMessageTest, Deserialize_UnexpectedMessageFormatVersion) { bool is_incomplete; // Version 2 is below the minimum supported version. std::unique_ptr<WireMessage> message = @@ -36,7 +45,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_BodyOfSizeZero) { +TEST(CryptAuthWireMessageTest, Deserialize_BodyOfSizeZero) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(std::string("\3\0\0", 3), &is_incomplete); @@ -44,7 +53,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_IncompleteBody) { +TEST(CryptAuthWireMessageTest, Deserialize_IncompleteBody) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(std::string("\3\0\5", 3), &is_incomplete); @@ -52,7 +61,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_BodyLongerThanSpecifiedInHeader) { +TEST(CryptAuthWireMessageTest, Deserialize_BodyLongerThanSpecifiedInHeader) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize( std::string("\3\0\5", 3) + "123456", &is_incomplete); @@ -60,7 +69,7 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_BodyIsNotValidJSON) { +TEST(CryptAuthWireMessageTest, Deserialize_BodyIsNotValidJSON) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize( std::string("\3\0\5", 3) + "12345", &is_incomplete); @@ -68,122 +77,101 @@ EXPECT_FALSE(message); } -TEST(ProximityAuthWireMessage, Deserialize_BodyIsNotADictionary) { +TEST(CryptAuthWireMessageTest, Deserialize_BodyIsNotADictionary) { + bool is_incomplete; + std::string header("\3\0\x15", 3); + std::string bytes = + header + "[{\"payload\": \"YQ==\"}]"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(CryptAuthWireMessageTest, Deserialize_BodyLacksPayload) { + bool is_incomplete; + std::string header("\3\0\x02", 3); + std::string bytes = header + "{}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(CryptAuthWireMessageTest, Deserialize_BodyHasEmptyPayload) { bool is_incomplete; std::string header("\3\0\x29", 3); + std::string bytes = header + + "{\"payload\": \"\", \"feature\": \"testFeature\"}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(CryptAuthWireMessageTest, Deserialize_PayloadIsNotBase64Encoded) { + bool is_incomplete; + std::string header("\3\0\x30", 3); std::string bytes = - header + "[{\"permit_id\": \"Hi!\", \"payload\": \"YQ==\"}]"; + header + "{\"payload\": \"garbage\", \"feature\": \"testFeature\"}"; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(bytes, &is_incomplete); EXPECT_FALSE(is_incomplete); EXPECT_FALSE(message); } -// The permit ID is optional. -TEST(ProximityAuthWireMessage, Deserialize_BodyLacksPermitId) { +TEST(CryptAuthWireMessageTest, Deserialize_ValidMessage) { bool is_incomplete; - std::string header("\3\0\x13", 3); - std::string bytes = header + "{\"payload\": \"YQ==\"}"; - std::unique_ptr<WireMessage> message = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - EXPECT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); - EXPECT_EQ("a", message->payload()); -} - -TEST(ProximityAuthWireMessage, Deserialize_BodyLacksPayload) { - bool is_incomplete; - std::string header("\3\0\x14", 3); - std::string bytes = header + "{\"permit_id\": \"Hi!\"}"; - std::unique_ptr<WireMessage> message = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - EXPECT_FALSE(message); -} - -// The permit ID is optional. -TEST(ProximityAuthWireMessage, Deserialize_BodyHasEmptyPermitId) { - bool is_incomplete; - std::string header("\3\0\x24", 3); - std::string bytes = header + "{\"permit_id\": \"\", \"payload\": \"YQ==\"}"; - std::unique_ptr<WireMessage> message = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - EXPECT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); - EXPECT_EQ("a", message->payload()); -} - -TEST(ProximityAuthWireMessage, Deserialize_BodyHasEmptyPayload) { - bool is_incomplete; - std::string header("\3\0\x23", 3); - std::string bytes = header + "{\"permit_id\": \"Hi!\", \"payload\": \"\"}"; - std::unique_ptr<WireMessage> message = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - EXPECT_FALSE(message); -} - -TEST(ProximityAuthWireMessage, Deserialize_PayloadIsNotBase64Encoded) { - bool is_incomplete; - std::string header("\3\0\x2A", 3); + std::string header("\3\0\x2d", 3); std::string bytes = - header + "{\"permit_id\": \"Hi!\", \"payload\": \"garbage\"}"; - std::unique_ptr<WireMessage> message = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - EXPECT_FALSE(message); -} - -TEST(ProximityAuthWireMessage, Deserialize_ValidMessage) { - bool is_incomplete; - std::string header("\3\0\x27", 3); - std::string bytes = - header + "{\"permit_id\": \"Hi!\", \"payload\": \"YQ==\"}"; + header + "{\"payload\": \"YQ==\", \"feature\": \"testFeature\"}"; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(bytes, &is_incomplete); EXPECT_FALSE(is_incomplete); ASSERT_TRUE(message); - EXPECT_EQ("Hi!", message->permit_id()); EXPECT_EQ("a", message->payload()); + EXPECT_EQ("testFeature", message->feature()); } -TEST(ProximityAuthWireMessage, Deserialize_ValidMessageWithBase64UrlEncoding) { +TEST(CryptAuthWireMessageTest, Deserialize_ValidMessageWithBase64UrlEncoding) { bool is_incomplete; - std::string header("\3\0\x27", 3); + std::string header("\3\0\x2d", 3); std::string bytes = - header + "{\"permit_id\": \"Hi!\", \"payload\": \"_-Y=\"}"; + header + "{\"payload\": \"_-Y=\", \"feature\": \"testFeature\"}"; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(bytes, &is_incomplete); EXPECT_FALSE(is_incomplete); ASSERT_TRUE(message); - EXPECT_EQ("Hi!", message->permit_id()); EXPECT_EQ("\xFF\xE6", message->payload()); + EXPECT_EQ("testFeature", message->feature()); } -TEST(ProximityAuthWireMessage, Deserialize_ValidMessageWithExtraUnknownFields) { +TEST(CryptAuthWireMessageTest, Deserialize_ValidMessageWithExtraUnknownFields) { bool is_incomplete; - std::string header("\3\0\x46", 3); + std::string header("\3\0\x4c", 3); std::string bytes = header + "{" - " \"permit_id\": \"Hi!\"," " \"payload\": \"YQ==\"," + " \"feature\": \"testFeature\"," " \"unexpected\": \"surprise!\"" "}"; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(bytes, &is_incomplete); EXPECT_FALSE(is_incomplete); ASSERT_TRUE(message); - EXPECT_EQ("Hi!", message->permit_id()); EXPECT_EQ("a", message->payload()); + EXPECT_EQ("testFeature", message->feature()); } -TEST(ProximityAuthWireMessage, Deserialize_SizeEquals0x01FF) { +TEST(CryptAuthWireMessageTest, Deserialize_SizeEquals0x01FF) { // Create a message with a body of 0x01FF bytes to test the size contained in // the header is parsed correctly. std::string header("\3\x01\xff", 3); - char json_template[] = "{\"payload\":\"YQ==\", \"filler\":\"$1\"}"; + char json_template[] = "{" + " \"payload\":\"YQ==\"," + " \"feature\": \"testFeature\"," + " \"filler\":\"$1\"" + "}"; // Add 3 to the size to take into account the "$1" and NUL terminator ("\0") // characters in |json_template|. uint16_t filler_size = 0x01ff - sizeof(json_template) + 3; @@ -199,37 +187,25 @@ EXPECT_FALSE(is_incomplete); ASSERT_TRUE(message); EXPECT_EQ("a", message->payload()); + EXPECT_EQ("testFeature", message->feature()); } -TEST(ProximityAuthWireMessage, Serialize_WithPermitId) { - WireMessage message1("example payload", "example id"); - std::string bytes = message1.Serialize(); - ASSERT_FALSE(bytes.empty()); - +TEST(CryptAuthWireMessageTest, Serialize_WithoutFeature) { bool is_incomplete; - std::unique_ptr<WireMessage> message2 = + std::string header("\3\0\x13", 3); + std::string bytes = header + "{\"payload\": \"YQ==\"}"; + std::unique_ptr<WireMessage> message = WireMessage::Deserialize(bytes, &is_incomplete); EXPECT_FALSE(is_incomplete); - ASSERT_TRUE(message2); - EXPECT_EQ("example id", message2->permit_id()); - EXPECT_EQ("example payload", message2->payload()); + EXPECT_TRUE(message); + EXPECT_EQ("a", message->payload()); + + // If unspecified, the default feature is "easy_unlock" for backwards + // compatibility. + EXPECT_EQ("easy_unlock", message->feature()); } -TEST(ProximityAuthWireMessage, Serialize_WithoutPermitId) { - WireMessage message1("example payload"); - std::string bytes = message1.Serialize(); - ASSERT_FALSE(bytes.empty()); - - bool is_incomplete; - std::unique_ptr<WireMessage> message2 = - WireMessage::Deserialize(bytes, &is_incomplete); - EXPECT_FALSE(is_incomplete); - ASSERT_TRUE(message2); - EXPECT_EQ(std::string(), message2->permit_id()); - EXPECT_EQ("example payload", message2->payload()); -} - -TEST(ProximityAuthWireMessage, Serialize_FailsWithoutPayload) { +TEST(CryptAuthWireMessageTest, Serialize_FailsWithoutPayload) { WireMessage message1(std::string(), "example id"); std::string bytes = message1.Serialize(); EXPECT_TRUE(bytes.empty());
diff --git a/components/password_manager/content/browser/credential_manager_impl.cc b/components/password_manager/content/browser/credential_manager_impl.cc index 3f7a88e7..7c01bea 100644 --- a/components/password_manager/content/browser/credential_manager_impl.cc +++ b/components/password_manager/content/browser/credential_manager_impl.cc
@@ -16,6 +16,7 @@ #include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/password_manager/core/browser/affiliated_match_helper.h" #include "components/password_manager/core/browser/credential_manager_logger.h" +#include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/form_saver.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" @@ -76,9 +77,14 @@ std::unique_ptr<autofill::PasswordForm> form( CreatePasswordFormFromCredentialInfo(credential, origin)); + std::unique_ptr<autofill::PasswordForm> observed_form = + CreateObservedPasswordFormFromOrigin(origin); + // Create a custom form fetcher with suppressed HTTP->HTTPS migration. + auto form_fetcher = base::MakeUnique<FormFetcherImpl>( + PasswordStore::FormDigest(*observed_form), client_, false); form_manager_ = base::MakeUnique<CredentialManagerPasswordFormManager>( - client_, GetDriver(), *CreateObservedPasswordFormFromOrigin(origin), - std::move(form), this, nullptr, nullptr); + client_, GetDriver(), *observed_form, std::move(form), this, nullptr, + std::move(form_fetcher)); } void CredentialManagerImpl::OnProvisionalSaveComplete() {
diff --git a/components/password_manager/content/browser/credential_manager_impl_unittest.cc b/components/password_manager/content/browser/credential_manager_impl_unittest.cc index 887fb91..103f830 100644 --- a/components/password_manager/content/browser/credential_manager_impl_unittest.cc +++ b/components/password_manager/content/browser/credential_manager_impl_unittest.cc
@@ -35,6 +35,8 @@ #include "content/public/test/test_renderer_host.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/url_constants.h" using content::BrowserContext; using content::WebContents; @@ -197,6 +199,12 @@ *out_info = info; } +GURL HttpURLFromHttps(const GURL& https_url) { + GURL::Replacements rep; + rep.SetSchemeStr(url::kHttpScheme); + return https_url.ReplaceComponents(rep); +} + } // namespace class CredentialManagerImplTest : public content::RenderViewHostTestHarness { @@ -1393,15 +1401,23 @@ // in. store_->AddLogin(affiliated_form1_); - auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper); - store_->SetAffiliatedMatchHelper(std::move(mock_helper)); + store_->SetAffiliatedMatchHelper( + base::MakeUnique<MockAffiliatedMatchHelper>()); + + std::vector<std::string> affiliated_realms; + PasswordStore::FormDigest digest = + cm_service_impl_->GetSynthesizedFormForOrigin(); + // First expect affiliations for the HTTPS domain. + static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper()) + ->ExpectCallToGetAffiliatedAndroidRealms(digest, affiliated_realms); + + digest.origin = HttpURLFromHttps(digest.origin); + digest.signon_realm = digest.origin.spec(); + // The second call happens for HTTP as the migration is triggered. + static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper()) + ->ExpectCallToGetAffiliatedAndroidRealms(digest, affiliated_realms); std::vector<GURL> federations; - std::vector<std::string> affiliated_realms; - static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper()) - ->ExpectCallToGetAffiliatedAndroidRealms( - cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms); - ExpectZeroClickSignInFailure(true, true, federations); } @@ -1446,6 +1462,20 @@ CredentialType::CREDENTIAL_TYPE_FEDERATED); } +TEST_F(CredentialManagerImplTest, ZeroClickAfterMigratingHttpCredential) { + // There is an http credential saved. It should be migrated and used for auto + // sign-in. + form_.origin = HttpURLFromHttps(form_.origin); + form_.signon_realm = form_.origin.GetOrigin().spec(); + // That is the default value for old credentials. + form_.skip_zero_click = true; + store_->AddLogin(form_); + + std::vector<GURL> federations; + ExpectZeroClickSignInSuccess(true, true, federations, + CredentialType::CREDENTIAL_TYPE_PASSWORD); +} + TEST_F(CredentialManagerImplTest, GetSynthesizedFormForOrigin) { PasswordStore::FormDigest synthesized = cm_service_impl_->GetSynthesizedFormForOrigin();
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager.cc b/components/password_manager/core/browser/credential_manager_password_form_manager.cc index 38224508..0677a17f 100644 --- a/components/password_manager/core/browser/credential_manager_password_form_manager.cc +++ b/components/password_manager/core/browser/credential_manager_password_form_manager.cc
@@ -26,7 +26,7 @@ std::unique_ptr<autofill::PasswordForm> saved_form, CredentialManagerPasswordFormManagerDelegate* delegate, std::unique_ptr<FormSaver> form_saver, - FormFetcher* form_fetcher) + std::unique_ptr<FormFetcher> form_fetcher) : PasswordFormManager(driver->GetPasswordManager(), client, driver, @@ -34,11 +34,15 @@ (form_saver ? std::move(form_saver) : base::MakeUnique<FormSaverImpl>( client->GetPasswordStore())), - form_fetcher), + form_fetcher.get()), delegate_(delegate), saved_form_(std::move(saved_form)), + form_fetcher_(std::move(form_fetcher)), weak_factory_(this) { DCHECK(saved_form_); + // This condition is only false on iOS. + if (form_fetcher_) + form_fetcher_->Fetch(); } CredentialManagerPasswordFormManager::~CredentialManagerPasswordFormManager() {
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager.h b/components/password_manager/core/browser/credential_manager_password_form_manager.h index 6ac5a18..d41f8079 100644 --- a/components/password_manager/core/browser/credential_manager_password_form_manager.h +++ b/components/password_manager/core/browser/credential_manager_password_form_manager.h
@@ -45,19 +45,24 @@ std::unique_ptr<autofill::PasswordForm> saved_form, CredentialManagerPasswordFormManagerDelegate* delegate, std::unique_ptr<FormSaver> form_saver, - FormFetcher* form_fetcher); + std::unique_ptr<FormFetcher> form_fetcher); ~CredentialManagerPasswordFormManager() override; void ProcessMatches( const std::vector<const autofill::PasswordForm*>& non_federated, size_t filtered_count) override; +#if defined(UNIT_TEST) + FormFetcher* form_fetcher() const { return form_fetcher_.get(); } +#endif // defined(UNIT_TEST) + private: // Calls OnProvisionalSaveComplete on |delegate_|. void NotifyDelegate(); CredentialManagerPasswordFormManagerDelegate* delegate_; std::unique_ptr<autofill::PasswordForm> saved_form_; + std::unique_ptr<FormFetcher> form_fetcher_; base::WeakPtrFactory<CredentialManagerPasswordFormManager> weak_factory_;
diff --git a/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc b/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc index b25176a7..88caa117 100644 --- a/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/credential_manager_password_form_manager_unittest.cc
@@ -50,29 +50,28 @@ TEST_F(CredentialManagerPasswordFormManagerTest, AbortEarly) { PasswordForm observed_form; MockDelegate delegate; - auto form_fetcher = base::MakeUnique<FakeFormFetcher>(); - form_fetcher->Fetch(); - CredentialManagerPasswordFormManager form_manager( + auto form_manager = base::MakeUnique<CredentialManagerPasswordFormManager>( &client_, driver_.AsWeakPtr(), observed_form, base::MakeUnique<PasswordForm>(observed_form), &delegate, - base::MakeUnique<StubFormSaver>(), form_fetcher.get()); + base::MakeUnique<StubFormSaver>(), base::MakeUnique<FakeFormFetcher>()); - auto deleter = [&form_fetcher]() { form_fetcher.reset(); }; + auto deleter = [&form_manager]() { form_manager.reset(); }; // Simulate that the PasswordStore responded to the FormFetcher. As a result, // |form_manager| should call the delegate's OnProvisionalSaveComplete, which // in turn should delete |form_fetcher|. EXPECT_CALL(delegate, OnProvisionalSaveComplete()).WillOnce(Invoke(deleter)); - form_fetcher->SetNonFederated(std::vector<const PasswordForm*>(), 0u); - // Check that |form_fetcher| was not deleted yet; doing so would have caused + static_cast<FakeFormFetcher*>(form_manager->form_fetcher()) + ->SetNonFederated(std::vector<const PasswordForm*>(), 0u); + // Check that |form_manager| was not deleted yet; doing so would have caused // use after free during SetNonFederated. - EXPECT_TRUE(form_fetcher); + EXPECT_TRUE(form_manager); base::RunLoop().RunUntilIdle(); // Ultimately, |form_fetcher| should have been deleted. It just should happen // after it finishes executing. - EXPECT_FALSE(form_fetcher); + EXPECT_FALSE(form_manager); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc index 8508bda2..a3a3747 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -122,6 +122,22 @@ void CredentialManagerPendingRequestTask::OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) { + if (results.empty()) { + // Try to migrate the HTTP passwords and process them later. + http_migrator_ = base::MakeUnique<HttpPasswordMigrator>( + origin_, delegate_->client()->GetPasswordStore(), this); + return; + } + ProcessForms(std::move(results)); +} + +void CredentialManagerPendingRequestTask::ProcessMigratedForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { + ProcessForms(std::move(forms)); +} + +void CredentialManagerPendingRequestTask::ProcessForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> results) { using metrics_util::LogCredentialManagerGetResult; metrics_util::CredentialManagerGetMediation mediation_status = zero_click_only_ ? metrics_util::CREDENTIAL_MANAGER_GET_UNMEDIATED
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.h b/components/password_manager/core/browser/credential_manager_pending_request_task.h index b29994a9..289a820e 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.h +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.h
@@ -5,12 +5,14 @@ #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_REQUEST_TASK_H_ #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_REQUEST_TASK_H_ +#include <memory> #include <set> #include <string> #include <vector> #include "base/callback_forward.h" #include "base/macros.h" +#include "components/password_manager/core/browser/http_password_migrator.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "url/gurl.h" @@ -51,7 +53,9 @@ }; // Retrieves credentials from the PasswordStore. -class CredentialManagerPendingRequestTask : public PasswordStoreConsumer { +class CredentialManagerPendingRequestTask + : public PasswordStoreConsumer, + public HttpPasswordMigrator::Consumer { public: CredentialManagerPendingRequestTask( CredentialManagerPendingRequestTaskDelegate* delegate, @@ -64,11 +68,18 @@ SendCredentialCallback send_callback() const { return send_callback_; } const GURL& origin() const { return origin_; } - // PasswordStoreConsumer implementation. + // PasswordStoreConsumer: void OnGetPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) override; private: + // HttpPasswordMigrator::Consumer: + void ProcessMigratedForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override; + + void ProcessForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> results); + CredentialManagerPendingRequestTaskDelegate* delegate_; // Weak; SendCredentialCallback send_callback_; const bool zero_click_only_; @@ -76,6 +87,8 @@ const bool include_passwords_; std::set<std::string> federations_; + std::unique_ptr<HttpPasswordMigrator> http_migrator_; + DISALLOW_COPY_AND_ASSIGN(CredentialManagerPendingRequestTask); };
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc index 72b71b71..e4f8ed6 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.cc +++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -59,12 +59,15 @@ } // namespace FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, - const PasswordManagerClient* client) - : form_digest_(std::move(form_digest)), client_(client) {} + const PasswordManagerClient* client, + bool should_migrate_http_passwords) + : form_digest_(std::move(form_digest)), + client_(client), + should_migrate_http_passwords_(should_migrate_http_passwords) {} FormFetcherImpl::~FormFetcherImpl() = default; -void FormFetcherImpl::AddConsumer(Consumer* consumer) { +void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { DCHECK(consumer); consumers_.insert(consumer); if (state_ == State::NOT_WAITING) @@ -105,21 +108,14 @@ logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); } - federated_ = SplitFederatedMatches(&results); - non_federated_ = std::move(results); + if (should_migrate_http_passwords_ && results.empty() && + form_digest_.origin.SchemeIs(url::kHttpsScheme)) { + http_migrator_ = base::MakeUnique<HttpPasswordMigrator>( + form_digest_.origin, client_->GetPasswordStore(), this); + return; + } - const size_t original_count = non_federated_.size(); - - non_federated_ = - client_->GetStoreResultFilter()->FilterResults(std::move(non_federated_)); - - filtered_count_ = original_count - non_federated_.size(); - - weak_non_federated_ = MakeWeakCopies(non_federated_); - weak_federated_ = MakeWeakCopies(federated_); - - for (Consumer* consumer : consumers_) - consumer->ProcessMatches(weak_non_federated_, filtered_count_); + ProcessPasswordStoreResults(std::move(results)); } void FormFetcherImpl::OnGetSiteStatistics( @@ -129,6 +125,11 @@ interactions_stats_ = std::move(stats); } +void FormFetcherImpl::ProcessMigratedForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { + ProcessPasswordStoreResults(std::move(forms)); +} + void FormFetcherImpl::Fetch() { std::unique_ptr<BrowserSavePasswordProgressLogger> logger; if (password_manager_util::IsLoggingActive(client_)) { @@ -164,4 +165,23 @@ #endif } +void FormFetcherImpl::ProcessPasswordStoreResults( + std::vector<std::unique_ptr<autofill::PasswordForm>> results) { + federated_ = SplitFederatedMatches(&results); + non_federated_ = std::move(results); + + const size_t original_count = non_federated_.size(); + + non_federated_ = + client_->GetStoreResultFilter()->FilterResults(std::move(non_federated_)); + + filtered_count_ = original_count - non_federated_.size(); + + weak_non_federated_ = MakeWeakCopies(non_federated_); + weak_federated_ = MakeWeakCopies(federated_); + + for (FormFetcher::Consumer* consumer : consumers_) + consumer->ProcessMatches(weak_non_federated_, filtered_count_); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/form_fetcher_impl.h b/components/password_manager/core/browser/form_fetcher_impl.h index b786f945..0a7b2a5 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.h +++ b/components/password_manager/core/browser/form_fetcher_impl.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "components/password_manager/core/browser/form_fetcher.h" +#include "components/password_manager/core/browser/http_password_migrator.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_consumer.h" @@ -20,17 +21,20 @@ // Production implementation of FormFetcher. Fetches credentials associated // with a particular origin. -class FormFetcherImpl : public FormFetcher, public PasswordStoreConsumer { +class FormFetcherImpl : public FormFetcher, + public PasswordStoreConsumer, + public HttpPasswordMigrator::Consumer { public: // |form_digest| describes what credentials need to be retrieved and // |client| serves the PasswordStore, the logging information etc. FormFetcherImpl(PasswordStore::FormDigest form_digest, - const PasswordManagerClient* client); + const PasswordManagerClient* client, + bool should_migrate_http_passwords); ~FormFetcherImpl() override; // FormFetcher: - void AddConsumer(Consumer* consumer) override; + void AddConsumer(FormFetcher::Consumer* consumer) override; State GetState() const override; const std::vector<InteractionsStats>& GetInteractionsStats() const override; const std::vector<const autofill::PasswordForm*>& GetFederatedMatches() @@ -42,7 +46,15 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> results) override; void OnGetSiteStatistics(std::vector<InteractionsStats> stats) override; + // HttpPasswordMigrator::Consumer: + void ProcessMigratedForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override; + private: + // Processes password form results and forwards them to the |consumers_|. + void ProcessPasswordStoreResults( + std::vector<std::unique_ptr<autofill::PasswordForm>> results); + // PasswordStore results will be fetched for this description. const PasswordStore::FormDigest form_digest_; @@ -62,7 +74,7 @@ std::vector<const autofill::PasswordForm*> weak_federated_; // Consumers of the fetcher, all are assumed to outlive |this|. - std::set<Consumer*> consumers_; + std::set<FormFetcher::Consumer*> consumers_; // Client used to obtain a CredentialFilter. const PasswordManagerClient* const client_; @@ -78,6 +90,12 @@ // password store returning results in the meantime. bool need_to_refetch_ = false; + // Indicates whether HTTP passwords should be migrated to HTTPS. + const bool should_migrate_http_passwords_; + + // Does the actual migration. + std::unique_ptr<HttpPasswordMigrator> http_migrator_; + DISALLOW_COPY_AND_ASSIGN(FormFetcherImpl); };
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc index 269abc9..9ab832f 100644 --- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc +++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -27,6 +27,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" +#include "url/url_constants.h" using autofill::PasswordForm; using base::ASCIIToUTF16; @@ -113,6 +114,17 @@ return form; } +// Creates a dummy non-federated HTTP form with some basic arbitrary values. +PasswordForm CreateHTTPNonFederated() { + PasswordForm form; + form.origin = GURL("http://example.in"); + form.signon_realm = form.origin.spec(); + form.action = GURL("http://login.example.org"); + form.username_value = ASCIIToUTF16("user"); + form.password_value = ASCIIToUTF16("password"); + return form; +} + // Creates a dummy federated form with some basic arbitrary values. PasswordForm CreateFederated() { PasswordForm form = CreateNonFederated(); @@ -131,6 +143,38 @@ return form; } +// Small helper that wraps passed in forms in unique ptrs. +std::vector<std::unique_ptr<PasswordForm>> make_results( + const std::vector<PasswordForm>& forms) { + std::vector<std::unique_ptr<PasswordForm>> results; + results.reserve(forms.size()); + for (const auto& form : forms) + results.push_back(base::MakeUnique<PasswordForm>(form)); + return results; +} + +class MockFormFetcherImpl : public FormFetcherImpl { + public: + // Inherit constructors. + using FormFetcherImpl::FormFetcherImpl; + + // Google Mock is currently unable to mock |ProcessMigratedForms| due to the + // presence of move-only types. In order to ensure it is called, a dummy is + // added which can be passed to |EXPECT_CALL|. + void ProcessMigratedForms( + std::vector<std::unique_ptr<autofill::PasswordForm>> results) override { + FormFetcherImpl::ProcessMigratedForms(std::move(results)); + ProcessMigratedFormsDummy(); + } + + MOCK_METHOD0(ProcessMigratedFormsDummy, void()); +}; + +ACTION(InvokeMigratorGetResults) { + static_cast<HttpPasswordMigrator*>(arg0)->OnGetPasswordStoreResults( + std::vector<std::unique_ptr<PasswordForm>>()); +} + } // namespace class FormFetcherImplTest : public testing::Test { @@ -142,7 +186,8 @@ mock_store_ = new MockPasswordStore(); client_.set_store(mock_store_.get()); - form_fetcher_ = base::MakeUnique<FormFetcherImpl>(form_digest_, &client_); + form_fetcher_ = base::MakeUnique<FormFetcherImpl>( + form_digest_, &client_, /* should_migrate_http_passwords */ false); } ~FormFetcherImplTest() override { mock_store_->ShutdownOnUIThread(); } @@ -362,4 +407,65 @@ } #endif +// Test that ensures HTTP passwords are not migrated on HTTP sites. +TEST_F(FormFetcherImplTest, DoNotTryToMigrateHTTPPasswordsOnHTTPSites) { + GURL::Replacements http_rep; + http_rep.SetSchemeStr(url::kHttpScheme); + const GURL http_origin = form_digest_.origin.ReplaceComponents(http_rep); + const PasswordStore::FormDigest http_form_digest( + PasswordForm::SCHEME_HTML, http_origin.GetOrigin().spec(), http_origin); + + // A new form fetcher is created to be able to set the form digest and + // migration flag. + const auto http_form_fetcher = base::MakeUnique<MockFormFetcherImpl>( + http_form_digest, &client_, /* should_migrate_http_passwords */ true); + + std::vector<PasswordForm> empty_forms; + const PasswordForm http_form = CreateHTTPNonFederated(); + + // Tests that there is no attempt to migrate credentials on HTTP origins. + // FormFetcherImplTest::Fetch() can't be used here due to different + // expectations. The repeated calls to MockFormFetcherImpl::Fetch() are + // necessary to set the correct state. + EXPECT_CALL(*mock_store_, GetLogins(_, _)); + http_form_fetcher->Fetch(); + EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); + http_form_fetcher->OnGetPasswordStoreResults(make_results(empty_forms)); + + EXPECT_CALL(*mock_store_, GetLogins(_, _)); + http_form_fetcher->Fetch(); + EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0); + http_form_fetcher->OnGetPasswordStoreResults(make_results({http_form})); +} + +// Test that ensures HTTP passwords are only migrated on HTTPS sites when no +// HTTPS credentials are available. +TEST_F(FormFetcherImplTest, TryToMigrateHTTPPasswordsOnHTTPSSites) { + GURL::Replacements https_rep; + https_rep.SetSchemeStr(url::kHttpsScheme); + const GURL https_origin = form_digest_.origin.ReplaceComponents(https_rep); + const PasswordStore::FormDigest https_form_digest( + PasswordForm::SCHEME_HTML, https_origin.GetOrigin().spec(), https_origin); + + // A new form fetcher is created to be able to set the form digest and + // migration flag. + const auto https_form_fetcher = base::MakeUnique<MockFormFetcherImpl>( + https_form_digest, &client_, /* should_migrate_http_passwords */ true); + + std::vector<PasswordForm> empty_forms; + const PasswordForm https_form = CreateNonFederated(); + + // Tests that there is only an attempt to migrate credentials on HTTPS origins + // when no other credentials are available. + // FormFetcherImplTest::Fetch() can't be used here due to different + // expectations. The repeated calls to MockFormFetcherImpl::Fetch() are + // necessary to set the correct state. + EXPECT_CALL(*mock_store_, GetLogins(_, _)); + https_form_fetcher->Fetch(); + EXPECT_CALL(*mock_store_, GetLogins(_, _)) + .WillOnce(testing::WithArg<1>(InvokeMigratorGetResults())); + EXPECT_CALL(*https_form_fetcher, ProcessMigratedFormsDummy()); + https_form_fetcher->OnGetPasswordStoreResults(make_results(empty_forms)); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index 51e3f1e..a8ef741 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -228,10 +228,12 @@ submit_result_(kSubmitResultNotSubmitted), form_type_(kFormTypeUnspecified), form_saver_(std::move(form_saver)), - form_fetcher_impl_( - form_fetcher ? nullptr : base::MakeUnique<FormFetcherImpl>( - PasswordStore::FormDigest(observed_form), - client)), + form_fetcher_impl_(form_fetcher + ? nullptr + : base::MakeUnique<FormFetcherImpl>( + PasswordStore::FormDigest(observed_form), + client, + /* should_migrate_http_passwords */ true)), form_fetcher_(form_fetcher ? form_fetcher : form_fetcher_impl_.get()) { if (form_fetcher_impl_) form_fetcher_impl_->Fetch();
diff --git a/components/payments/payment_request_web_contents_manager.cc b/components/payments/payment_request_web_contents_manager.cc index bb358f9..ca89372 100644 --- a/components/payments/payment_request_web_contents_manager.cc +++ b/components/payments/payment_request_web_contents_manager.cc
@@ -20,7 +20,7 @@ PaymentRequestWebContentsManager::GetOrCreateForWebContents( content::WebContents* web_contents) { DCHECK(web_contents); - // CreateForWebContents does nothing if the delegate instance already exists. + // CreateForWebContents does nothing if the manager instance already exists. PaymentRequestWebContentsManager::CreateForWebContents(web_contents); return PaymentRequestWebContentsManager::FromWebContents(web_contents); }
diff --git a/components/payments/payment_request_web_contents_manager.h b/components/payments/payment_request_web_contents_manager.h index 503107b61..42e26f4 100644 --- a/components/payments/payment_request_web_contents_manager.h +++ b/components/payments/payment_request_web_contents_manager.h
@@ -46,7 +46,7 @@ private: explicit PaymentRequestWebContentsManager(content::WebContents* web_contents); friend class content::WebContentsUserData<PaymentRequestWebContentsManager>; - friend class PaymentRequestWebContentsManagerBrowserTest; + friend class PaymentRequestInteractiveTestBase; // Owns all the PaymentRequest for this WebContents. Since the // PaymentRequestWebContentsManager's lifetime is tied to the WebContents, @@ -58,4 +58,4 @@ } // namespace payments -#endif // COMPONENTS_PAYMENTS_PAYMENT_REQUEST_IMPL_H_ +#endif // COMPONENTS_PAYMENTS_PAYMENT_REQUEST_WEB_CONTENTS_MANAGER_H_
diff --git a/components/proximity_auth/BUILD.gn b/components/proximity_auth/BUILD.gn index a8a1f66..9e19dc5 100644 --- a/components/proximity_auth/BUILD.gn +++ b/components/proximity_auth/BUILD.gn
@@ -6,6 +6,7 @@ static_library("proximity_auth") { sources = [ + "authenticator.cc", "authenticator.h", "bluetooth_connection.cc", "bluetooth_connection.h",
diff --git a/components/proximity_auth/authenticator.cc b/components/proximity_auth/authenticator.cc new file mode 100644 index 0000000..92ca25a --- /dev/null +++ b/components/proximity_auth/authenticator.cc
@@ -0,0 +1,12 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/proximity_auth/authenticator.h" + +namespace proximity_auth { + +// static +const char Authenticator::kAuthenticationFeature[] = "auth"; + +} // namespace proximity_auth
diff --git a/components/proximity_auth/authenticator.h b/components/proximity_auth/authenticator.h index 3882a76..2c56fcc 100644 --- a/components/proximity_auth/authenticator.h +++ b/components/proximity_auth/authenticator.h
@@ -27,6 +27,10 @@ FAILURE, }; + // Feature to be used in |WireMessage|s sent during the authentication + // handshake. + static const char kAuthenticationFeature[]; + virtual ~Authenticator() {} // Initiates the authentication attempt, invoking |callback| with the result.
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_unittest.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection_unittest.cc index 4266d8e..2c529ff 100644 --- a/components/proximity_auth/ble/bluetooth_low_energy_connection_unittest.cc +++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_unittest.cc
@@ -52,6 +52,8 @@ const char kToPeripheralCharID[] = "to peripheral char id"; const char kFromPeripheralCharID[] = "from peripheral char id"; +const char kTestFeature[] = "testFeature"; + const device::BluetoothRemoteGattCharacteristic::Properties kCharacteristicProperties = device::BluetoothRemoteGattCharacteristic::PROPERTY_BROADCAST | @@ -598,19 +600,25 @@ int message_size = 100; std::string message(message_size, 'A'); message[0] = 'B'; - connection->SendMessage( - base::MakeUnique<cryptauth::FakeWireMessage>(message)); + + std::unique_ptr<cryptauth::FakeWireMessage> wire_message = + base::MakeUnique<cryptauth::FakeWireMessage>(message, + std::string(kTestFeature)); + std::string serialized_message = wire_message->Serialize(); + + connection->SendMessage(std::move(wire_message)); // Expecting that |kSendSignal| + |message_size| + |message| was written. EXPECT_EQ(last_value_written_on_to_peripheral_char_, - CreateFirstCharacteristicValue(message, message.size())); + CreateFirstCharacteristicValue(serialized_message, + serialized_message.size())); EXPECT_CALL(*connection, OnDidSendMessage(_, _)); RunWriteCharacteristicSuccessCallback(); } TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, - SendMessage_LagerThanCharacteristicSize) { + SendMessage_LargerThanCharacteristicSize) { std::unique_ptr<MockBluetoothLowEnergyConnection> connection( CreateConnection()); InitializeConnection(connection.get()); @@ -627,15 +635,21 @@ int message_size = 600; std::string message(message_size, 'A'); message[0] = 'B'; - connection->SendMessage( - base::MakeUnique<cryptauth::FakeWireMessage>(message)); - // Expecting that |kSendSignal| + |message_size| was written in the first 8 - // bytes. + std::unique_ptr<cryptauth::FakeWireMessage> wire_message = + base::MakeUnique<cryptauth::FakeWireMessage>(message, + std::string(kTestFeature)); + std::string serialized_message = wire_message->Serialize(); + + // Send the message. + connection->SendMessage(std::move(wire_message)); + + // Expecting that |kSendSignal| + |serialized_message| was written in the + // first 8 bytes. std::vector<uint8_t> prefix( last_value_written_on_to_peripheral_char_.begin(), last_value_written_on_to_peripheral_char_.begin() + 8); - EXPECT_EQ(prefix, CreateSendSignalWithSize(message_size)); + EXPECT_EQ(prefix, CreateSendSignalWithSize(serialized_message.size())); std::vector<uint8_t> bytes_received( last_value_written_on_to_peripheral_char_.begin() + 8, last_value_written_on_to_peripheral_char_.end()); @@ -654,7 +668,8 @@ last_value_written_on_to_peripheral_char_.end()); // Expecting that the message was written. - std::vector<uint8_t> expected_value(message.begin(), message.end()); + std::vector<uint8_t> expected_value(serialized_message.begin(), + serialized_message.end()); EXPECT_EQ(expected_value.size(), bytes_received.size()); EXPECT_EQ(expected_value, bytes_received);
diff --git a/components/proximity_auth/bluetooth_connection_unittest.cc b/components/proximity_auth/bluetooth_connection_unittest.cc index e318c21..dd57691 100644 --- a/components/proximity_auth/bluetooth_connection_unittest.cc +++ b/components/proximity_auth/bluetooth_connection_unittest.cc
@@ -80,7 +80,7 @@ class TestWireMessage : public cryptauth::WireMessage { public: - TestWireMessage() : cryptauth::WireMessage("permit id", "payload") {} + TestWireMessage() : cryptauth::WireMessage("payload", "feature") {} ~TestWireMessage() override {} std::string Serialize() const override { return kSerializedMessage; }
diff --git a/components/proximity_auth/device_to_device_authenticator.cc b/components/proximity_auth/device_to_device_authenticator.cc index cc9ccdf6..751e277f 100644 --- a/components/proximity_auth/device_to_device_authenticator.cc +++ b/components/proximity_auth/device_to_device_authenticator.cc
@@ -12,6 +12,7 @@ #include "components/cryptauth/connection.h" #include "components/cryptauth/secure_message_delegate.h" #include "components/cryptauth/wire_message.h" +#include "components/proximity_auth/authenticator.h" #include "components/proximity_auth/device_to_device_initiator_operations.h" #include "components/proximity_auth/device_to_device_secure_context.h" #include "components/proximity_auth/logging/logging.h" @@ -26,10 +27,6 @@ // authentication will fail. const int kResponderAuthTimeoutSeconds = 5; -// The prefix of the permit id sent to the remote device. The permit id -// is used by the remote device to find the credentials of the local device. -const char kPermitIdPrefix[] = "permit://google.com/easyunlock/v1/"; - } // namespace DeviceToDeviceAuthenticator::DeviceToDeviceAuthenticator( @@ -113,9 +110,8 @@ // Send the [Hello] message to the remote device. state_ = State::SENT_HELLO; hello_message_ = message; - std::string permit_id = kPermitIdPrefix + account_id_; - connection_->SendMessage( - base::MakeUnique<cryptauth::WireMessage>(hello_message_, permit_id)); + connection_->SendMessage(base::MakeUnique<cryptauth::WireMessage>( + hello_message_, std::string(Authenticator::kAuthenticationFeature))); } void DeviceToDeviceAuthenticator::OnResponderAuthTimedOut() { @@ -154,7 +150,8 @@ } state_ = State::SENT_INITIATOR_AUTH; - connection_->SendMessage(base::MakeUnique<cryptauth::WireMessage>(message)); + connection_->SendMessage(base::MakeUnique<cryptauth::WireMessage>( + message, std::string(Authenticator::kAuthenticationFeature))); } void DeviceToDeviceAuthenticator::Fail(const std::string& error_message) { @@ -200,7 +197,8 @@ void DeviceToDeviceAuthenticator::OnMessageReceived( const cryptauth::Connection& connection, const cryptauth::WireMessage& message) { - if (state_ == State::SENT_HELLO) { + if (state_ == State::SENT_HELLO && + message.feature() == std::string(Authenticator::kAuthenticationFeature)) { PA_LOG(INFO) << "Received [Responder Auth] message, payload_size=" << message.payload().size(); state_ = State::RECEIVED_RESPONDER_AUTH;
diff --git a/components/proximity_auth/device_to_device_authenticator_unittest.cc b/components/proximity_auth/device_to_device_authenticator_unittest.cc index 510d266..b66d735 100644 --- a/components/proximity_auth/device_to_device_authenticator_unittest.cc +++ b/components/proximity_auth/device_to_device_authenticator_unittest.cc
@@ -17,6 +17,7 @@ #include "components/cryptauth/cryptauth_test_util.h" #include "components/cryptauth/fake_secure_message_delegate.h" #include "components/cryptauth/wire_message.h" +#include "components/proximity_auth/authenticator.h" #include "components/proximity_auth/device_to_device_responder_operations.h" #include "components/proximity_auth/secure_context.h" #include "testing/gmock/include/gmock/gmock.h" @@ -181,8 +182,6 @@ base::Unretained(this))); EXPECT_EQ(1u, connection_.message_buffer().size()); - EXPECT_EQ(std::string("permit://google.com/easyunlock/v1/") + kAccountId, - connection_.message_buffer()[0]->permit_id()); std::string hello_message = connection_.message_buffer()[0]->payload(); connection_.ClearMessageBuffer(); @@ -214,7 +213,8 @@ base::Bind(&SaveStringResult, &responder_auth_message)); EXPECT_FALSE(responder_auth_message.empty()); - cryptauth::WireMessage wire_message(responder_auth_message); + cryptauth::WireMessage wire_message(responder_auth_message, + Authenticator::kAuthenticationFeature); connection_.OnBytesReceived(wire_message.Serialize()); return responder_auth_message; @@ -281,7 +281,8 @@ // If the responder could not validate the [Hello message], it essentially // sends random bytes back for privacy reasons. - cryptauth::WireMessage wire_message(base::RandBytesAsString(300u)); + cryptauth::WireMessage wire_message(base::RandBytesAsString(300u), + Authenticator::kAuthenticationFeature); EXPECT_CALL(*this, OnAuthenticationResultProxy(Authenticator::Result::FAILURE)); connection_.OnBytesReceived(wire_message.Serialize()); @@ -346,12 +347,13 @@ // Test that the authenticator is properly cleaned up after authentication // completes. - cryptauth::WireMessage wire_message(base::RandBytesAsString(300u)); - connection_.SendMessage( - base::MakeUnique<cryptauth::WireMessage>(base::RandBytesAsString(300u))); + cryptauth::WireMessage wire_message(base::RandBytesAsString(300u), + Authenticator::kAuthenticationFeature); + connection_.SendMessage(base::MakeUnique<cryptauth::WireMessage>( + base::RandBytesAsString(300u), Authenticator::kAuthenticationFeature)); connection_.OnBytesReceived(wire_message.Serialize()); - connection_.SendMessage( - base::MakeUnique<cryptauth::WireMessage>(base::RandBytesAsString(300u))); + connection_.SendMessage(base::MakeUnique<cryptauth::WireMessage>( + base::RandBytesAsString(300u), Authenticator::kAuthenticationFeature)); connection_.OnBytesReceived(wire_message.Serialize()); }
diff --git a/components/proximity_auth/messenger_impl.cc b/components/proximity_auth/messenger_impl.cc index 200539e9..1a512b6 100644 --- a/components/proximity_auth/messenger_impl.cc +++ b/components/proximity_auth/messenger_impl.cc
@@ -50,6 +50,8 @@ const char kScreenLocked[] = "Screen Locked"; const int kIOSPollingIntervalSeconds = 5; +const char kEasyUnlockFeatureName[] = "easy_unlock"; + // Serializes the |value| to a JSON string and returns the result. std::string SerializeValueToJson(const base::Value& value) { std::string json; @@ -179,8 +181,8 @@ } void MessengerImpl::OnMessageEncoded(const std::string& encoded_message) { - connection_->SendMessage( - base::MakeUnique<cryptauth::WireMessage>(encoded_message)); + connection_->SendMessage(base::MakeUnique<cryptauth::WireMessage>( + encoded_message, std::string(kEasyUnlockFeatureName))); } void MessengerImpl::OnMessageDecoded(const std::string& decoded_message) {
diff --git a/components/proximity_auth/messenger_impl_unittest.cc b/components/proximity_auth/messenger_impl_unittest.cc index 2a66e8f..5ff61dc1 100644 --- a/components/proximity_auth/messenger_impl_unittest.cc +++ b/components/proximity_auth/messenger_impl_unittest.cc
@@ -112,13 +112,13 @@ cryptauth::WireMessage* message = messenger.GetFakeConnection()->current_message(); ASSERT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); EXPECT_EQ( "{" "\"name\":\"easy_unlock\"," "\"type\":\"event\"" "}, but encoded", message->payload()); + EXPECT_EQ("easy_unlock", message->feature()); } TEST(ProximityAuthMessengerImplTest, DispatchUnlockEvent_SendMessageFails) { @@ -155,7 +155,6 @@ cryptauth::WireMessage* message = messenger.GetFakeConnection()->current_message(); ASSERT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); EXPECT_EQ( "{" "\"encrypted_data\":\"YSBtb3N0IGRpZmZpY3VsdCBjaGFsbGVuZ2U=\"," @@ -172,7 +171,6 @@ cryptauth::WireMessage* message = messenger.GetFakeConnection()->current_message(); ASSERT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); EXPECT_EQ( "{" "\"encrypted_data\":\"_-Y=\"," @@ -274,7 +272,6 @@ cryptauth::WireMessage* message = messenger.GetFakeConnection()->current_message(); ASSERT_TRUE(message); - EXPECT_EQ(std::string(), message->permit_id()); EXPECT_EQ("{\"type\":\"unlock_request\"}, but encoded", message->payload()); }
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index f05878b0..2a552cd 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -760,6 +760,8 @@ "model/mock_model_type_store.h", "model/model_type_store_test_util.cc", "model/model_type_store_test_util.h", + "model/recording_model_type_change_processor.cc", + "model/recording_model_type_change_processor.h", "model/stub_model_type_sync_bridge.cc", "model/stub_model_type_sync_bridge.h", "model/sync_change_processor_wrapper_for_test.cc",
diff --git a/components/sync/device_info/device_info_sync_bridge_unittest.cc b/components/sync/device_info/device_info_sync_bridge_unittest.cc index 6f996f4..bac12413 100644 --- a/components/sync/device_info/device_info_sync_bridge_unittest.cc +++ b/components/sync/device_info/device_info_sync_bridge_unittest.cc
@@ -21,6 +21,7 @@ #include "components/sync/model/fake_model_type_change_processor.h" #include "components/sync/model/metadata_batch.h" #include "components/sync/model/model_type_store_test_util.h" +#include "components/sync/model/recording_model_type_change_processor.h" #include "components/sync/protocol/model_type_state.pb.h" #include "testing/gtest/include/gtest/gtest.h" @@ -170,43 +171,6 @@ return map; } -// Instead of actually processing anything, simply accumulates all instructions -// in members that can then be accessed. TODO(skym): If this ends up being -// useful for other model type unittests it should be moved out to a shared -// location. -class RecordingModelTypeChangeProcessor : public FakeModelTypeChangeProcessor { - public: - RecordingModelTypeChangeProcessor() {} - ~RecordingModelTypeChangeProcessor() override {} - - void Put(const std::string& storage_key, - std::unique_ptr<EntityData> entity_data, - MetadataChangeList* metadata_changes) override { - put_multimap_.insert(std::make_pair(storage_key, std::move(entity_data))); - } - - void Delete(const std::string& storage_key, - MetadataChangeList* metadata_changes) override { - delete_set_.insert(storage_key); - } - - void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override { - std::swap(metadata_, batch); - } - - const std::multimap<std::string, std::unique_ptr<EntityData>>& put_multimap() - const { - return put_multimap_; - } - const std::set<std::string>& delete_set() const { return delete_set_; } - const MetadataBatch* metadata() const { return metadata_.get(); } - - private: - std::multimap<std::string, std::unique_ptr<EntityData>> put_multimap_; - std::set<std::string> delete_set_; - std::unique_ptr<MetadataBatch> metadata_; -}; - } // namespace class DeviceInfoSyncBridgeTest : public testing::Test,
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h index aef685cd..29d2e22e 100644 --- a/components/sync/driver/data_type_controller.h +++ b/components/sync/driver/data_type_controller.h
@@ -91,6 +91,12 @@ // return false while USS datatypes should return true. virtual bool ShouldLoadModelBeforeConfigure() const = 0; + // Called right before LoadModels. This method allows controller to register + // the type with sync engine. Directory datatypes download initial data in + // parallel with LoadModels and thus should be ready to receive updates with + // initial data before LoadModels finishes. + virtual void BeforeLoadModels(ModelTypeConfigurer* configurer) = 0; + // Begins asynchronous operation of loading the model to get it ready for // model association. Once the models are loaded the callback will be invoked // with the result. If the models are already loaded it is safe to call the
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc index 071d4c42..afb73b0 100644 --- a/components/sync/driver/data_type_manager_impl.cc +++ b/components/sync/driver/data_type_manager_impl.cc
@@ -642,6 +642,12 @@ model_association_manager_.StartAssociationAsync(types_to_associate); } +void DataTypeManagerImpl::OnSingleDataTypeWillStart(ModelType type) { + DCHECK(controllers_->find(type) != controllers_->end()); + DataTypeController* dtc = controllers_->find(type)->second.get(); + dtc->BeforeLoadModels(configurer_); +} + void DataTypeManagerImpl::OnSingleDataTypeWillStop(ModelType type, const SyncError& error) { DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type);
diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h index 2f64a457..cf28cdf 100644 --- a/components/sync/driver/data_type_manager_impl.h +++ b/components/sync/driver/data_type_manager_impl.h
@@ -59,6 +59,7 @@ State state() const override; // |ModelAssociationManagerDelegate| implementation. + void OnSingleDataTypeWillStart(ModelType type) override; void OnAllDataTypesReadyForConfigure() override; void OnSingleDataTypeAssociationDone( ModelType type,
diff --git a/components/sync/driver/data_type_manager_impl_unittest.cc b/components/sync/driver/data_type_manager_impl_unittest.cc index af1bf7e..52ecd58 100644 --- a/components/sync/driver/data_type_manager_impl_unittest.cc +++ b/components/sync/driver/data_type_manager_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "components/sync/driver/data_type_manager_impl.h" #include <memory> +#include <utility> #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" @@ -80,6 +81,15 @@ last_params_ = std::move(params); } + void RegisterDirectoryDataType(ModelType type, + ModelSafeGroup group) override { + registered_directory_types_.Put(type); + } + + void UnregisterDirectoryDataType(ModelType type) override { + registered_directory_types_.Remove(type); + } + void ActivateDirectoryDataType(ModelType type, ModelSafeGroup group, ChangeProcessor* change_processor) override { @@ -100,6 +110,10 @@ // TODO(stanisc): crbug.com/515962: Add test coverage. } + const ModelTypeSet registered_directory_types() { + return registered_directory_types_; + } + const ModelTypeSet activated_types() { return activated_types_; } int configure_call_count() const { return configure_call_count_; } @@ -107,6 +121,7 @@ const ConfigureParams& last_params() const { return last_params_; } private: + ModelTypeSet registered_directory_types_; ModelTypeSet activated_types_; int configure_call_count_ = 0; ConfigureParams last_params_; @@ -342,6 +357,7 @@ Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); FinishDownload(ModelTypeSet(), ModelTypeSet()); FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); @@ -354,6 +370,7 @@ dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with a single controller, configure it, but stop it @@ -369,9 +386,12 @@ Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), + configurer_.registered_directory_types()); dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } last_configure_params().ready_task.Run(ModelTypeSet(BOOKMARKS), @@ -393,13 +413,15 @@ Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - + EXPECT_EQ(ModelTypeSet(BOOKMARKS), + configurer_.registered_directory_types()); FinishDownload(ModelTypeSet(), ModelTypeSet()); FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); dtm_.reset(); } @@ -422,6 +444,8 @@ Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), + configurer_.registered_directory_types()); FinishDownload(ModelTypeSet(), ModelTypeSet()); FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); @@ -430,6 +454,7 @@ dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); dtm_.reset(); } @@ -497,6 +522,7 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 2. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -514,6 +540,8 @@ // Step 4. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 5. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -529,6 +557,7 @@ dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -550,6 +579,7 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 2. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -567,6 +597,8 @@ // Step 4. Configure(ModelTypeSet(PREFERENCES)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(PREFERENCES), + configurer_.registered_directory_types()); // Step 5. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -582,6 +614,7 @@ dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -603,6 +636,7 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 2. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -626,11 +660,14 @@ GetController(PREFERENCES)->FinishStart(DataTypeController::OK); EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); EXPECT_EQ(2U, configurer_.activated_types().Size()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 7. dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with one controller. Then configure, finish @@ -647,6 +684,7 @@ Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); FinishDownload(ModelTypeSet(), ModelTypeSet()); FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); @@ -657,6 +695,7 @@ DataTypeController::UNRECOVERABLE_ERROR); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -680,6 +719,8 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 2. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -694,6 +735,7 @@ GetController(PREFERENCES) ->FinishStart(DataTypeController::UNRECOVERABLE_ERROR); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -722,6 +764,8 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 2. FinishDownload(ModelTypeSet(), ModelTypeSet()); @@ -742,11 +786,13 @@ FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); EXPECT_EQ(1U, configurer_.activated_types().Size()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 6. dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); EXPECT_TRUE(configurer_.activated_types().Empty()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -767,6 +813,7 @@ // Step 1. Configure(ModelTypeSet(BOOKMARKS)); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 2. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES)); @@ -786,10 +833,13 @@ EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); GetController(PREFERENCES)->FinishStart(DataTypeController::OK); EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 6. dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Set up a DTM with two controllers. Then: @@ -814,6 +864,7 @@ Configure(ModelTypeSet(BOOKMARKS)); FinishDownload(ModelTypeSet(), ModelTypeSet()); EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.registered_directory_types()); // Step 2. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES)); @@ -833,10 +884,13 @@ EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); GetController(PREFERENCES)->FinishStart(DataTypeController::OK); EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), + configurer_.registered_directory_types()); // Step 6. dtm_->Stop(); EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.registered_directory_types().Empty()); } // Tests a Purge then Configure. This is similar to the sequence of
diff --git a/components/sync/driver/directory_data_type_controller.cc b/components/sync/driver/directory_data_type_controller.cc index 86fdd73..933a328 100644 --- a/components/sync/driver/directory_data_type_controller.cc +++ b/components/sync/driver/directory_data_type_controller.cc
@@ -34,6 +34,31 @@ return false; } +void DirectoryDataTypeController::BeforeLoadModels( + ModelTypeConfigurer* configurer) { + configurer->RegisterDirectoryDataType(type(), model_safe_group_); +} + +void DirectoryDataTypeController::RegisterWithBackend( + base::Callback<void(bool)> set_downloaded, + ModelTypeConfigurer* configurer) {} + +void DirectoryDataTypeController::ActivateDataType( + ModelTypeConfigurer* configurer) { + DCHECK(CalledOnValidThread()); + // Tell the backend about the change processor for this type so it can + // begin routing changes to it. + configurer->ActivateDirectoryDataType(type(), model_safe_group_, + GetChangeProcessor()); +} + +void DirectoryDataTypeController::DeactivateDataType( + ModelTypeConfigurer* configurer) { + DCHECK(CalledOnValidThread()); + configurer->DeactivateDirectoryDataType(type()); + configurer->UnregisterDirectoryDataType(type()); +} + void DirectoryDataTypeController::GetAllNodes( const AllNodesCallback& callback) { std::unique_ptr<base::ListValue> node_list = GetAllNodesForTypeFromDirectory( @@ -57,25 +82,6 @@ callback.Run(type(), counters); } -void DirectoryDataTypeController::RegisterWithBackend( - base::Callback<void(bool)> set_downloaded, - ModelTypeConfigurer* configurer) {} - -void DirectoryDataTypeController::ActivateDataType( - ModelTypeConfigurer* configurer) { - DCHECK(CalledOnValidThread()); - // Tell the backend about the change processor for this type so it can - // begin routing changes to it. - configurer->ActivateDirectoryDataType(type(), model_safe_group_, - GetChangeProcessor()); -} - -void DirectoryDataTypeController::DeactivateDataType( - ModelTypeConfigurer* configurer) { - DCHECK(CalledOnValidThread()); - configurer->DeactivateDirectoryDataType(type()); -} - // static std::unique_ptr<base::ListValue> DirectoryDataTypeController::GetAllNodesForTypeFromDirectory(
diff --git a/components/sync/driver/directory_data_type_controller.h b/components/sync/driver/directory_data_type_controller.h index b4b2777..d05bddc5 100644 --- a/components/sync/driver/directory_data_type_controller.h +++ b/components/sync/driver/directory_data_type_controller.h
@@ -23,12 +23,13 @@ // DataTypeController implementation. bool ShouldLoadModelBeforeConfigure() const override; - void GetAllNodes(const AllNodesCallback& callback) override; - void GetStatusCounters(const StatusCountersCallback& callback) override; - // Directory based data types don't need to register with backend. - // ModelTypeRegistry will create all necessary objects in - // SetEnabledDirectoryTypes based on routing info. + // Directory types need to register with sync engine before LoadModels because + // downloading initial data happens in parallel with LoadModels. + void BeforeLoadModels(ModelTypeConfigurer* configurer) override; + + // Directory based data types register with backend before LoadModels in + // BeforeLoadModels. No need to do anything in RegisterWithBackend. void RegisterWithBackend(base::Callback<void(bool)> set_downloaded, ModelTypeConfigurer* configurer) override; @@ -46,6 +47,9 @@ // See ModelTypeConfigurer::DeactivateDataType for more details. void DeactivateDataType(ModelTypeConfigurer* configurer) override; + void GetAllNodes(const AllNodesCallback& callback) override; + void GetStatusCounters(const StatusCountersCallback& callback) override; + // Returns a ListValue representing all nodes for a specified type by querying // the directory. static std::unique_ptr<base::ListValue> GetAllNodesForTypeFromDirectory(
diff --git a/components/sync/driver/glue/sync_backend_host_core.cc b/components/sync/driver/glue/sync_backend_host_core.cc index b934544..0751ba2 100644 --- a/components/sync/driver/glue/sync_backend_host_core.cc +++ b/components/sync/driver/glue/sync_backend_host_core.cc
@@ -141,6 +141,16 @@ ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(ControlTypes(), ModelTypeSet()); + + // Control types don't have DataTypeControllers, but they need to have + // update handlers registered in ModelTypeRegistry. Register them here. + ModelTypeConnector* model_type_connector = + sync_manager_->GetModelTypeConnector(); + ModelTypeSet control_types = ControlTypes(); + for (auto it = control_types.First(); it.Good(); it.Inc()) { + model_type_connector->RegisterDirectoryType(it.Get(), GROUP_PASSIVE); + } + ModelSafeRoutingInfo routing_info; registrar_->GetModelSafeRoutingInfo(&routing_info); SDVLOG(1) << "Control Types " << ModelTypeSetToString(new_control_types) @@ -152,7 +162,7 @@ sync_manager_->PurgeDisabledTypes(types_to_purge, ModelTypeSet(), ModelTypeSet()); sync_manager_->ConfigureSyncer( - reason, new_control_types, routing_info, + reason, new_control_types, base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes, weak_ptr_factory_.GetWeakPtr()), base::Closure()); @@ -389,11 +399,13 @@ } } -void SyncBackendHostCore::DoStartSyncing( - const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) { +void SyncBackendHostCore::DoStartConfiguration() { + sync_manager_->StartConfiguration(); +} + +void SyncBackendHostCore::DoStartSyncing(base::Time last_poll_time) { DCHECK(thread_checker_.CalledOnValidThread()); - sync_manager_->StartSyncingNormally(routing_info, last_poll_time); + sync_manager_->StartSyncingNormally(last_poll_time); } void SyncBackendHostCore::DoSetEncryptionPassphrase( @@ -515,9 +527,6 @@ registrar_->ConfigureDataTypes(params.enabled_types, params.disabled_types); - ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - base::Closure chained_ready_task(base::Bind( &SyncBackendHostCore::DoFinishConfigureDataTypes, weak_ptr_factory_.GetWeakPtr(), params.to_download, params.ready_task)); @@ -526,8 +535,7 @@ weak_ptr_factory_.GetWeakPtr(), params.retry_callback)); sync_manager_->ConfigureSyncer(params.reason, params.to_download, - routing_info, chained_ready_task, - chained_retry_task); + chained_ready_task, chained_retry_task); } void SyncBackendHostCore::DoFinishConfigureDataTypes(
diff --git a/components/sync/driver/glue/sync_backend_host_core.h b/components/sync/driver/glue/sync_backend_host_core.h index 787a1eb..c46814b 100644 --- a/components/sync/driver/glue/sync_backend_host_core.h +++ b/components/sync/driver/glue/sync_backend_host_core.h
@@ -106,10 +106,14 @@ // SyncEngine::UpdateCredentials. void DoUpdateCredentials(const SyncCredentials& credentials); + // Switches sync engine into configuration mode. In this mode only initial + // data for newly enabled types is downloaded from server. No local changes + // are committed to server. + void DoStartConfiguration(); + // Called to tell the syncapi to start syncing (generally after // initialization and authentication). - void DoStartSyncing(const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time); + void DoStartSyncing(base::Time last_poll_time); // Called to set the passphrase for encryption. void DoSetEncryptionPassphrase(const std::string& passphrase,
diff --git a/components/sync/driver/glue/sync_backend_host_impl.cc b/components/sync/driver/glue/sync_backend_host_impl.cc index ff1a70e..0106db4c 100644 --- a/components/sync/driver/glue/sync_backend_host_impl.cc +++ b/components/sync/driver/glue/sync_backend_host_impl.cc
@@ -90,15 +90,17 @@ credentials)); } +void SyncBackendHostImpl::StartConfiguration() { + sync_task_runner_->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoStartConfiguration, core_)); +} + void SyncBackendHostImpl::StartSyncingWithServer() { SDVLOG(1) << "SyncBackendHostImpl::StartSyncingWithServer called."; - ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - sync_task_runner_->PostTask( FROM_HERE, base::Bind(&SyncBackendHostCore::DoStartSyncing, core_, - routing_info, sync_prefs_->GetLastPollTime())); + sync_prefs_->GetLastPollTime())); } void SyncBackendHostImpl::SetEncryptionPassphrase(const std::string& passphrase, @@ -211,6 +213,15 @@ base::Passed(¶ms))); } +void SyncBackendHostImpl::RegisterDirectoryDataType(ModelType type, + ModelSafeGroup group) { + model_type_connector_->RegisterDirectoryType(type, group); +} + +void SyncBackendHostImpl::UnregisterDirectoryDataType(ModelType type) { + model_type_connector_->UnregisterDirectoryType(type); +} + void SyncBackendHostImpl::EnableEncryptEverything() { sync_task_runner_->PostTask( FROM_HERE, @@ -234,11 +245,12 @@ registrar_->RegisterNonBlockingType(type); if (activation_context->model_type_state.initial_sync_done()) registrar_->AddRestoredNonBlockingType(type); - model_type_connector_->ConnectType(type, std::move(activation_context)); + model_type_connector_->ConnectNonBlockingType(type, + std::move(activation_context)); } void SyncBackendHostImpl::DeactivateNonBlockingDataType(ModelType type) { - model_type_connector_->DisconnectType(type); + model_type_connector_->DisconnectNonBlockingType(type); } UserShare* SyncBackendHostImpl::GetUserShare() const {
diff --git a/components/sync/driver/glue/sync_backend_host_impl.h b/components/sync/driver/glue/sync_backend_host_impl.h index 4d06288..e7f93eb 100644 --- a/components/sync/driver/glue/sync_backend_host_impl.h +++ b/components/sync/driver/glue/sync_backend_host_impl.h
@@ -60,6 +60,7 @@ void Initialize(InitParams params) override; void TriggerRefresh(const ModelTypeSet& types) override; void UpdateCredentials(const SyncCredentials& credentials) override; + void StartConfiguration() override; void StartSyncingWithServer() override; void SetEncryptionPassphrase(const std::string& passphrase, bool is_explicit) override; @@ -68,6 +69,8 @@ void StopSyncingForShutdown() override; void Shutdown(ShutdownReason reason) override; void ConfigureDataTypes(ConfigureParams params) override; + void RegisterDirectoryDataType(ModelType type, ModelSafeGroup group) override; + void UnregisterDirectoryDataType(ModelType type) override; void ActivateDirectoryDataType(ModelType type, ModelSafeGroup group, ChangeProcessor* change_processor) override;
diff --git a/components/sync/driver/glue/sync_backend_host_impl_unittest.cc b/components/sync/driver/glue/sync_backend_host_impl_unittest.cc index 21d8d42..a96b4b2 100644 --- a/components/sync/driver/glue/sync_backend_host_impl_unittest.cc +++ b/components/sync/driver/glue/sync_backend_host_impl_unittest.cc
@@ -323,7 +323,6 @@ EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( Difference(enabled_types_, ControlTypes()))); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -353,7 +352,6 @@ Intersection(fake_manager_->GetAndResetPurgedTypes(), enabled_types_) .Empty()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -389,7 +387,6 @@ .Empty()); EXPECT_EQ(partial_types, fake_manager_->GetAndResetDownloadedTypes()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -424,7 +421,6 @@ Intersection(fake_manager_->GetAndResetPurgedTypes(), enabled_types_) .Empty()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -459,7 +455,6 @@ EXPECT_EQ(disabled_types, Intersection(fake_manager_->GetAndResetPurgedTypes(), old_types)); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -495,7 +490,6 @@ Intersection(fake_manager_->GetAndResetPurgedTypes(), enabled_types_) .Empty()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -534,7 +528,6 @@ EXPECT_EQ(disabled_types, Intersection(fake_manager_->GetAndResetPurgedTypes(), old_types)); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_EQ(disabled_types, fake_manager_->GetTypesWithEmptyProgressMarkerToken(old_types)); } @@ -570,7 +563,6 @@ Intersection(fake_manager_->GetAndResetPurgedTypes(), enabled_types_) .Empty()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty()); @@ -612,7 +604,6 @@ Intersection(fake_manager_->GetAndResetPurgedTypes(), enabled_types_) .Empty()); EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); EXPECT_TRUE( fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) .Empty());
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc index 382c4f1..e8dae8a 100644 --- a/components/sync/driver/model_association_manager.cc +++ b/components/sync/driver/model_association_manager.cc
@@ -169,6 +169,7 @@ if (dtc->state() == DataTypeController::NOT_RUNNING) { DCHECK(!loaded_types_.Has(dtc->type())); DCHECK(!associated_types_.Has(dtc->type())); + delegate_->OnSingleDataTypeWillStart(dtc->type()); dtc->LoadModels(base::Bind(&ModelAssociationManager::ModelLoadCallback, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/components/sync/driver/model_association_manager.h b/components/sync/driver/model_association_manager.h index 2f8bd9d..c083d47 100644 --- a/components/sync/driver/model_association_manager.h +++ b/components/sync/driver/model_association_manager.h
@@ -28,6 +28,10 @@ // those operations are passed back via this interface. class ModelAssociationManagerDelegate { public: + // Called right before ModelAssociationManager calls LoadModels. Allows + // directory types to register with sync engine before download starts. + virtual void OnSingleDataTypeWillStart(ModelType type) = 0; + // Called when all desired types are ready to be configured with // ModelTypeConfigurer. Data type is ready when its progress marker is // available to configurer. Directory data types are always ready, their
diff --git a/components/sync/driver/model_association_manager_unittest.cc b/components/sync/driver/model_association_manager_unittest.cc index ebb576b5..251bb637 100644 --- a/components/sync/driver/model_association_manager_unittest.cc +++ b/components/sync/driver/model_association_manager_unittest.cc
@@ -25,6 +25,7 @@ MOCK_METHOD2(OnSingleDataTypeAssociationDone, void(ModelType type, const DataTypeAssociationStats& association_stats)); + MOCK_METHOD1(OnSingleDataTypeWillStart, void(ModelType type)); MOCK_METHOD2(OnSingleDataTypeWillStop, void(ModelType, const SyncError& error)); MOCK_METHOD1(OnModelAssociationDone, @@ -64,6 +65,8 @@ ModelAssociationManager model_association_manager(&controllers_, &delegate_); ModelTypeSet types(BOOKMARKS, APPS); DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result)); @@ -99,9 +102,9 @@ ModelTypeSet types; types.Put(BOOKMARKS); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); DataTypeManager::ConfigureResult expected_result(DataTypeManager::ABORTED, types); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result)); EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(BOOKMARKS, _)); @@ -122,6 +125,7 @@ ModelAssociationManager model_association_manager(&controllers_, &delegate_); ModelTypeSet types; types.Put(BOOKMARKS); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result)); @@ -145,6 +149,7 @@ ModelAssociationManager model_association_manager(&controllers_, &delegate_); ModelTypeSet types; types.Put(BOOKMARKS); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(BOOKMARKS, _)); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) @@ -167,6 +172,7 @@ ModelAssociationManager model_association_manager(&controllers_, &delegate_); ModelTypeSet types; types.Put(BOOKMARKS); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); DataTypeManager::ConfigureResult expected_result( DataTypeManager::UNRECOVERABLE_ERROR, types); EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(BOOKMARKS, _)); @@ -195,6 +201,8 @@ DataTypeManager::ConfigureResult expected_result_partially_done( DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result_partially_done)); @@ -262,6 +270,7 @@ ModelTypeSet types; types.Put(BOOKMARKS); DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(BOOKMARKS, _)); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result)); @@ -281,6 +290,7 @@ ModelTypeSet types; types.Put(BOOKMARKS); DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result)); @@ -315,6 +325,8 @@ DataTypeManager::ConfigureResult expected_result_partially_done( DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnModelAssociationDone(_)) .WillOnce(VerifyResult(expected_result_partially_done)); @@ -350,6 +362,8 @@ DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not // loaded yet. + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); model_association_manager.Initialize(types); @@ -395,6 +409,7 @@ DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not // loaded yet. + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); model_association_manager.Initialize(types); @@ -436,6 +451,8 @@ // Apps will finish loading but bookmarks won't. // OnAllDataTypesReadyForConfigure shouldn't be called. + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(BOOKMARKS)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStart(APPS)); EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); model_association_manager.Initialize(types);
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index b0d28cf0..c85cf6c 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -127,18 +127,7 @@ std::move(error_handler), std::move(callback))); } -void ModelTypeController::GetAllNodes(const AllNodesCallback& callback) { - model_thread_->PostTask( - FROM_HERE, base::Bind(&CallGetAllNodesHelper, sync_client_, type(), - BindToCurrentThread(callback))); -} - -void ModelTypeController::GetStatusCounters( - const StatusCountersCallback& callback) { - model_thread_->PostTask( - FROM_HERE, - base::Bind(&CallGetStatusCountersHelper, sync_client_, type(), callback)); -} +void ModelTypeController::BeforeLoadModels(ModelTypeConfigurer* configurer) {} void ModelTypeController::LoadModelsDone(ConfigureResult result, const SyncError& error) { @@ -253,6 +242,19 @@ return state_; } +void ModelTypeController::GetAllNodes(const AllNodesCallback& callback) { + model_thread_->PostTask( + FROM_HERE, base::Bind(&CallGetAllNodesHelper, sync_client_, type(), + BindToCurrentThread(callback))); +} + +void ModelTypeController::GetStatusCounters( + const StatusCountersCallback& callback) { + model_thread_->PostTask( + FROM_HERE, + base::Bind(&CallGetStatusCountersHelper, sync_client_, type(), callback)); +} + void ModelTypeController::ReportModelError(const ModelError& error) { DCHECK(CalledOnValidThread()); LoadModelsDone(UNRECOVERABLE_ERROR,
diff --git a/components/sync/driver/model_type_controller.h b/components/sync/driver/model_type_controller.h index 92152d7..9092526 100644 --- a/components/sync/driver/model_type_controller.h +++ b/components/sync/driver/model_type_controller.h
@@ -35,9 +35,8 @@ // DataTypeController implementation. bool ShouldLoadModelBeforeConfigure() const override; + void BeforeLoadModels(ModelTypeConfigurer* configurer) override; void LoadModels(const ModelLoadCallback& model_load_callback) override; - void GetAllNodes(const AllNodesCallback& callback) override; - void GetStatusCounters(const StatusCountersCallback& callback) override; void RegisterWithBackend(base::Callback<void(bool)> set_downloaded, ModelTypeConfigurer* configurer) override; void StartAssociating(const StartCallback& start_callback) override; @@ -46,6 +45,8 @@ void Stop() override; std::string name() const override; State state() const override; + void GetAllNodes(const AllNodesCallback& callback) override; + void GetStatusCounters(const StatusCountersCallback& callback) override; private: void RecordStartFailure(ConfigureResult result) const;
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index bf7ef71..1de8370 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -92,6 +92,15 @@ NOTREACHED() << "Not implemented."; } + void RegisterDirectoryDataType(ModelType type, + ModelSafeGroup group) override { + NOTREACHED() << "Not implemented."; + } + + void UnregisterDirectoryDataType(ModelType type) override { + NOTREACHED() << "Not implemented."; + } + void ActivateDirectoryDataType(ModelType type, ModelSafeGroup group, ChangeProcessor* change_processor) override {
diff --git a/components/sync/driver/proxy_data_type_controller.cc b/components/sync/driver/proxy_data_type_controller.cc index 16e291e0..0c1beb6cd 100644 --- a/components/sync/driver/proxy_data_type_controller.cc +++ b/components/sync/driver/proxy_data_type_controller.cc
@@ -21,6 +21,9 @@ return false; } +void ProxyDataTypeController::BeforeLoadModels( + ModelTypeConfigurer* configurer) {} + void ProxyDataTypeController::LoadModels( const ModelLoadCallback& model_load_callback) { DCHECK(CalledOnValidThread());
diff --git a/components/sync/driver/proxy_data_type_controller.h b/components/sync/driver/proxy_data_type_controller.h index 635e656..2036f2a 100644 --- a/components/sync/driver/proxy_data_type_controller.h +++ b/components/sync/driver/proxy_data_type_controller.h
@@ -23,6 +23,7 @@ // DataTypeController interface. bool ShouldLoadModelBeforeConfigure() const override; + void BeforeLoadModels(ModelTypeConfigurer* configurer) override; void LoadModels(const ModelLoadCallback& model_load_callback) override; void RegisterWithBackend(base::Callback<void(bool)> set_downloaded, ModelTypeConfigurer* configurer) override;
diff --git a/components/sync/engine/fake_model_type_connector.cc b/components/sync/engine/fake_model_type_connector.cc index 59b80266..5142c12 100644 --- a/components/sync/engine/fake_model_type_connector.cc +++ b/components/sync/engine/fake_model_type_connector.cc
@@ -12,10 +12,15 @@ FakeModelTypeConnector::~FakeModelTypeConnector() {} -void FakeModelTypeConnector::ConnectType( +void FakeModelTypeConnector::ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) {} -void FakeModelTypeConnector::DisconnectType(ModelType type) {} +void FakeModelTypeConnector::DisconnectNonBlockingType(ModelType type) {} + +void FakeModelTypeConnector::RegisterDirectoryType(ModelType type, + ModelSafeGroup group) {} + +void FakeModelTypeConnector::UnregisterDirectoryType(ModelType type) {} } // namespace syncer
diff --git a/components/sync/engine/fake_model_type_connector.h b/components/sync/engine/fake_model_type_connector.h index 7c47378..978e24aa 100644 --- a/components/sync/engine/fake_model_type_connector.h +++ b/components/sync/engine/fake_model_type_connector.h
@@ -17,10 +17,12 @@ FakeModelTypeConnector(); ~FakeModelTypeConnector() override; - void ConnectType( + void ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) override; - void DisconnectType(ModelType type) override; + void DisconnectNonBlockingType(ModelType type) override; + void RegisterDirectoryType(ModelType type, ModelSafeGroup group) override; + void UnregisterDirectoryType(ModelType type) override; }; } // namespace syncer
diff --git a/components/sync/engine/fake_sync_engine.cc b/components/sync/engine/fake_sync_engine.cc index e40e673..8b35a10e 100644 --- a/components/sync/engine/fake_sync_engine.cc +++ b/components/sync/engine/fake_sync_engine.cc
@@ -24,6 +24,8 @@ void FakeSyncEngine::UpdateCredentials(const SyncCredentials& credentials) {} +void FakeSyncEngine::StartConfiguration() {} + void FakeSyncEngine::StartSyncingWithServer() {} void FakeSyncEngine::SetEncryptionPassphrase(const std::string& passphrase, @@ -39,6 +41,11 @@ void FakeSyncEngine::ConfigureDataTypes(ConfigureParams params) {} +void FakeSyncEngine::RegisterDirectoryDataType(ModelType type, + ModelSafeGroup group) {} + +void FakeSyncEngine::UnregisterDirectoryDataType(ModelType type) {} + void FakeSyncEngine::EnableEncryptEverything() {} void FakeSyncEngine::ActivateDirectoryDataType(
diff --git a/components/sync/engine/fake_sync_engine.h b/components/sync/engine/fake_sync_engine.h index 70f3627..b71bec9 100644 --- a/components/sync/engine/fake_sync_engine.h +++ b/components/sync/engine/fake_sync_engine.h
@@ -32,6 +32,8 @@ void UpdateCredentials(const SyncCredentials& credentials) override; + void StartConfiguration() override; + void StartSyncingWithServer() override; void SetEncryptionPassphrase(const std::string& passphrase, @@ -45,6 +47,10 @@ void ConfigureDataTypes(ConfigureParams params) override; + void RegisterDirectoryDataType(ModelType type, ModelSafeGroup group) override; + + void UnregisterDirectoryDataType(ModelType type) override; + void EnableEncryptEverything() override; void ActivateDirectoryDataType(ModelType type,
diff --git a/components/sync/engine/fake_sync_manager.cc b/components/sync/engine/fake_sync_manager.cc index b97e933..e9f9ce8 100644 --- a/components/sync/engine/fake_sync_manager.cc +++ b/components/sync/engine/fake_sync_manager.cc
@@ -17,10 +17,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "components/sync/base/weak_handle.h" #include "components/sync/engine/engine_components_factory.h" -#include "components/sync/engine/fake_model_type_connector.h" #include "components/sync/engine/net/http_post_provider_factory.h" #include "components/sync/syncable/directory.h" -#include "components/sync/test/fake_sync_encryption_handler.h" class GURL; @@ -33,9 +31,7 @@ progress_marker_types_(progress_marker_types), configure_fail_types_(configure_fail_types), last_configure_reason_(CONFIGURE_REASON_UNKNOWN), - num_invalidations_received_(0) { - fake_encryption_handler_ = base::MakeUnique<FakeSyncEncryptionHandler>(); -} + num_invalidations_received_(0) {} FakeSyncManager::~FakeSyncManager() {} @@ -57,12 +53,6 @@ return downloaded_types; } -ModelTypeSet FakeSyncManager::GetAndResetEnabledTypes() { - ModelTypeSet enabled_types = enabled_types_; - enabled_types_.Clear(); - return enabled_types; -} - ConfigureReason FakeSyncManager::GetAndResetConfigureReason() { ConfigureReason reason = last_configure_reason_; last_configure_reason_ = CONFIGURE_REASON_UNKNOWN; @@ -144,20 +134,20 @@ NOTIMPLEMENTED(); } -void FakeSyncManager::StartSyncingNormally( - const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) { +void FakeSyncManager::StartSyncingNormally(base::Time last_poll_time) { + // Do nothing. +} + +void FakeSyncManager::StartConfiguration() { // Do nothing. } void FakeSyncManager::ConfigureSyncer( ConfigureReason reason, ModelTypeSet to_download, - const ModelSafeRoutingInfo& new_routing_info, const base::Closure& ready_task, const base::Closure& retry_task) { last_configure_reason_ = reason; - enabled_types_ = GetRoutingInfoTypes(new_routing_info); ModelTypeSet success_types = to_download; success_types.RemoveAll(configure_fail_types_); @@ -208,6 +198,10 @@ return test_user_share_.user_share(); } +ModelTypeConnector* FakeSyncManager::GetModelTypeConnector() { + return &fake_model_type_connector_; +} + std::unique_ptr<ModelTypeConnector> FakeSyncManager::GetModelTypeConnectorProxy() { return base::MakeUnique<FakeModelTypeConnector>(); @@ -227,7 +221,7 @@ } SyncEncryptionHandler* FakeSyncManager::GetEncryptionHandler() { - return fake_encryption_handler_.get(); + return &fake_encryption_handler_; } std::vector<std::unique_ptr<ProtocolEvent>>
diff --git a/components/sync/engine/fake_sync_manager.h b/components/sync/engine/fake_sync_manager.h index 31f47440..8098e4dc 100644 --- a/components/sync/engine/fake_sync_manager.h +++ b/components/sync/engine/fake_sync_manager.h
@@ -12,8 +12,10 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" +#include "components/sync/engine/fake_model_type_connector.h" #include "components/sync/engine/sync_manager.h" #include "components/sync/syncable/test_user_share.h" +#include "components/sync/test/fake_sync_encryption_handler.h" namespace base { class SequencedTaskRunner; @@ -55,11 +57,6 @@ // GetAndResetDownloadedTypes(), or since startup if never called. ModelTypeSet GetAndResetDownloadedTypes(); - // Returns those types that have been marked as enabled since the - // last call to GetAndResetEnabledTypes(), or since startup if never - // called. - ModelTypeSet GetAndResetEnabledTypes(); - // Returns the types that have most recently received a refresh request. ModelTypeSet GetLastRefreshRequestTypes(); @@ -85,11 +82,10 @@ ModelTypeSet to_journal, ModelTypeSet to_unapply) override; void UpdateCredentials(const SyncCredentials& credentials) override; - void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) override; + void StartSyncingNormally(base::Time last_poll_time) override; + void StartConfiguration() override; void ConfigureSyncer(ConfigureReason reason, ModelTypeSet to_download, - const ModelSafeRoutingInfo& new_routing_info, const base::Closure& ready_task, const base::Closure& retry_task) override; void OnIncomingInvalidation( @@ -102,6 +98,7 @@ void SaveChanges() override; void ShutdownOnSyncThread(ShutdownReason reason) override; UserShare* GetUserShare() override; + ModelTypeConnector* GetModelTypeConnector() override; std::unique_ptr<ModelTypeConnector> GetModelTypeConnectorProxy() override; const std::string cache_guid() override; bool ReceivedExperiment(Experiments* experiments) override; @@ -140,8 +137,6 @@ ModelTypeSet unapplied_types_; // The set of types that have been downloaded. ModelTypeSet downloaded_types_; - // The set of types that have been enabled. - ModelTypeSet enabled_types_; // The types for which a refresh was most recently requested. ModelTypeSet last_refresh_request_types_; @@ -149,7 +144,9 @@ // The most recent configure reason. ConfigureReason last_configure_reason_; - std::unique_ptr<FakeSyncEncryptionHandler> fake_encryption_handler_; + FakeModelTypeConnector fake_model_type_connector_; + + FakeSyncEncryptionHandler fake_encryption_handler_; TestUserShare test_user_share_;
diff --git a/components/sync/engine/model_type_configurer.h b/components/sync/engine/model_type_configurer.h index a913a35..72d0951 100644 --- a/components/sync/engine/model_type_configurer.h +++ b/components/sync/engine/model_type_configurer.h
@@ -56,6 +56,16 @@ // Changes the set of data types that are currently being synced. virtual void ConfigureDataTypes(ConfigureParams params) = 0; + // Registers directory type with sync engine. This function creates update + // handler for the type and thus needs to be called before ConfigureDataType + // that includes the type in |to_download| type set. + virtual void RegisterDirectoryDataType(ModelType type, + ModelSafeGroup group) = 0; + + // Unregisters directory type from sync engine. After this call updates and + // local change will not be synced with server. + virtual void UnregisterDirectoryDataType(ModelType type) = 0; + // Activates change processing for the given directory data type. This must // be called synchronously with the data type's model association so // no changes are dropped between model association and change
diff --git a/components/sync/engine/model_type_connector.h b/components/sync/engine/model_type_connector.h index 1917100..d95d8de 100644 --- a/components/sync/engine/model_type_connector.h +++ b/components/sync/engine/model_type_connector.h
@@ -8,13 +8,17 @@ #include <memory> #include "components/sync/base/model_type.h" +#include "components/sync/engine/model_safe_worker.h" namespace syncer { struct ActivationContext; -// An interface into the core parts of sync for USS model types. Handles -// creating the connection between the ModelTypeWorker (CommitQueue) on the sync -// side and the (Shared)ModelTypeProcessor on the model type side. +// An interface into the core parts of sync for model types. By adding/removing +// types through methods of this interface consumer controls which types will be +// syncing (receiving updates and committing local changes). +// In addition it handles creating the connection between the ModelTypeWorker +// (CommitQueue) on the sync side and the (Shared)ModelTypeProcessor on the +// model type side for non-blocking types. class ModelTypeConnector { public: ModelTypeConnector(); @@ -24,7 +28,7 @@ // thread. Note that in production |activation_context| actually owns a // processor proxy that forwards calls to the model thread and is safe to call // from the sync thread. - virtual void ConnectType( + virtual void ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) = 0; @@ -33,7 +37,16 @@ // This is the sync thread's chance to clear state associated with the type. // It also causes the syncer to stop requesting updates for this type, and to // abort any in-progress commit requests. - virtual void DisconnectType(ModelType type) = 0; + virtual void DisconnectNonBlockingType(ModelType type) = 0; + + // Registers directory based type with sync engine. Sync engine will create + // update handler and commit contributor objects for this type. It will start + // including the type in GetUpdates and commit requests. + virtual void RegisterDirectoryType(ModelType type, ModelSafeGroup group) = 0; + + // Unregisters directory based type from sync engine. Type will no longer be + // included in communications with server. + virtual void UnregisterDirectoryType(ModelType type) = 0; }; } // namespace syncer
diff --git a/components/sync/engine/sync_engine.h b/components/sync/engine/sync_engine.h index af4e53d0..55cd760c 100644 --- a/components/sync/engine/sync_engine.h +++ b/components/sync/engine/sync_engine.h
@@ -95,6 +95,11 @@ // Updates the engine's SyncCredentials. virtual void UpdateCredentials(const SyncCredentials& credentials) = 0; + // Switches sync engine into configuration mode. In this mode only initial + // data for newly enabled types is downloaded from server. No local changes + // are committed to server. + virtual void StartConfiguration() = 0; + // This starts the sync engine running a Syncer object to communicate with // sync servers. Until this is called, no changes will leave or enter this // browser from the cloud / sync servers.
diff --git a/components/sync/engine/sync_manager.h b/components/sync/engine/sync_manager.h index 37e7de63..b853b54 100644 --- a/components/sync/engine/sync_manager.h +++ b/components/sync/engine/sync_manager.h
@@ -304,8 +304,11 @@ virtual void UpdateCredentials(const SyncCredentials& credentials) = 0; // Put the syncer in normal mode ready to perform nudges and polls. - virtual void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) = 0; + virtual void StartSyncingNormally(base::Time last_poll_time) = 0; + + // Put syncer in configuration mode. Only configuration sync cycles are + // performed. No local changes are committed to the server. + virtual void StartConfiguration() = 0; // Switches the mode of operation to CONFIGURATION_MODE and performs // any configuration tasks needed as determined by the params. Once complete, @@ -317,7 +320,6 @@ // does finish. virtual void ConfigureSyncer(ConfigureReason reason, ModelTypeSet to_download, - const ModelSafeRoutingInfo& new_routing_info, const base::Closure& ready_task, const base::Closure& retry_task) = 0; @@ -352,7 +354,13 @@ // May be called from any thread. virtual UserShare* GetUserShare() = 0; - // Returns an instance of the main interface for non-blocking sync types. + // Returns non-owning pointer to ModelTypeConnector. In contrast with + // ModelTypeConnectorProxy all calls are executed synchronously, thus the + // pointer should be used on sync thread. + virtual ModelTypeConnector* GetModelTypeConnector() = 0; + + // Returns an instance of the main interface for registering sync types with + // sync engine. virtual std::unique_ptr<ModelTypeConnector> GetModelTypeConnectorProxy() = 0; // Returns the cache_guid of the currently open database.
diff --git a/components/sync/engine_impl/cycle/sync_cycle.h b/components/sync/engine_impl/cycle/sync_cycle.h index e25fad03..72c0789 100644 --- a/components/sync/engine_impl/cycle/sync_cycle.h +++ b/components/sync/engine_impl/cycle/sync_cycle.h
@@ -16,7 +16,6 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" #include "components/sync/engine/cycle/sync_cycle_snapshot.h" -#include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine_impl/cycle/status_controller.h" #include "components/sync/engine_impl/cycle/sync_cycle_context.h" #include "components/sync/engine_impl/sync_cycle_event.h"
diff --git a/components/sync/engine_impl/cycle/sync_cycle_context.cc b/components/sync/engine_impl/cycle/sync_cycle_context.cc index 744fa4bc..c50ea25 100644 --- a/components/sync/engine_impl/cycle/sync_cycle_context.cc +++ b/components/sync/engine_impl/cycle/sync_cycle_context.cc
@@ -43,9 +43,4 @@ return model_type_registry_->GetEnabledTypes(); } -void SyncCycleContext::SetRoutingInfo( - const ModelSafeRoutingInfo& routing_info) { - model_type_registry_->SetEnabledDirectoryTypes(routing_info); -} - } // namespace syncer
diff --git a/components/sync/engine_impl/cycle/sync_cycle_context.h b/components/sync/engine_impl/cycle/sync_cycle_context.h index b7d50de..1e7e0aef 100644 --- a/components/sync/engine_impl/cycle/sync_cycle_context.h +++ b/components/sync/engine_impl/cycle/sync_cycle_context.h
@@ -56,8 +56,6 @@ ModelTypeSet GetEnabledTypes() const; - void SetRoutingInfo(const ModelSafeRoutingInfo& routing_info); - ExtensionsActivity* extensions_activity() { return extensions_activity_.get(); }
diff --git a/components/sync/engine_impl/model_type_connector_proxy.cc b/components/sync/engine_impl/model_type_connector_proxy.cc index c863117..86adea02 100644 --- a/components/sync/engine_impl/model_type_connector_proxy.cc +++ b/components/sync/engine_impl/model_type_connector_proxy.cc
@@ -18,19 +18,32 @@ ModelTypeConnectorProxy::~ModelTypeConnectorProxy() {} -void ModelTypeConnectorProxy::ConnectType( +void ModelTypeConnectorProxy::ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) { - task_runner_->PostTask( - FROM_HERE, - base::Bind(&ModelTypeConnector::ConnectType, model_type_connector_, type, - base::Passed(&activation_context))); + task_runner_->PostTask(FROM_HERE, + base::Bind(&ModelTypeConnector::ConnectNonBlockingType, + model_type_connector_, type, + base::Passed(&activation_context))); } -void ModelTypeConnectorProxy::DisconnectType(ModelType type) { +void ModelTypeConnectorProxy::DisconnectNonBlockingType(ModelType type) { + task_runner_->PostTask( + FROM_HERE, base::Bind(&ModelTypeConnector::DisconnectNonBlockingType, + model_type_connector_, type)); +} + +void ModelTypeConnectorProxy::RegisterDirectoryType(ModelType type, + ModelSafeGroup group) { task_runner_->PostTask(FROM_HERE, - base::Bind(&ModelTypeConnector::DisconnectType, - model_type_connector_, type)); + base::Bind(&ModelTypeConnector::RegisterDirectoryType, + model_type_connector_, type, group)); +} + +void ModelTypeConnectorProxy::UnregisterDirectoryType(ModelType type) { + task_runner_->PostTask( + FROM_HERE, base::Bind(&ModelTypeConnector::UnregisterDirectoryType, + model_type_connector_, type)); } } // namespace syncer
diff --git a/components/sync/engine_impl/model_type_connector_proxy.h b/components/sync/engine_impl/model_type_connector_proxy.h index ddf751b..6c2e4a9 100644 --- a/components/sync/engine_impl/model_type_connector_proxy.h +++ b/components/sync/engine_impl/model_type_connector_proxy.h
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" #include "components/sync/base/model_type.h" +#include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine/model_type_connector.h" namespace syncer { @@ -25,10 +26,12 @@ ~ModelTypeConnectorProxy() override; // ModelTypeConnector implementation - void ConnectType( + void ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) override; - void DisconnectType(ModelType type) override; + void DisconnectNonBlockingType(ModelType type) override; + void RegisterDirectoryType(ModelType type, ModelSafeGroup group) override; + void UnregisterDirectoryType(ModelType type) override; private: // A SequencedTaskRunner representing the thread where the ModelTypeConnector
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 72450f4..33af9514 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -71,72 +71,7 @@ ModelTypeRegistry::~ModelTypeRegistry() {} -void ModelTypeRegistry::SetEnabledDirectoryTypes( - const ModelSafeRoutingInfo& routing_info) { - // Remove all existing directory processors and delete them. The - // DebugInfoEmitters are not deleted here, since we want to preserve their - // counters. - for (ModelTypeSet::Iterator it = enabled_directory_types_.First(); it.Good(); - it.Inc()) { - size_t result1 = update_handler_map_.erase(it.Get()); - size_t result2 = commit_contributor_map_.erase(it.Get()); - DCHECK_EQ(1U, result1); - DCHECK_EQ(1U, result2); - } - - // Clear the old instances of directory update handlers and commit - // contributors, deleting their contents in the processs. - directory_update_handlers_.clear(); - directory_commit_contributors_.clear(); - - enabled_directory_types_.Clear(); - - // Create new ones and add them to the appropriate containers. - for (const auto& routing_kv : routing_info) { - ModelType type = routing_kv.first; - ModelSafeGroup group = routing_kv.second; - if (group == GROUP_NON_BLOCKING) - continue; - - std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker>>::iterator - worker_it = workers_map_.find(group); - DCHECK(worker_it != workers_map_.end()); - scoped_refptr<ModelSafeWorker> worker = worker_it->second; - - DataTypeDebugInfoEmitter* emitter = GetEmitter(type); - if (emitter == nullptr) { - auto new_emitter = base::MakeUnique<DirectoryTypeDebugInfoEmitter>( - directory(), type, &type_debug_info_observers_); - emitter = new_emitter.get(); - data_type_debug_info_emitter_map_.insert( - std::make_pair(type, std::move(new_emitter))); - } - - auto updater = base::MakeUnique<DirectoryUpdateHandler>(directory(), type, - worker, emitter); - bool updater_inserted = - update_handler_map_.insert(std::make_pair(type, updater.get())).second; - DCHECK(updater_inserted) - << "Attempt to override existing type handler in map"; - directory_update_handlers_.push_back(std::move(updater)); - - auto committer = base::MakeUnique<DirectoryCommitContributor>( - directory(), type, emitter); - bool committer_inserted = - commit_contributor_map_.insert(std::make_pair(type, committer.get())) - .second; - DCHECK(committer_inserted) - << "Attempt to override existing type handler in map"; - directory_commit_contributors_.push_back(std::move(committer)); - - enabled_directory_types_.Put(type); - } - - DCHECK(Intersection(GetEnabledDirectoryTypes(), GetEnabledNonBlockingTypes()) - .Empty()); -} - -void ModelTypeRegistry::ConnectType( +void ModelTypeRegistry::ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) { DCHECK(update_handler_map_.find(type) == update_handler_map_.end()); @@ -204,7 +139,7 @@ .Empty()); } -void ModelTypeRegistry::DisconnectType(ModelType type) { +void ModelTypeRegistry::DisconnectNonBlockingType(ModelType type) { DVLOG(1) << "Disabling an off-thread sync type: " << ModelTypeToString(type); DCHECK(update_handler_map_.find(type) != update_handler_map_.end()); DCHECK(commit_contributor_map_.find(type) != commit_contributor_map_.end()); @@ -225,6 +160,58 @@ } } +void ModelTypeRegistry::RegisterDirectoryType(ModelType type, + ModelSafeGroup group) { + DCHECK(update_handler_map_.find(type) == update_handler_map_.end()); + DCHECK(commit_contributor_map_.find(type) == commit_contributor_map_.end()); + DCHECK(directory_update_handlers_.find(type) == + directory_update_handlers_.end()); + DCHECK(directory_commit_contributors_.find(type) == + directory_commit_contributors_.end()); + DCHECK(data_type_debug_info_emitter_map_.find(type) == + data_type_debug_info_emitter_map_.end()); + DCHECK_NE(GROUP_NON_BLOCKING, group); + DCHECK(workers_map_.find(group) != workers_map_.end()); + + auto worker = workers_map_[group]; + DCHECK(GetEmitter(type) == nullptr); + auto owned_emitter = base::MakeUnique<DirectoryTypeDebugInfoEmitter>( + directory(), type, &type_debug_info_observers_); + DataTypeDebugInfoEmitter* emitter_ptr = owned_emitter.get(); + data_type_debug_info_emitter_map_[type] = std::move(owned_emitter); + + auto updater = base::MakeUnique<DirectoryUpdateHandler>(directory(), type, + worker, emitter_ptr); + auto committer = base::MakeUnique<DirectoryCommitContributor>( + directory(), type, emitter_ptr); + + update_handler_map_[type] = updater.get(); + commit_contributor_map_[type] = committer.get(); + + directory_update_handlers_[type] = std::move(updater); + directory_commit_contributors_[type] = std::move(committer); + + DCHECK(Intersection(GetEnabledDirectoryTypes(), GetEnabledNonBlockingTypes()) + .Empty()); +} + +void ModelTypeRegistry::UnregisterDirectoryType(ModelType type) { + DCHECK(update_handler_map_.find(type) != update_handler_map_.end()); + DCHECK(commit_contributor_map_.find(type) != commit_contributor_map_.end()); + DCHECK(directory_update_handlers_.find(type) != + directory_update_handlers_.end()); + DCHECK(directory_commit_contributors_.find(type) != + directory_commit_contributors_.end()); + DCHECK(data_type_debug_info_emitter_map_.find(type) != + data_type_debug_info_emitter_map_.end()); + + update_handler_map_.erase(type); + commit_contributor_map_.erase(type); + directory_update_handlers_.erase(type); + directory_commit_contributors_.erase(type); + data_type_debug_info_emitter_map_.erase(type); +} + ModelTypeSet ModelTypeRegistry::GetEnabledTypes() const { return Union(GetEnabledDirectoryTypes(), GetEnabledNonBlockingTypes()); } @@ -351,7 +338,10 @@ } ModelTypeSet ModelTypeRegistry::GetEnabledDirectoryTypes() const { - return enabled_directory_types_; + ModelTypeSet enabled_directory_types; + for (const auto& kv : directory_update_handlers_) + enabled_directory_types.Put(kv.first); + return enabled_directory_types; } ModelTypeSet ModelTypeRegistry::GetEnabledNonBlockingTypes() const {
diff --git a/components/sync/engine_impl/model_type_registry.h b/components/sync/engine_impl/model_type_registry.h index 5229f0d6..3e25257 100644 --- a/components/sync/engine_impl/model_type_registry.h +++ b/components/sync/engine_impl/model_type_registry.h
@@ -38,21 +38,17 @@ class ModelTypeRegistry : public ModelTypeConnector, public SyncEncryptionHandler::Observer { public: - // Constructs a ModelTypeRegistry that supports directory types. ModelTypeRegistry(const std::vector<scoped_refptr<ModelSafeWorker>>& workers, UserShare* user_share, NudgeHandler* nudge_handler, const UssMigrator& uss_migrator); ~ModelTypeRegistry() override; - // Sets the set of enabled types. - void SetEnabledDirectoryTypes(const ModelSafeRoutingInfo& routing_info); - // Enables an off-thread type for syncing. Connects the given proxy // and its task_runner to the newly created worker. // // Expects that the proxy's ModelType is not currently enabled. - void ConnectType( + void ConnectNonBlockingType( ModelType type, std::unique_ptr<ActivationContext> activation_context) override; @@ -60,7 +56,15 @@ // // Expects that the type is currently enabled. // Deletes the worker associated with the type. - void DisconnectType(ModelType type) override; + void DisconnectNonBlockingType(ModelType type) override; + + // Creates update handler and commit contributor objects for directory type. + // Expects that the type is not yet registered. + void RegisterDirectoryType(ModelType type, ModelSafeGroup group) override; + + // Deletes objects related to directory type. Expects that the type is + // registered. + void UnregisterDirectoryType(ModelType type) override; // Implementation of SyncEncryptionHandler::Observer. void OnPassphraseRequired( @@ -118,9 +122,9 @@ } // Sets of handlers and contributors. - std::vector<std::unique_ptr<DirectoryCommitContributor>> + std::map<ModelType, std::unique_ptr<DirectoryCommitContributor>> directory_commit_contributors_; - std::vector<std::unique_ptr<DirectoryUpdateHandler>> + std::map<ModelType, std::unique_ptr<DirectoryUpdateHandler>> directory_update_handlers_; std::vector<std::unique_ptr<ModelTypeWorker>> model_type_workers_; @@ -149,9 +153,6 @@ // The NudgeHandler. Not owned. NudgeHandler* nudge_handler_; - // The set of enabled directory types. - ModelTypeSet enabled_directory_types_; - // Function to call to migrate data from the directory to USS. UssMigrator uss_migrator_;
diff --git a/components/sync/engine_impl/model_type_registry_unittest.cc b/components/sync/engine_impl/model_type_registry_unittest.cc index 39d6548e..0b72864 100644 --- a/components/sync/engine_impl/model_type_registry_unittest.cc +++ b/components/sync/engine_impl/model_type_registry_unittest.cc
@@ -9,6 +9,7 @@ #include "base/deferred_sequenced_task_runner.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/test/gtest_util.h" #include "components/sync/engine/activation_context.h" #include "components/sync/engine/fake_model_type_processor.h" #include "components/sync/protocol/model_type_state.pb.h" @@ -24,11 +25,29 @@ class ModelTypeRegistryTest : public ::testing::Test { public: - ModelTypeRegistryTest(); - void SetUp() override; - void TearDown() override; + void SetUp() override { + test_user_share_.SetUp(); + scoped_refptr<ModelSafeWorker> passive_worker( + new FakeModelWorker(GROUP_PASSIVE)); + scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); + scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); + workers_.push_back(passive_worker); + workers_.push_back(ui_worker); + workers_.push_back(db_worker); - ModelTypeRegistry* registry(); + registry_ = base::MakeUnique<ModelTypeRegistry>( + workers_, test_user_share_.user_share(), &mock_nudge_handler_, + base::Bind(&ModelTypeRegistryTest::MigrateDirectory, + base::Unretained(this))); + } + + void TearDown() override { + registry_.reset(); + workers_.clear(); + test_user_share_.TearDown(); + } + + ModelTypeRegistry* registry() { return registry_.get(); } static sync_pb::ModelTypeState MakeInitialModelTypeState(ModelType type) { sync_pb::ModelTypeState state; @@ -66,7 +85,9 @@ return true; } - syncable::Directory* directory(); + syncable::Directory* directory() { + return test_user_share_.user_share()->directory.get(); + } base::MessageLoop message_loop_; @@ -77,127 +98,51 @@ bool migration_attempted_ = false; }; -ModelTypeRegistryTest::ModelTypeRegistryTest() {} - -void ModelTypeRegistryTest::SetUp() { - test_user_share_.SetUp(); - scoped_refptr<ModelSafeWorker> passive_worker( - new FakeModelWorker(GROUP_PASSIVE)); - scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); - scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); - workers_.push_back(passive_worker); - workers_.push_back(ui_worker); - workers_.push_back(db_worker); - - registry_ = base::MakeUnique<ModelTypeRegistry>( - workers_, test_user_share_.user_share(), &mock_nudge_handler_, - base::Bind(&ModelTypeRegistryTest::MigrateDirectory, - base::Unretained(this))); -} - -void ModelTypeRegistryTest::TearDown() { - registry_.reset(); - workers_.clear(); - test_user_share_.TearDown(); -} - -ModelTypeRegistry* ModelTypeRegistryTest::registry() { - return registry_.get(); -} - -syncable::Directory* ModelTypeRegistryTest::directory() { - return test_user_share_.user_share()->directory.get(); -} - -// Create some directory update handlers and commit contributors. -// -// We don't get to inspect any of the state we're modifying. This test is -// useful only for detecting crashes or memory leaks. -TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Once) { - ModelSafeRoutingInfo routing_info; - routing_info.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info.insert(std::make_pair(BOOKMARKS, GROUP_UI)); - routing_info.insert(std::make_pair(AUTOFILL, GROUP_DB)); - routing_info.insert(std::make_pair(APPS, GROUP_NON_BLOCKING)); - - registry()->SetEnabledDirectoryTypes(routing_info); - +// Tests operations with directory types. +// Registering/unregistering type should affect enabled types and handlers map. +// Registering/unregistering type twice should trigger DCHECK. +// Registering type with unknown ModelSafeGroup should trigger DCHECK. +TEST_F(ModelTypeRegistryTest, DirectoryTypes) { UpdateHandlerMap* update_handler_map = registry()->update_handler_map(); - // Apps is non-blocking type, SetEnabledDirectoryTypes shouldn't instantiate - // update_handler for it. - EXPECT_TRUE(update_handler_map->find(APPS) == update_handler_map->end()); -} + EXPECT_TRUE(registry()->GetEnabledTypes().Empty()); -// Try two different routing info settings. -// -// We don't get to inspect any of the state we're modifying. This test is -// useful only for detecting crashes or memory leaks. -TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Repeatedly) { - ModelSafeRoutingInfo routing_info1; - routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(AUTOFILL, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(APPS, GROUP_NON_BLOCKING)); + registry()->RegisterDirectoryType(AUTOFILL, GROUP_DB); + EXPECT_EQ(ModelTypeSet(AUTOFILL), registry()->GetEnabledTypes()); - registry()->SetEnabledDirectoryTypes(routing_info1); + registry()->RegisterDirectoryType(BOOKMARKS, GROUP_UI); + EXPECT_EQ(ModelTypeSet(AUTOFILL, BOOKMARKS), registry()->GetEnabledTypes()); - ModelSafeRoutingInfo routing_info2; - routing_info2.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info2.insert(std::make_pair(BOOKMARKS, GROUP_UI)); - routing_info2.insert(std::make_pair(AUTOFILL, GROUP_DB)); - routing_info2.insert(std::make_pair(APPS, GROUP_NON_BLOCKING)); + // Try registering already registered type. + EXPECT_DCHECK_DEATH(registry()->RegisterDirectoryType(BOOKMARKS, GROUP_UI)); - registry()->SetEnabledDirectoryTypes(routing_info2); -} + EXPECT_TRUE(update_handler_map->find(AUTOFILL) != update_handler_map->end()); + EXPECT_TRUE(update_handler_map->find(BOOKMARKS) != update_handler_map->end()); -// Test removing all types from the list. -// -// We don't get to inspect any of the state we're modifying. This test is -// useful only for detecting crashes or memory leaks. -TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Clear) { - ModelSafeRoutingInfo routing_info1; - routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI)); - routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB)); - routing_info1.insert(std::make_pair(APPS, GROUP_NON_BLOCKING)); + registry()->UnregisterDirectoryType(AUTOFILL); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), registry()->GetEnabledTypes()); + EXPECT_TRUE(update_handler_map->find(AUTOFILL) == update_handler_map->end()); + EXPECT_TRUE(update_handler_map->find(BOOKMARKS) != update_handler_map->end()); - registry()->SetEnabledDirectoryTypes(routing_info1); + // Try unregistering already unregistered type. + EXPECT_DCHECK_DEATH(registry()->UnregisterDirectoryType(AUTOFILL)); - ModelSafeRoutingInfo routing_info2; - registry()->SetEnabledDirectoryTypes(routing_info2); -} - -// Test disabling then re-enabling some directory types. -// -// We don't get to inspect any of the state we're modifying. This test is -// useful only for detecting crashes or memory leaks. -TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_OffAndOn) { - ModelSafeRoutingInfo routing_info1; - routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI)); - routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB)); - routing_info1.insert(std::make_pair(APPS, GROUP_NON_BLOCKING)); - - registry()->SetEnabledDirectoryTypes(routing_info1); - - ModelSafeRoutingInfo routing_info2; - registry()->SetEnabledDirectoryTypes(routing_info2); - - registry()->SetEnabledDirectoryTypes(routing_info1); + // Try registering type with unknown worker. + EXPECT_DCHECK_DEATH( + registry()->RegisterDirectoryType(SESSIONS, GROUP_HISTORY)); } TEST_F(ModelTypeRegistryTest, NonBlockingTypes) { EXPECT_TRUE(registry()->GetEnabledTypes().Empty()); - registry()->ConnectType( + registry()->ConnectNonBlockingType( THEMES, MakeActivationContext(MakeInitialModelTypeState(THEMES))); EXPECT_EQ(ModelTypeSet(THEMES), registry()->GetEnabledTypes()); - registry()->ConnectType( + registry()->ConnectNonBlockingType( SESSIONS, MakeActivationContext(MakeInitialModelTypeState(SESSIONS))); EXPECT_EQ(ModelTypeSet(THEMES, SESSIONS), registry()->GetEnabledTypes()); - registry()->DisconnectType(THEMES); + registry()->DisconnectNonBlockingType(THEMES); EXPECT_EQ(ModelTypeSet(SESSIONS), registry()->GetEnabledTypes()); // Allow ModelTypeRegistry destruction to delete the @@ -205,73 +150,70 @@ } TEST_F(ModelTypeRegistryTest, NonBlockingTypesWithDirectoryTypes) { - ModelSafeRoutingInfo routing_info1; - routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE)); - routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI)); - routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB)); - routing_info1.insert(std::make_pair(THEMES, GROUP_NON_BLOCKING)); - routing_info1.insert(std::make_pair(SESSIONS, GROUP_NON_BLOCKING)); - ModelTypeSet directory_types(NIGORI, BOOKMARKS, AUTOFILL); ModelTypeSet current_types; EXPECT_TRUE(registry()->GetEnabledTypes().Empty()); // Add the themes non-blocking type. - registry()->ConnectType( + registry()->ConnectNonBlockingType( THEMES, MakeActivationContext(MakeInitialModelTypeState(THEMES))); current_types.Put(THEMES); EXPECT_EQ(current_types, registry()->GetEnabledTypes()); // Add some directory types. - registry()->SetEnabledDirectoryTypes(routing_info1); + for (auto it = directory_types.First(); it.Good(); it.Inc()) + registry()->RegisterDirectoryType(it.Get(), GROUP_PASSIVE); current_types.PutAll(directory_types); EXPECT_EQ(current_types, registry()->GetEnabledTypes()); // Add sessions non-blocking type. - registry()->ConnectType( + registry()->ConnectNonBlockingType( SESSIONS, MakeActivationContext(MakeInitialModelTypeState(SESSIONS))); current_types.Put(SESSIONS); EXPECT_EQ(current_types, registry()->GetEnabledTypes()); // Remove themes non-blocking type. - registry()->DisconnectType(THEMES); + registry()->DisconnectNonBlockingType(THEMES); current_types.Remove(THEMES); EXPECT_EQ(current_types, registry()->GetEnabledTypes()); // Clear all directory types. - ModelSafeRoutingInfo routing_info2; - registry()->SetEnabledDirectoryTypes(routing_info2); + for (auto it = directory_types.First(); it.Good(); it.Inc()) + registry()->UnregisterDirectoryType(it.Get()); current_types.RemoveAll(directory_types); EXPECT_EQ(current_types, registry()->GetEnabledTypes()); } // Tests correct result returned from GetInitialSyncEndedTypes. TEST_F(ModelTypeRegistryTest, GetInitialSyncEndedTypes) { - ModelSafeRoutingInfo routing_info; - // Add two directory and two non-blocking types. - routing_info.insert(std::make_pair(AUTOFILL, GROUP_PASSIVE)); - routing_info.insert(std::make_pair(BOOKMARKS, GROUP_PASSIVE)); - routing_info.insert(std::make_pair(THEMES, GROUP_NON_BLOCKING)); - routing_info.insert(std::make_pair(SESSIONS, GROUP_NON_BLOCKING)); - registry()->SetEnabledDirectoryTypes(routing_info); + // Add two directory types. + registry()->RegisterDirectoryType(AUTOFILL, GROUP_PASSIVE); + registry()->RegisterDirectoryType(BOOKMARKS, GROUP_PASSIVE); // Only Autofill and Themes types finished initial sync. MarkInitialSyncEndedForDirectoryType(AUTOFILL); + // Add two non-blocking type. sync_pb::ModelTypeState model_type_state = MakeInitialModelTypeState(THEMES); model_type_state.set_initial_sync_done(true); - registry()->ConnectType(THEMES, MakeActivationContext(model_type_state)); + registry()->ConnectNonBlockingType(THEMES, + MakeActivationContext(model_type_state)); + + registry()->ConnectNonBlockingType( + SESSIONS, MakeActivationContext(MakeInitialModelTypeState(SESSIONS))); EXPECT_EQ(ModelTypeSet(AUTOFILL, THEMES), registry()->GetInitialSyncEndedTypes()); } +// Tests that when directory data is present for type ConnectNonBlockingType +// triggers USS migration. TEST_F(ModelTypeRegistryTest, UssMigrationAttempted) { EXPECT_FALSE(migration_attempted()); MarkInitialSyncEndedForDirectoryType(THEMES); - registry()->ConnectType( + registry()->ConnectNonBlockingType( THEMES, MakeActivationContext(MakeInitialModelTypeState(THEMES))); EXPECT_TRUE(migration_attempted());
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index e52090e..b4f52a50 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -182,7 +182,6 @@ void SyncManagerImpl::ConfigureSyncer( ConfigureReason reason, ModelTypeSet to_download, - const ModelSafeRoutingInfo& new_routing_info, const base::Closure& ready_task, const base::Closure& retry_task) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -195,12 +194,9 @@ DVLOG(1) << "Configuring -" << "\n\t" - << "current types: " - << ModelTypeSetToString(GetRoutingInfoTypes(new_routing_info)) - << "\n\t" << "types to download: " << ModelTypeSetToString(to_download); ConfigurationParams params(GetSourceFromReason(reason), to_download, - new_routing_info, ready_task, retry_task); + ready_task, retry_task); scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time()); scheduler_->ScheduleConfiguration(params); @@ -396,18 +392,17 @@ const SyncEncryptionHandler::NigoriState& nigori_state) {} void SyncManagerImpl::StartSyncingNormally( - const ModelSafeRoutingInfo& routing_info, base::Time last_poll_time) { // Start the sync scheduler. - // TODO(sync): We always want the newest set of routes when we switch back - // to normal mode. Figure out how to enforce set_routing_info is always - // appropriately set and that it's only modified when switching to normal - // mode. DCHECK(thread_checker_.CalledOnValidThread()); - cycle_context_->SetRoutingInfo(routing_info); scheduler_->Start(SyncScheduler::NORMAL_MODE, last_poll_time); } +void SyncManagerImpl::StartConfiguration() { + DCHECK(thread_checker_.CalledOnValidThread()); + scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time()); +} + syncable::Directory* SyncManagerImpl::directory() { return share_.directory.get(); } @@ -906,6 +901,11 @@ return &share_; } +ModelTypeConnector* SyncManagerImpl::GetModelTypeConnector() { + DCHECK(thread_checker_.CalledOnValidThread()); + return model_type_registry_.get(); +} + std::unique_ptr<ModelTypeConnector> SyncManagerImpl::GetModelTypeConnectorProxy() { DCHECK(initialized_);
diff --git a/components/sync/engine_impl/sync_manager_impl.h b/components/sync/engine_impl/sync_manager_impl.h index 4b396e9..6dbc42a 100644 --- a/components/sync/engine_impl/sync_manager_impl.h +++ b/components/sync/engine_impl/sync_manager_impl.h
@@ -72,11 +72,10 @@ ModelTypeSet to_journal, ModelTypeSet to_unapply) override; void UpdateCredentials(const SyncCredentials& credentials) override; - void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) override; + void StartSyncingNormally(base::Time last_poll_time) override; + void StartConfiguration() override; void ConfigureSyncer(ConfigureReason reason, ModelTypeSet to_download, - const ModelSafeRoutingInfo& new_routing_info, const base::Closure& ready_task, const base::Closure& retry_task) override; void SetInvalidatorEnabled(bool invalidator_enabled) override; @@ -89,6 +88,7 @@ void SaveChanges() override; void ShutdownOnSyncThread(ShutdownReason reason) override; UserShare* GetUserShare() override; + ModelTypeConnector* GetModelTypeConnector() override; std::unique_ptr<ModelTypeConnector> GetModelTypeConnectorProxy() override; const std::string cache_guid() override; bool ReceivedExperiment(Experiments* experiments) override;
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index afaab93..8bf15f9 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -1017,8 +1017,6 @@ EXPECT_FALSE(js_backend_.IsInitialized()); std::vector<scoped_refptr<ModelSafeWorker>> workers; - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); // This works only because all routing info types are GROUP_PASSIVE. // If we had types in other groups, we would need additional workers @@ -1052,10 +1050,10 @@ EXPECT_EQ(EngineComponentsFactory::STORAGE_ON_DISK, storage_used_); if (initialization_succeeded_) { - for (ModelSafeRoutingInfo::iterator i = routing_info.begin(); - i != routing_info.end(); ++i) { - type_roots_[i->first] = - MakeTypeRoot(sync_manager_.GetUserShare(), i->first); + ModelTypeSet enabled_types = GetEnabledTypes(); + for (auto it = enabled_types.First(); it.Good(); it.Inc()) { + type_roots_[it.Get()] = + MakeTypeRoot(sync_manager_.GetUserShare(), it.Get()); } } @@ -1071,23 +1069,20 @@ PumpLoop(); } - void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { - (*out)[NIGORI] = GROUP_PASSIVE; - (*out)[DEVICE_INFO] = GROUP_PASSIVE; - (*out)[EXPERIMENTS] = GROUP_PASSIVE; - (*out)[BOOKMARKS] = GROUP_PASSIVE; - (*out)[THEMES] = GROUP_PASSIVE; - (*out)[SESSIONS] = GROUP_PASSIVE; - (*out)[PASSWORDS] = GROUP_PASSIVE; - (*out)[PREFERENCES] = GROUP_PASSIVE; - (*out)[PRIORITY_PREFERENCES] = GROUP_PASSIVE; - (*out)[ARTICLES] = GROUP_PASSIVE; - } - ModelTypeSet GetEnabledTypes() { - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - return GetRoutingInfoTypes(routing_info); + ModelTypeSet enabled_types; + enabled_types.Put(NIGORI); + enabled_types.Put(DEVICE_INFO); + enabled_types.Put(EXPERIMENTS); + enabled_types.Put(BOOKMARKS); + enabled_types.Put(THEMES); + enabled_types.Put(SESSIONS); + enabled_types.Put(PASSWORDS); + enabled_types.Put(PREFERENCES); + enabled_types.Put(PRIORITY_PREFERENCES); + enabled_types.Put(ARTICLES); + + return enabled_types; } void OnChangesApplied(ModelType model_type, @@ -2663,18 +2658,15 @@ // Verify transaction version of a model type is incremented when node of // that type is updated. TEST_F(SyncManagerTest, IncrementTransactionVersion) { - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - { ReadTransaction read_trans(FROM_HERE, sync_manager_.GetUserShare()); - for (ModelSafeRoutingInfo::iterator i = routing_info.begin(); - i != routing_info.end(); ++i) { + ModelTypeSet enabled_types = GetEnabledTypes(); + for (auto it = enabled_types.First(); it.Good(); it.Inc()) { // Transaction version is incremented when SyncManagerTest::SetUp() // creates a node of each type. EXPECT_EQ(1, sync_manager_.GetUserShare()->directory->GetTransactionVersion( - i->first)); + it.Get())); } } @@ -2688,11 +2680,11 @@ { ReadTransaction read_trans(FROM_HERE, sync_manager_.GetUserShare()); - for (ModelSafeRoutingInfo::iterator i = routing_info.begin(); - i != routing_info.end(); ++i) { - EXPECT_EQ(i->first == BOOKMARKS ? 2 : 1, + ModelTypeSet enabled_types = GetEnabledTypes(); + for (auto it = enabled_types.First(); it.Good(); it.Inc()) { + EXPECT_EQ(it.Get() == BOOKMARKS ? 2 : 1, sync_manager_.GetUserShare()->directory->GetTransactionVersion( - i->first)); + it.Get())); } } } @@ -2783,21 +2775,34 @@ }; // Test that the configuration params are properly created and sent to -// ScheduleConfigure. No callback should be invoked. Any disabled datatypes -// should be purged. +// ScheduleConfigure. No callback should be invoked. TEST_F(SyncManagerTestWithMockScheduler, BasicConfiguration) { ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; ModelTypeSet types_to_download(BOOKMARKS, PREFERENCES); - ModelSafeRoutingInfo new_routing_info; - GetModelSafeRoutingInfo(&new_routing_info); - ModelTypeSet enabled_types = GetRoutingInfoTypes(new_routing_info); - ModelTypeSet disabled_types = Difference(ModelTypeSet::All(), enabled_types); ConfigurationParams params; EXPECT_CALL(*scheduler(), Start(SyncScheduler::CONFIGURATION_MODE, _)); EXPECT_CALL(*scheduler(), ScheduleConfiguration(_)) .WillOnce(SaveArg<0>(¶ms)); + CallbackCounter ready_task_counter, retry_task_counter; + sync_manager_.ConfigureSyncer( + reason, types_to_download, + base::Bind(&CallbackCounter::Callback, + base::Unretained(&ready_task_counter)), + base::Bind(&CallbackCounter::Callback, + base::Unretained(&retry_task_counter))); + EXPECT_EQ(0, ready_task_counter.times_called()); + EXPECT_EQ(0, retry_task_counter.times_called()); + EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, params.source); + EXPECT_EQ(types_to_download, params.types_to_download); +} + +// Test that PurgeDisabledTypes only purges recently disabled types leaving +// others intact. +TEST_F(SyncManagerTestWithMockScheduler, PurgeDisabledTypes) { + ModelTypeSet enabled_types = GetEnabledTypes(); + ModelTypeSet disabled_types = Difference(ModelTypeSet::All(), enabled_types); // Set data for all types. ModelTypeSet protocol_types = ProtocolTypes(); for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good(); @@ -2807,19 +2812,6 @@ sync_manager_.PurgeDisabledTypes(disabled_types, ModelTypeSet(), ModelTypeSet()); - CallbackCounter ready_task_counter, retry_task_counter; - sync_manager_.ConfigureSyncer( - reason, types_to_download, new_routing_info, - base::Bind(&CallbackCounter::Callback, - base::Unretained(&ready_task_counter)), - base::Bind(&CallbackCounter::Callback, - base::Unretained(&retry_task_counter))); - EXPECT_EQ(0, ready_task_counter.times_called()); - EXPECT_EQ(0, retry_task_counter.times_called()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, params.source); - EXPECT_EQ(types_to_download, params.types_to_download); - EXPECT_EQ(new_routing_info, params.routing_info); - // Verify all the disabled types were purged. EXPECT_EQ(enabled_types, sync_manager_.GetUserShare()->directory->InitialSyncEndedTypes()); @@ -2827,60 +2819,6 @@ ModelTypeSet::All())); } -// Test that on a reconfiguration (configuration where the session context -// already has routing info), only those recently disabled types are purged. -TEST_F(SyncManagerTestWithMockScheduler, ReConfiguration) { - ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; - ModelTypeSet types_to_download(BOOKMARKS, PREFERENCES); - ModelTypeSet disabled_types = ModelTypeSet(THEMES, SESSIONS); - ModelSafeRoutingInfo old_routing_info; - ModelSafeRoutingInfo new_routing_info; - GetModelSafeRoutingInfo(&old_routing_info); - new_routing_info = old_routing_info; - new_routing_info.erase(THEMES); - new_routing_info.erase(SESSIONS); - ModelTypeSet enabled_types = GetRoutingInfoTypes(new_routing_info); - - ConfigurationParams params; - EXPECT_CALL(*scheduler(), Start(SyncScheduler::CONFIGURATION_MODE, _)); - EXPECT_CALL(*scheduler(), ScheduleConfiguration(_)) - .WillOnce(SaveArg<0>(¶ms)); - - // Set data for all types except those recently disabled (so we can verify - // only those recently disabled are purged) . - ModelTypeSet protocol_types = ProtocolTypes(); - for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good(); - iter.Inc()) { - if (!disabled_types.Has(iter.Get())) { - SetProgressMarkerForType(iter.Get(), true); - } else { - SetProgressMarkerForType(iter.Get(), false); - } - } - - // Set the context to have the old routing info. - cycle_context()->SetRoutingInfo(old_routing_info); - - CallbackCounter ready_task_counter, retry_task_counter; - sync_manager_.PurgeDisabledTypes(ModelTypeSet(), ModelTypeSet(), - ModelTypeSet()); - sync_manager_.ConfigureSyncer( - reason, types_to_download, new_routing_info, - base::Bind(&CallbackCounter::Callback, - base::Unretained(&ready_task_counter)), - base::Bind(&CallbackCounter::Callback, - base::Unretained(&retry_task_counter))); - EXPECT_EQ(0, ready_task_counter.times_called()); - EXPECT_EQ(0, retry_task_counter.times_called()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, params.source); - EXPECT_EQ(types_to_download, params.types_to_download); - EXPECT_EQ(new_routing_info, params.routing_info); - - // Verify only the recently disabled types were purged. - EXPECT_EQ(disabled_types, sync_manager_.GetTypesWithEmptyProgressMarkerToken( - ProtocolTypes())); -} - // Test that SyncManager::ClearServerData invokes the scheduler. TEST_F(SyncManagerTestWithMockScheduler, ClearServerData) { EXPECT_CALL(*scheduler(), Start(SyncScheduler::CLEAR_SERVER_DATA_MODE, _)); @@ -2894,9 +2832,7 @@ // Test that PurgePartiallySyncedTypes purges only those types that have not // fully completed their initial download and apply. TEST_F(SyncManagerTest, PurgePartiallySyncedTypes) { - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); + ModelTypeSet enabled_types = GetEnabledTypes(); UserShare* share = sync_manager_.GetUserShare(); @@ -2971,9 +2907,7 @@ // Test CleanupDisabledTypes properly purges all disabled types as specified // by the previous and current enabled params. TEST_F(SyncManagerTest, PurgeDisabledTypes) { - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); + ModelTypeSet enabled_types = GetEnabledTypes(); ModelTypeSet disabled_types = Difference(ModelTypeSet::All(), enabled_types); // The harness should have initialized the enabled_types for us. @@ -3014,10 +2948,8 @@ // Test PurgeDisabledTypes properly unapplies types by deleting their local data // and preserving their server data and progress marker. TEST_F(SyncManagerTest, PurgeUnappliedTypes) { - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); ModelTypeSet unapplied_types = ModelTypeSet(BOOKMARKS, PREFERENCES); - ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); + ModelTypeSet enabled_types = GetEnabledTypes(); ModelTypeSet disabled_types = Difference(ModelTypeSet::All(), enabled_types); // The harness should have initialized the enabled_types for us.
diff --git a/components/sync/engine_impl/sync_scheduler.h b/components/sync/engine_impl/sync_scheduler.h index c1c18b2..160dc1c1 100644 --- a/components/sync/engine_impl/sync_scheduler.h +++ b/components/sync/engine_impl/sync_scheduler.h
@@ -26,7 +26,6 @@ ConfigurationParams( const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, ModelTypeSet types_to_download, - const ModelSafeRoutingInfo& routing_info, const base::Closure& ready_task, const base::Closure& retry_task); ConfigurationParams(const ConfigurationParams& other); @@ -36,8 +35,6 @@ sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source; // The types that should be downloaded. ModelTypeSet types_to_download; - // The new routing info (superset of types to be downloaded). - ModelSafeRoutingInfo routing_info; // Callback to invoke on configuration completion. base::Closure ready_task; // Callback to invoke on configuration failure.
diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc index 69559b51..09a873c 100644 --- a/components/sync/engine_impl/sync_scheduler_impl.cc +++ b/components/sync/engine_impl/sync_scheduler_impl.cc
@@ -100,12 +100,10 @@ ConfigurationParams::ConfigurationParams( const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, ModelTypeSet types_to_download, - const ModelSafeRoutingInfo& routing_info, const base::Closure& ready_task, const base::Closure& retry_task) : source(source), types_to_download(types_to_download), - routing_info(routing_info), ready_task(ready_task), retry_task(retry_task) { DCHECK(!ready_task.is_null()); @@ -270,25 +268,6 @@ observer.OnSyncCycleEvent(event); } -namespace { - -// Helper to extract the routing info corresponding to types in -// |types_to_download| from |current_routes|. -void BuildModelSafeParams(ModelTypeSet types_to_download, - const ModelSafeRoutingInfo& current_routes, - ModelSafeRoutingInfo* result_routes) { - for (ModelTypeSet::Iterator iter = types_to_download.First(); iter.Good(); - iter.Inc()) { - ModelType type = iter.Get(); - ModelSafeRoutingInfo::const_iterator route = current_routes.find(type); - DCHECK(route != current_routes.end()); - ModelSafeGroup group = route->second; - (*result_routes)[type] = group; - } -} - -} // namespace. - void SyncSchedulerImpl::ScheduleConfiguration( const ConfigurationParams& params) { DCHECK(CalledOnValidThread()); @@ -302,11 +281,6 @@ // for a pending configure job. DCHECK(!pending_configure_params_); - ModelSafeRoutingInfo restricted_routes; - BuildModelSafeParams(params.types_to_download, params.routing_info, - &restricted_routes); - cycle_context_->SetRoutingInfo(restricted_routes); - // Only reconfigure if we have types to download. if (!params.types_to_download.Empty()) { pending_configure_params_ = base::MakeUnique<ConfigurationParams>(params);
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc index d4d6734..93d8a00 100644 --- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -89,14 +89,6 @@ RunLoop(); } -ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) { - ModelSafeRoutingInfo routes; - for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { - routes[iter.Get()] = GROUP_PASSIVE; - } - return routes; -} - static const size_t kMinNumSamples = 5; // Test harness for the SyncScheduler. Test the delays and backoff timers used @@ -129,11 +121,6 @@ delay_ = nullptr; extensions_activity_ = new ExtensionsActivity(); - routing_info_[THEMES] = GROUP_UI; - routing_info_[TYPED_URLS] = GROUP_DB; - routing_info_[THEMES] = GROUP_UI; - routing_info_[NIGORI] = GROUP_PASSIVE; - workers_.clear(); workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI))); workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_DB))); @@ -146,6 +133,9 @@ model_type_registry_ = base::MakeUnique<ModelTypeRegistry>( workers_, test_user_share_.user_share(), &mock_nudge_handler_, UssMigrator()); + model_type_registry_->RegisterDirectoryType(NIGORI, GROUP_PASSIVE); + model_type_registry_->RegisterDirectoryType(THEMES, GROUP_UI); + model_type_registry_->RegisterDirectoryType(TYPED_URLS, GROUP_DB); context_ = base::MakeUnique<SyncCycleContext>( connection_.get(), directory(), extensions_activity_.get(), @@ -154,7 +144,6 @@ true, // enable keystore encryption false, // force enable pre-commit GU avoidance "fake_invalidator_client_id"); - context_->SetRoutingInfo(routing_info_); context_->set_notifications_enabled(true); context_->set_account_name("Test"); scheduler_ = base::MakeUnique<SyncSchedulerImpl>( @@ -164,7 +153,6 @@ } SyncSchedulerImpl* scheduler() { return scheduler_.get(); } - const ModelSafeRoutingInfo& routing_info() { return routing_info_; } MockSyncer* syncer() { return syncer_; } MockDelayProvider* delay() { return delay_; } MockConnectionManager* connection() { return connection_.get(); } @@ -309,7 +297,6 @@ MockDelayProvider* delay_; std::vector<scoped_refptr<ModelSafeWorker>> workers_; scoped_refptr<ExtensionsActivity> extensions_activity_; - ModelSafeRoutingInfo routing_info_; base::WeakPtrFactory<SyncSchedulerImplTest> weak_ptr_factory_; }; @@ -393,7 +380,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -422,7 +408,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -468,7 +453,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -490,7 +474,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -518,7 +501,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -546,7 +528,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -807,7 +788,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), + GetUpdatesCallerInfo::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -891,7 +872,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), + GetUpdatesCallerInfo::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1212,7 +1193,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, config_types, - TypesToRoutingInfo(config_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1229,9 +1209,6 @@ .WillOnce(DoAll(Invoke(test_util::SimulateNormalSuccess), RecordSyncShare(×2, true))); - // TODO(tim): Figure out how to remove this dangerous need to reset - // routing info between mode switches. - context()->SetRoutingInfo(routing_info()); StartSyncScheduler(base::Time()); RunLoop(); @@ -1307,7 +1284,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), + GetUpdatesCallerInfo::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1356,7 +1333,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), + GetUpdatesCallerInfo::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1589,7 +1566,6 @@ CallbackCounter retry_counter; ConfigurationParams params( GetUpdatesCallerInfo::RECONFIGURATION, model_types, - TypesToRoutingInfo(model_types), base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params);
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc index c07f91a..a66b784 100644 --- a/components/sync/engine_impl/syncer_unittest.cc +++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -219,15 +219,6 @@ void OnProtocolEvent(const ProtocolEvent& event) override {} void OnSyncProtocolError(const SyncProtocolError& error) override {} - void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { - // We're just testing the sync engine here, so we shunt everything to - // the SyncerThread. Datatypes which aren't enabled aren't in the map. - for (ModelTypeSet::Iterator it = enabled_datatypes_.First(); it.Good(); - it.Inc()) { - (*out)[it.Get()] = GROUP_PASSIVE; - } - } - void OnSyncCycleEvent(const SyncCycleEvent& event) override { DVLOG(1) << "HandleSyncEngineEvent in unittest " << event.what_happened; // we only test for entry-specific events, not status changed ones. @@ -271,32 +262,28 @@ mock_server_ = base::MakeUnique<MockConnectionManager>( directory(), &cancelation_signal_); debug_info_getter_ = base::MakeUnique<MockDebugInfoGetter>(); - EnableDatatype(BOOKMARKS); - EnableDatatype(EXTENSIONS); - EnableDatatype(NIGORI); - EnableDatatype(PREFERENCES); - EnableDatatype(NIGORI); workers_.push_back( scoped_refptr<ModelSafeWorker>(new FakeModelWorker(GROUP_PASSIVE))); std::vector<SyncEngineEventListener*> listeners; listeners.push_back(this); - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - model_type_registry_ = base::MakeUnique<ModelTypeRegistry>( workers_, test_user_share_.user_share(), &mock_nudge_handler_, UssMigrator()); model_type_registry_->RegisterDirectoryTypeDebugInfoObserver( &debug_info_cache_); + EnableDatatype(BOOKMARKS); + EnableDatatype(EXTENSIONS); + EnableDatatype(NIGORI); + EnableDatatype(PREFERENCES); + context_ = base::MakeUnique<SyncCycleContext>( mock_server_.get(), directory(), extensions_activity_.get(), listeners, debug_info_getter_.get(), model_type_registry_.get(), true, // enable keystore encryption false, // force enable pre-commit GU avoidance experiment "fake_invalidator_client_id"); - context_->SetRoutingInfo(routing_info); syncer_ = new Syncer(&cancelation_signal_); scheduler_ = base::MakeUnique<SyncSchedulerImpl>( "TestSyncScheduler", BackoffDelayProvider::FromDefaults(), @@ -510,27 +497,13 @@ void EnableDatatype(ModelType model_type) { enabled_datatypes_.Put(model_type); - - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - - if (context_) { - context_->SetRoutingInfo(routing_info); - } - + model_type_registry_->RegisterDirectoryType(model_type, GROUP_PASSIVE); mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); } void DisableDatatype(ModelType model_type) { enabled_datatypes_.Remove(model_type); - - ModelSafeRoutingInfo routing_info; - GetModelSafeRoutingInfo(&routing_info); - - if (context_) { - context_->SetRoutingInfo(routing_info); - } - + model_type_registry_->UnregisterDirectoryType(model_type); mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); } @@ -4896,7 +4869,6 @@ // The expectations of this test happen in the MockConnectionManager's // GetUpdates handler. EnableDatatype sets the expectation value from our // set of enabled/disabled datatypes. - EnableDatatype(BOOKMARKS); EXPECT_TRUE(SyncShareNudge()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); @@ -4904,10 +4876,6 @@ EXPECT_TRUE(SyncShareNudge()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); - EnableDatatype(PREFERENCES); - EXPECT_TRUE(SyncShareNudge()); - EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); - DisableDatatype(BOOKMARKS); EXPECT_TRUE(SyncShareNudge()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
diff --git a/components/sync/model/recording_model_type_change_processor.cc b/components/sync/model/recording_model_type_change_processor.cc new file mode 100644 index 0000000..13c1850 --- /dev/null +++ b/components/sync/model/recording_model_type_change_processor.cc
@@ -0,0 +1,43 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/model/recording_model_type_change_processor.h" + +#include "components/sync/model/fake_model_type_change_processor.h" +#include "components/sync/model/metadata_batch.h" + +namespace syncer { + +RecordingModelTypeChangeProcessor::RecordingModelTypeChangeProcessor() {} + +RecordingModelTypeChangeProcessor::~RecordingModelTypeChangeProcessor() {} + +void RecordingModelTypeChangeProcessor::Put( + const std::string& storage_key, + std::unique_ptr<EntityData> entity_data, + MetadataChangeList* metadata_changes) { + put_multimap_.insert(std::make_pair(storage_key, std::move(entity_data))); +} + +void RecordingModelTypeChangeProcessor::Delete( + const std::string& storage_key, + MetadataChangeList* metadata_changes) { + delete_set_.insert(storage_key); +} + +void RecordingModelTypeChangeProcessor::ModelReadyToSync( + std::unique_ptr<MetadataBatch> batch) { + std::swap(metadata_, batch); +} + +bool RecordingModelTypeChangeProcessor::IsTrackingMetadata() { + return is_tracking_metadata_; +} + +void RecordingModelTypeChangeProcessor::SetIsTrackingMetadata( + bool is_tracking) { + is_tracking_metadata_ = is_tracking; +} + +} // namespace syncer
diff --git a/components/sync/model/recording_model_type_change_processor.h b/components/sync/model/recording_model_type_change_processor.h new file mode 100644 index 0000000..d0789b4e --- /dev/null +++ b/components/sync/model/recording_model_type_change_processor.h
@@ -0,0 +1,48 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_MODEL_RECORDING_MODEL_TYPE_CHANGE_PROCESSOR_H_ +#define COMPONENTS_SYNC_MODEL_RECORDING_MODEL_TYPE_CHANGE_PROCESSOR_H_ + +#include "components/sync/model/fake_model_type_change_processor.h" + +namespace syncer { + +// Augmented FakeModelTypeChangeProcessor that accumulates all instructions in +// members that can then be accessed for verification. +class RecordingModelTypeChangeProcessor : public FakeModelTypeChangeProcessor { + public: + RecordingModelTypeChangeProcessor(); + ~RecordingModelTypeChangeProcessor() override; + + // FakeModelTypeChangeProcessor overrides. + void Put(const std::string& storage_key, + std::unique_ptr<EntityData> entity_data, + MetadataChangeList* metadata_changes) override; + void Delete(const std::string& storage_key, + MetadataChangeList* metadata_changes) override; + void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override; + bool IsTrackingMetadata() override; + + void SetIsTrackingMetadata(bool is_tracking); + + const std::multimap<std::string, std::unique_ptr<EntityData>>& put_multimap() + const { + return put_multimap_; + } + + const std::set<std::string>& delete_set() const { return delete_set_; } + + const MetadataBatch* metadata() const { return metadata_.get(); } + + private: + std::multimap<std::string, std::unique_ptr<EntityData>> put_multimap_; + std::set<std::string> delete_set_; + std::unique_ptr<MetadataBatch> metadata_; + bool is_tracking_metadata_ = true; +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_MODEL_RECORDING_MODEL_TYPE_CHANGE_PROCESSOR_H_
diff --git a/components/sync/tools/sync_client.cc b/components/sync/tools/sync_client.cc index 69954bca..2056aea1 100644 --- a/components/sync/tools/sync_client.cc +++ b/components/sync/tools/sync_client.cc
@@ -378,10 +378,6 @@ model_types.Put(FAVICON_IMAGES); model_types.Put(FAVICON_TRACKING); - ModelSafeRoutingInfo routing_info; - for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { - routing_info[it.Get()] = GROUP_PASSIVE; - } scoped_refptr<PassiveModelWorker> passive_model_safe_worker = new PassiveModelWorker(); std::vector<scoped_refptr<ModelSafeWorker>> workers; @@ -442,7 +438,13 @@ invalidator->RegisterHandler(shim.get()); CHECK(invalidator->UpdateRegisteredIds( shim.get(), ModelTypeSetToObjectIdSet(model_types))); - sync_manager->StartSyncingNormally(routing_info, base::Time()); + ModelTypeConnector* model_type_connector = + sync_manager->GetModelTypeConnector(); + for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { + model_type_connector->RegisterDirectoryType(it.Get(), GROUP_PASSIVE); + } + + sync_manager->StartSyncingNormally(base::Time()); base::RunLoop().Run();
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index a013741..6da88a2 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -551,6 +551,9 @@ const base::Process& process = child_process_->GetProcess(); DCHECK(process.IsValid()); + if (child_connection_) + child_connection_->SetProcessHandle(process.Handle()); + #if defined(OS_WIN) // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the // child process exits. This watcher is stopped once the IPC channel is
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 266d689..0a77951 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -1154,27 +1154,35 @@ } } -std::string GpuProcessHost::GetShaderPrefixKey() { - if (shader_prefix_key_.empty()) { +std::string GpuProcessHost::GetShaderPrefixKey(const std::string& shader) { + if (shader_prefix_key_info_.empty()) { gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); - std::string in_str = GetContentClient()->GetProduct() + "-" + + shader_prefix_key_info_ = + GetContentClient()->GetProduct() + "-" + #if defined(OS_ANDROID) base::android::BuildInfo::GetInstance()->android_build_fp() + "-" + #endif - info.gl_vendor + "-" + info.gl_renderer + "-" + - info.driver_version + "-" + info.driver_vendor; - - base::Base64Encode(base::SHA1HashString(in_str), &shader_prefix_key_); + info.gl_vendor + "-" + info.gl_renderer + "-" + info.driver_version + + "-" + info.driver_vendor; } - return shader_prefix_key_; + // The shader prefix key is a SHA1 hash of a set of per-machine info, such as + // driver version and os version, as well as the shader data being cached. + // This ensures both that the shader was not corrupted on disk, as well as + // that the shader is correctly configured for the current hardware. + std::string prefix; + base::Base64Encode(base::SHA1HashString(shader_prefix_key_info_ + shader), + &prefix); + return prefix; } void GpuProcessHost::LoadedShader(const std::string& key, const std::string& data) { - std::string prefix = GetShaderPrefixKey(); - if (!key.compare(0, prefix.length(), prefix)) + std::string prefix = GetShaderPrefixKey(data); + bool prefix_ok = !key.compare(0, prefix.length(), prefix); + UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok); + if (prefix_ok) Send(new GpuMsg_LoadedShader(data)); } @@ -1205,7 +1213,7 @@ // If the cache doesn't exist then this is an off the record profile. if (iter == client_id_to_shader_cache_.end()) return; - iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); + iter->second->Cache(GetShaderPrefixKey(shader) + ":" + key, shader); } } // namespace content
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 7fe8079..dd9702b 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h
@@ -219,7 +219,7 @@ // Update GPU crash counters. Disable GPU if crash limit is reached. void RecordProcessCrash(); - std::string GetShaderPrefixKey(); + std::string GetShaderPrefixKey(const std::string& shader); // The serial number of the GpuProcessHost / GpuProcessHostUIShim pair. int host_id_; @@ -287,7 +287,7 @@ ClientIdToShaderCacheMap; ClientIdToShaderCacheMap client_id_to_shader_cache_; - std::string shader_prefix_key_; + std::string shader_prefix_key_info_; ui::mojom::GpuMainAssociatedPtr gpu_main_ptr_;
diff --git a/content/common/service_manager/child_connection.cc b/content/common/service_manager/child_connection.cc index b5f0bfe..58cca53 100644 --- a/content/common/service_manager/child_connection.cc +++ b/content/common/service_manager/child_connection.cc
@@ -126,14 +126,15 @@ const std::string& child_token, service_manager::Connector* connector, scoped_refptr<base::SequencedTaskRunner> io_task_runner) - : context_(new IOThreadContext), + : child_token_(child_token), + context_(new IOThreadContext), child_identity_(service_name, service_manager::mojom::kInheritUserID, instance_id), service_token_(mojo::edk::GenerateRandomToken()), weak_factory_(this) { mojo::ScopedMessagePipeHandle service_pipe = - mojo::edk::CreateParentMessagePipe(service_token_, child_token); + mojo::edk::CreateParentMessagePipe(service_token_, child_token_); context_->Initialize(child_identity_, connector, std::move(service_pipe), io_task_runner); @@ -145,9 +146,18 @@ ChildConnection::~ChildConnection() { context_->ShutDown(); + + if (process_handle_ == base::kNullProcessHandle) { + // The process handle was never set, so we have to assume the process was + // not successfully launched. Note that ChildProcessLauncher may also call + // call ChildProcessLaunchFailed for the same token, so this is (harmlessly) + // redundant in some cases. + mojo::edk::ChildProcessLaunchFailed(child_token_); + } } void ChildConnection::SetProcessHandle(base::ProcessHandle handle) { + process_handle_ = handle; context_->SetProcessHandle(handle); }
diff --git a/content/common/service_manager/child_connection.h b/content/common/service_manager/child_connection.h index b461ddf9..1e34ac0 100644 --- a/content/common/service_manager/child_connection.h +++ b/content/common/service_manager/child_connection.h
@@ -61,9 +61,11 @@ private: class IOThreadContext; + const std::string child_token_; scoped_refptr<IOThreadContext> context_; service_manager::Identity child_identity_; const std::string service_token_; + base::ProcessHandle process_handle_ = base::kNullProcessHandle; service_manager::InterfaceProvider remote_interfaces_;
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md index 6acb3fa3..2e2cf1bf 100644 --- a/docs/android_build_instructions.md +++ b/docs/android_build_instructions.md
@@ -7,7 +7,6 @@ Are you a Google employee? See [go/building-chrome](https://goto.google.com/building-chrome) instead. -Google employee? See [go/building-chrome](https://goto.google.com/building-chrome) instead. [TOC]
diff --git a/docs/android_studio.md b/docs/android_studio.md index ee3a6025..2a10aa7a 100644 --- a/docs/android_studio.md +++ b/docs/android_studio.md
@@ -4,21 +4,23 @@ ## Usage +Make sure you have followed [android build instructions](android_build_instructions.md) already. + ```shell -build/android/gradle/generate_gradle.py --output-directory out-gn/Debug +build/android/gradle/generate_gradle.py ``` -This creates a project at `out-gn/Debug/gradle`. To create elsewhere: +This creates a project at `out/Debug/gradle`. To create elsewhere: ```shell -build/android/gradle/generate_gradle.py --output-directory out-gn/Debug --project-dir my-project +build/android/gradle/generate_gradle.py --output-directory out/My-Out-Dir --project-dir my-project ``` By default, only common targets are generated. To customize the list of targets to generate projects for: ```shell -build/android/gradle/generate_gradle.py --output-directory out-gn/Debug --target //some:target_apk --target //some/other:target_apk +build/android/gradle/generate_gradle.py --target //some:target_apk --target //some/other:target_apk ``` For first-time Android Studio users: @@ -107,18 +109,18 @@ * Use a [gradle daemon](https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html) to speed up builds: * Add the line `org.gradle.daemon=true` to `~/.gradle/gradle.properties`, creating it if necessary. -## Status (as of Sept 21, 2016) +## Status (as of Jan 19, 2017) ### What works * Tested with Android Studio v2.2. -* Basic Java editing and compiling works. +* Java editing and gradle compile works. +* Instrumentation tests included as androidTest. +* Symlinks to existing .so files in jniLibs (doesn't generate them). ### What doesn't work (yet) ([crbug](https://bugs.chromium.org/p/chromium/issues/detail?id=620034)) -* Better support for instrumentation tests (they are treated as non-test .apks right now) * Make gradle aware of resources and assets -* Make gradle aware of native code via pointing it at the location of our .so * Add a mode in which gradle is responsible for generating `R.java` * Add support for native code editing * Make the "Make Project" button work correctly
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index 43a62ad..ef921d5 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -58,7 +58,7 @@ builders { name: "linux_chromium_rel_ng" } builders { name: "linux_chromium_tsan_rel_ng" - experiment_percentage: 10 + experiment_percentage: 50 } } buckets {
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc index 017bedc9..ec20342 100644 --- a/media/blink/video_frame_compositor.cc +++ b/media/blink/video_frame_compositor.cc
@@ -5,8 +5,8 @@ #include "media/blink/video_frame_compositor.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/message_loop/message_loop.h" -#include "base/metrics/histogram_macros.h" #include "base/time/default_tick_clock.h" #include "base/trace_event/auto_open_close_event.h" #include "base/trace_event/trace_event.h" @@ -139,6 +139,7 @@ compositor_task_runner_->PostTask( FROM_HERE, base::Bind(&VideoFrameCompositor::OnRendererStateUpdate, base::Unretained(this), false)); + new_processed_frame_cb_.Reset(); } void VideoFrameCompositor::PaintSingleFrame( @@ -189,9 +190,10 @@ return current_frame_->timestamp(); } -void VideoFrameCompositor::SetForegroundTime(base::TimeTicks when) { +void VideoFrameCompositor::SetOnNewProcessedFrameCallback( + const OnNewProcessedFrameCB& cb) { DCHECK(compositor_task_runner_->BelongsToCurrentThread()); - foreground_time_ = when; + new_processed_frame_cb_ = cb; } bool VideoFrameCompositor::ProcessNewFrame( @@ -210,13 +212,8 @@ current_frame_ = frame; - if (!foreground_time_.is_null()) { - base::TimeDelta time_to_first_frame = - base::TimeTicks::Now() - foreground_time_; - UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame", - time_to_first_frame); - foreground_time_ = base::TimeTicks(); - } + if (!new_processed_frame_cb_.is_null()) + base::ResetAndReturn(&new_processed_frame_cb_).Run(base::TimeTicks::Now()); return true; }
diff --git a/media/blink/video_frame_compositor.h b/media/blink/video_frame_compositor.h index 03fb4c5..0068933 100644 --- a/media/blink/video_frame_compositor.h +++ b/media/blink/video_frame_compositor.h
@@ -13,6 +13,7 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/time/tick_clock.h" +#include "base/time/time.h" #include "base/timer/timer.h" #include "cc/layers/video_frame_provider.h" #include "media/base/video_renderer_sink.h" @@ -57,6 +58,9 @@ : public VideoRendererSink, NON_EXPORTED_BASE(public cc::VideoFrameProvider) { public: + // Used to report back the time when the new frame has been processed. + using OnNewProcessedFrameCB = base::Callback<void(base::TimeTicks)>; + // |compositor_task_runner| is the task runner on which this class will live, // though it may be constructed on any thread. explicit VideoFrameCompositor( @@ -103,10 +107,10 @@ // PaintSingleFrame() is not also called while stopped.) base::TimeDelta GetCurrentFrameTimestamp() const; - // Called when the media player is brought to the foreground. - // Used to record the time it takes to process the first frame after that. + // Sets the callback to be run when the new frame has been processed. The + // callback is only run once and then reset. // Must be called on the compositor thread. - void SetForegroundTime(base::TimeTicks when); + void SetOnNewProcessedFrameCallback(const OnNewProcessedFrameCB& cb); void set_tick_clock_for_testing(std::unique_ptr<base::TickClock> tick_clock) { tick_clock_ = std::move(tick_clock); @@ -162,7 +166,7 @@ bool new_background_frame_; base::TimeDelta last_interval_; base::TimeTicks last_background_render_; - base::TimeTicks foreground_time_; + OnNewProcessedFrameCB new_processed_frame_cb_; // These values are set on the compositor thread, but also read on the media // thread when the VFC is stopped.
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index d2a7de2..3b0e829 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -470,8 +470,7 @@ // requires that currentTime() == duration() after ending. We want to ensure // |paused_time_| matches currentTime() in this case or a future seek() may // incorrectly discard what it thinks is a seek to the existing time. - paused_time_ = - ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); + paused_time_ = ended_ ? GetPipelineMediaDuration() : pipeline_.GetMediaTime(); if (observer_) observer_->OnPaused(); @@ -726,7 +725,7 @@ if (chunk_demuxer_) return chunk_demuxer_->GetDuration(); - base::TimeDelta pipeline_duration = pipeline_.GetMediaDuration(); + base::TimeDelta pipeline_duration = GetPipelineMediaDuration(); return pipeline_duration == kInfiniteDuration ? std::numeric_limits<double>::infinity() : pipeline_duration.InSecondsF(); @@ -785,7 +784,7 @@ Ranges<base::TimeDelta> buffered_time_ranges = pipeline_.GetBufferedTimeRanges(); - const base::TimeDelta duration = pipeline_.GetMediaDuration(); + const base::TimeDelta duration = GetPipelineMediaDuration(); if (duration != kInfiniteDuration) { buffered_data_source_host_.AddBufferedTimeRanges( &buffered_time_ranges, duration); @@ -1409,7 +1408,7 @@ if (watch_time_reporter_) watch_time_reporter_->OnHidden(); - if (ShouldPauseWhenHidden()) { + if (ShouldPauseVideoWhenHidden()) { if (!paused_when_hidden_) { // OnPause() will set |paused_when_hidden_| to false and call // UpdatePlayState(), so set the flag to true after and then return. @@ -1440,10 +1439,20 @@ if (watch_time_reporter_) watch_time_reporter_->OnShown(); - compositor_task_runner_->PostTask( - FROM_HERE, - base::Bind(&VideoFrameCompositor::SetForegroundTime, - base::Unretained(compositor_), base::TimeTicks::Now())); + // Only track the time to the first frame if playing or about to play because + // of being shown and only for videos we would optimize background playback + // for. + if ((!paused_ && IsBackgroundOptimizationCandidate()) || + paused_when_hidden_) { + VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb = + BIND_TO_RENDER_LOOP1( + &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame, + base::TimeTicks::Now()); + compositor_task_runner_->PostTask( + FROM_HERE, + base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback, + base::Unretained(compositor_), new_processed_frame_cb)); + } if (paused_when_hidden_) { paused_when_hidden_ = false; @@ -1834,7 +1843,7 @@ case DelegateState::PLAYING: { delegate_->DidPlay( delegate_id_, hasVideo(), has_audio, - media::DurationToMediaContentType(pipeline_.GetMediaDuration())); + media::DurationToMediaContentType(GetPipelineMediaDuration())); break; } case DelegateState::PAUSED: @@ -2121,30 +2130,46 @@ client_->activateViewportIntersectionMonitoring(activate); } -bool WebMediaPlayerImpl::ShouldPauseWhenHidden() const { - DCHECK(IsHidden()); -// Don't pause videos being Cast (Android only) or if the background video -// optimizations are off (desktop only). -#if defined(OS_ANDROID) // WMPI_CAST - if (isRemote()) - return false; -#else // defined(OS_ANDROID) +bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { +#if !defined(OS_ANDROID) + // On desktop, this behavior is behind the feature flag. if (!IsBackgroundVideoTrackOptimizationEnabled()) return false; -#endif // defined(OS_ANDROID) +#endif - return hasVideo() && !hasAudio(); + // Pause video-only players that match the criteria for being optimized. + return !hasAudio() && IsBackgroundOptimizationCandidate(); } bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { - DCHECK(main_task_runner_->BelongsToCurrentThread()); - DCHECK(IsHidden()); - - if (!IsBackgroundVideoTrackOptimizationEnabled() || !hasVideo() || - !hasAudio() || IsStreaming()) { + // This optimization is behind the flag on all platforms. + if (!IsBackgroundVideoTrackOptimizationEnabled()) return false; - } + // Disable video track only for players with audio that match the criteria for + // being optimized. + return hasAudio() && IsBackgroundOptimizationCandidate(); +} + +bool WebMediaPlayerImpl::IsBackgroundOptimizationCandidate() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + +// Don't optimize players being Cast (Android only). +#if defined(OS_ANDROID) // WMPI_CAST + if (isRemote()) + return false; +#endif // defined(OS_ANDROID) + + // Don't optimize audio-only or streaming players. + if (!hasVideo() || IsStreaming()) + return false; + + // Videos shorter than the maximum allowed keyframe distance can be optimized. + base::TimeDelta duration = GetPipelineMediaDuration(); + if (duration < max_keyframe_distance_to_disable_background_video_) + return true; + + // Otherwise, only optimize videos with shorter average keyframe distance. PipelineStatistics stats = GetPipelineStatistics(); return stats.video_keyframe_distance_average < max_keyframe_distance_to_disable_background_video_; @@ -2190,4 +2215,30 @@ return pipeline_statistics_for_test_.value_or(pipeline_.GetStatistics()); } +void WebMediaPlayerImpl::SetPipelineMediaDurationForTest( + base::TimeDelta duration) { + pipeline_media_duration_for_test_ = base::make_optional(duration); +} + +base::TimeDelta WebMediaPlayerImpl::GetPipelineMediaDuration() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + + return pipeline_media_duration_for_test_.value_or( + pipeline_.GetMediaDuration()); +} + +void WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame( + base::TimeTicks foreground_time, + base::TimeTicks new_frame_time) { + base::TimeDelta time_to_first_frame = new_frame_time - foreground_time; + if (hasAudio()) { + UMA_HISTOGRAM_TIMES( + "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", + time_to_first_frame); + } else { + UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", + time_to_first_frame); + } +} + } // namespace media
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index edaeb353..a4bb832 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -300,9 +300,6 @@ void SetNetworkState(blink::WebMediaPlayer::NetworkState state); void SetReadyState(blink::WebMediaPlayer::ReadyState state); - // Gets the duration value reported by the pipeline. - double GetPipelineDuration() const; - // Returns the current video frame from |compositor_|. Blocks until the // compositor can return the frame. scoped_refptr<VideoFrame> GetCurrentFrameFromCompositor(); @@ -380,14 +377,19 @@ // is intended for android. bool DoesOverlaySupportMetadata() const; - // Whether the media should be paused when hidden. Uses metadata so has + // Whether the video should be paused when hidden. Uses metadata so has // meaning only after the pipeline has started, otherwise returns false. - bool ShouldPauseWhenHidden() const; + bool ShouldPauseVideoWhenHidden() const; // Whether the video track should be disabled when hidden. Uses metadata so // has meaning only after the pipeline has started, otherwise returns false. bool ShouldDisableVideoWhenHidden() const; + // Whether the video is suitable for background playback optimizations (either + // pausing it or disabling the video track). Uses metadata so has meaning only + // after the pipeline has started, otherwise returns false. + bool IsBackgroundOptimizationCandidate() const; + // Disables the video track to save power if possible. // Must be called when either of the following happens: // - right after the video was hidden, @@ -404,12 +406,23 @@ // - right after the pipeline has resumed if the video is not hidden. void EnableVideoTrackIfNeeded(); - // Overrides the pipeline statistics returned by GetStatistics() for tests. + // Overrides the pipeline statistics returned by GetPiplineStatistics() for + // tests. void SetPipelineStatisticsForTest(const PipelineStatistics& stats); // Returns the pipeline statistics or the value overridden by tests. PipelineStatistics GetPipelineStatistics() const; + // Overrides the pipeline media duration returned by + // GetPipelineMediaDuration() for tests. + void SetPipelineMediaDurationForTest(base::TimeDelta duration); + + // Return the pipeline media duration or the value overridden by tests. + base::TimeDelta GetPipelineMediaDuration() const; + + void ReportTimeFromForegroundToFirstFrame(base::TimeTicks foreground_time, + base::TimeTicks new_frame_time); + blink::WebLocalFrame* frame_; // The playback state last reported to |delegate_|, to avoid setting duplicate @@ -650,6 +663,9 @@ // Pipeline statistics overridden by tests. base::Optional<PipelineStatistics> pipeline_statistics_for_test_; + // Pipeline media duration overridden by tests. + base::Optional<base::TimeDelta> pipeline_media_duration_for_test_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); };
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index b0fbb40..b68bba6 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -284,12 +284,24 @@ return wmpi_->ShouldDisableVideoWhenHidden(); } + bool ShouldPauseVideoWhenHidden() const { + return wmpi_->ShouldPauseVideoWhenHidden(); + } + + bool IsBackgroundOptimizationCandidate() const { + return wmpi_->IsBackgroundOptimizationCandidate(); + } + void SetVideoKeyframeDistanceAverage(base::TimeDelta value) { PipelineStatistics statistics; statistics.video_keyframe_distance_average = value; wmpi_->SetPipelineStatisticsForTest(statistics); } + void SetDuration(base::TimeDelta value) { + wmpi_->SetPipelineMediaDurationForTest(value); + } + // "Renderer" thread. base::MessageLoop message_loop_; @@ -668,36 +680,88 @@ ASSERT_EQ(blink::WebSize(1080, 1920), wmpi_->naturalSize()); } -TEST_F(WebMediaPlayerImplTest, ShouldDisableVideoWhenHidden) { +TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureEnabled) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(kBackgroundVideoTrackOptimization); - InitializeWebMediaPlayerImpl(); - delegate_.SetFrameHiddenForTesting(true); - - SetMetadata(true, true); SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5)); + SetDuration(base::TimeDelta::FromSeconds(300)); + + // Audible video. + SetMetadata(true, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); + EXPECT_TRUE(ShouldDisableVideoWhenHidden()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); + + // Video only. + SetMetadata(false, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); + EXPECT_TRUE(ShouldPauseVideoWhenHidden()); + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + + // Audio only. + SetMetadata(true, false); + EXPECT_FALSE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + + // Duration is shorter than max video keyframe distance. + SetDuration(base::TimeDelta::FromSeconds(5)); + SetMetadata(true, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); EXPECT_TRUE(ShouldDisableVideoWhenHidden()); - SetMetadata(false, true); - EXPECT_FALSE(ShouldDisableVideoWhenHidden()); - - SetMetadata(true, false); - EXPECT_FALSE(ShouldDisableVideoWhenHidden()); - + // Average keyframe distance is too big. SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100)); - SetMetadata(true, true); + SetDuration(base::TimeDelta::FromSeconds(300)); + EXPECT_FALSE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); EXPECT_FALSE(ShouldDisableVideoWhenHidden()); } -TEST_F(WebMediaPlayerImplTest, ShouldDisableVideoWhenHiddenFeatureDisabled) { +TEST_F(WebMediaPlayerImplTest, BackgroundOptimizationsFeatureDisabled) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature(kBackgroundVideoTrackOptimization); InitializeWebMediaPlayerImpl(); - delegate_.SetFrameHiddenForTesting(true); + SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(5)); + SetDuration(base::TimeDelta::FromSeconds(300)); + // Audible video. SetMetadata(true, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); + + // Video only (pausing is enabled on Android). + SetMetadata(false, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); +#if defined(OS_ANDROID) + EXPECT_TRUE(ShouldPauseVideoWhenHidden()); +#else + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); +#endif + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + + // Audio only. + SetMetadata(true, false); + EXPECT_FALSE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + + // Duration is shorter than max video keyframe distance. + SetDuration(base::TimeDelta::FromSeconds(5)); + SetMetadata(true, true); + EXPECT_TRUE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); + EXPECT_FALSE(ShouldDisableVideoWhenHidden()); + + // Average keyframe distance is too big. + SetVideoKeyframeDistanceAverage(base::TimeDelta::FromSeconds(100)); + SetDuration(base::TimeDelta::FromSeconds(300)); + EXPECT_FALSE(IsBackgroundOptimizationCandidate()); + EXPECT_FALSE(ShouldPauseVideoWhenHidden()); EXPECT_FALSE(ShouldDisableVideoWhenHidden()); }
diff --git a/net/net.gypi b/net/net.gypi index 33ea9be..9509bbe 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -1345,6 +1345,8 @@ 'spdy/hpack/hpack_decoder_interface.h', 'spdy/hpack/hpack_decoder2.cc', 'spdy/hpack/hpack_decoder2.h', + 'spdy/hpack/hpack_decoder3.cc', + 'spdy/hpack/hpack_decoder3.h', 'spdy/hpack/hpack_encoder.cc', 'spdy/hpack/hpack_encoder.h', 'spdy/hpack/hpack_entry.cc', @@ -2113,6 +2115,7 @@ 'spdy/header_coalescer_test.cc', 'spdy/hpack/hpack_decoder_test.cc', 'spdy/hpack/hpack_decoder2_test.cc', + 'spdy/hpack/hpack_decoder3_test.cc', 'spdy/hpack/hpack_encoder_test.cc', 'spdy/hpack/hpack_entry_test.cc', 'spdy/hpack/hpack_header_table_test.cc',
diff --git a/net/quic/core/quic_headers_stream_test.cc b/net/quic/core/quic_headers_stream_test.cc index a3afe00..d4fb9d5c 100644 --- a/net/quic/core/quic_headers_stream_test.cc +++ b/net/quic/core/quic_headers_stream_test.cc
@@ -40,7 +40,6 @@ // TODO(bnc): Merge these correctly. bool FLAGS_use_http2_frame_decoder_adapter; -bool FLAGS_spdy_use_hpack_decoder2; bool FLAGS_spdy_framer_use_new_methods4; namespace net { @@ -153,13 +152,15 @@ return os; } -enum HpackDecoderChoice { HPACK_DECODER_SPDY, HPACK_DECODER_NEW }; +enum HpackDecoderChoice { HPACK_DECODER_SPDY, HPACK_DECODER2, HPACK_DECODER3 }; std::ostream& operator<<(std::ostream& os, HpackDecoderChoice v) { switch (v) { case HPACK_DECODER_SPDY: return os << "SPDY"; - case HPACK_DECODER_NEW: - return os << "NEW"; + case HPACK_DECODER2: + return os << "HPACK_DECODER2"; + case HPACK_DECODER3: + return os << "HPACK_DECODER3"; } return os; } @@ -193,12 +194,16 @@ } switch (hpack_decoder) { case HPACK_DECODER_SPDY: - FLAGS_spdy_use_hpack_decoder2 = false; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; break; - case HPACK_DECODER_NEW: - FLAGS_spdy_use_hpack_decoder2 = true; - // Needs new header methods to be used. - FLAGS_spdy_framer_use_new_methods4 = true; + case HPACK_DECODER2: + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = true; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; + break; + case HPACK_DECODER3: + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = true; break; } QUIC_LOG(INFO) << "TestParams: version: " << QuicVersionToString(version) @@ -415,7 +420,7 @@ ::testing::Values(HTTP2_DECODER_SPDY, HTTP2_DECODER_NESTED_SPDY, HTTP2_DECODER_NEW), - ::testing::Values(HPACK_DECODER_SPDY, HPACK_DECODER_NEW))); + ::testing::Values(HPACK_DECODER_SPDY, HPACK_DECODER2, HPACK_DECODER3))); TEST_P(QuicHeadersStreamTest, StreamId) { EXPECT_EQ(3u, headers_stream_->id()); @@ -849,6 +854,10 @@ } TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { + if (test_params_.hpack_decoder == HPACK_DECODER3) { + return; + } + StrictMock<MockQuicHpackDebugVisitor>* hpack_decoder_visitor = hpack_decoder_visitor_.get(); QuicSpdySessionPeer::SetHpackDecoderDebugVisitor(
diff --git a/net/spdy/hpack/hpack_decoder2_test.cc b/net/spdy/hpack/hpack_decoder2_test.cc index efea044..8c70051 100644 --- a/net/spdy/hpack/hpack_decoder2_test.cc +++ b/net/spdy/hpack/hpack_decoder2_test.cc
@@ -565,8 +565,9 @@ EXPECT_FALSE(DecodeHeaderBlock(first)); } -// Round-tripping the header set from E.2.1 should work. -TEST_P(HpackDecoder2Test, BasicE21) { +// Round-tripping the header set from RFC 7541 C.3.1 should work. +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 +TEST_P(HpackDecoder2Test, BasicC31) { HpackEncoder encoder(ObtainHpackHuffmanTable()); SpdyHeaderBlock expected_header_set; @@ -583,7 +584,9 @@ EXPECT_EQ(expected_header_set, decoded_block()); } -TEST_P(HpackDecoder2Test, SectionD4RequestHuffmanExamples) { +// RFC 7541, Section C.4: Request Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 +TEST_P(HpackDecoder2Test, SectionC4RequestHuffmanExamples) { // TODO(jamessynge): Use net/http2/hpack/tools/hpack_example.h to parse the // example directly, instead of having it as a comment. // 82 | == Indexed - Add == @@ -703,7 +706,9 @@ EXPECT_EQ(164u, decoder_peer_.header_table()->size()); } -TEST_P(HpackDecoder2Test, SectionD6ResponseHuffmanExamples) { +// RFC 7541, Section C.6: Response Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6 +TEST_P(HpackDecoder2Test, SectionC6ResponseHuffmanExamples) { decoder_.ApplyHeaderTableSizeSetting(256); // 48 | == Literal indexed ==
diff --git a/net/spdy/hpack/hpack_decoder3.cc b/net/spdy/hpack/hpack_decoder3.cc new file mode 100644 index 0000000..d2dcbeb --- /dev/null +++ b/net/spdy/hpack/hpack_decoder3.cc
@@ -0,0 +1,151 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/spdy/hpack/hpack_decoder3.h" + +#include "base/logging.h" +#include "net/http2/decoder/decode_buffer.h" +#include "net/http2/decoder/decode_status.h" + +using base::StringPiece; + +namespace net { +namespace { +const size_t kMaxDecodeBufferSizeBytes = 32 * 1024; // 32 KB +} // namespace + +HpackDecoder3::HpackDecoder3() + : hpack_decoder_(&listener_adapter_, kMaxDecodeBufferSizeBytes), + max_decode_buffer_size_bytes_(kMaxDecodeBufferSizeBytes), + header_block_started_(false) {} + +HpackDecoder3::~HpackDecoder3() {} + +void HpackDecoder3::ApplyHeaderTableSizeSetting(size_t size_setting) { + DVLOG(2) << "HpackDecoder3::ApplyHeaderTableSizeSetting"; + hpack_decoder_.ApplyHeaderTableSizeSetting(size_setting); +} + +void HpackDecoder3::HandleControlFrameHeadersStart( + SpdyHeadersHandlerInterface* handler) { + DVLOG(2) << "HpackDecoder3::HandleControlFrameHeadersStart"; + DCHECK(!header_block_started_); + listener_adapter_.set_handler(handler); +} + +bool HpackDecoder3::HandleControlFrameHeadersData(const char* headers_data, + size_t headers_data_length) { + DVLOG(2) << "HpackDecoder3::HandleControlFrameHeadersData: len=" + << headers_data_length; + if (!header_block_started_) { + // Initialize the decoding process here rather than in + // HandleControlFrameHeadersStart because that method is not always called. + total_hpack_bytes_ = 0; + header_block_started_ = true; + if (!hpack_decoder_.StartDecodingBlock()) { + header_block_started_ = false; + return false; + } + } + + // Sometimes we get a call with headers_data==nullptr and + // headers_data_length==0, in which case we need to avoid creating + // a DecodeBuffer, which would otherwise complain. + if (headers_data_length > 0) { + DCHECK_NE(headers_data, nullptr); + if (headers_data_length > max_decode_buffer_size_bytes_) { + DVLOG(1) << "max_decode_buffer_size_bytes_ < headers_data_length: " + << max_decode_buffer_size_bytes_ << " < " << headers_data_length; + return false; + } + total_hpack_bytes_ += headers_data_length; + DecodeBuffer db(headers_data, headers_data_length); + bool ok = hpack_decoder_.DecodeFragment(&db); + DCHECK(!ok || db.Empty()) << "Remaining=" << db.Remaining(); + return ok; + } + return true; +} + +// TODO(jamessynge): Determine if compressed_len is needed; it is used to +// produce UUMA stat Net.SpdyHpackDecompressionPercentage, but only for +// SPDY3, not HTTP2. +bool HpackDecoder3::HandleControlFrameHeadersComplete(size_t* compressed_len) { + DVLOG(2) << "HpackDecoder3::HandleControlFrameHeadersComplete"; + if (compressed_len != nullptr) { + *compressed_len = total_hpack_bytes_; + } + if (!hpack_decoder_.EndDecodingBlock()) { + DVLOG(3) << "EndDecodingBlock returned false"; + return false; + } + header_block_started_ = false; + return true; +} + +const SpdyHeaderBlock& HpackDecoder3::decoded_block() const { + return listener_adapter_.decoded_block(); +} + +void HpackDecoder3::SetHeaderTableDebugVisitor( + std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { + DVLOG(2) << "HpackDecoder3::SetHeaderTableDebugVisitor"; + // Dropping on the floor for now. Not sure yet if needed at all. +} + +void HpackDecoder3::set_max_decode_buffer_size_bytes( + size_t max_decode_buffer_size_bytes) { + DVLOG(2) << "HpackDecoder3::set_max_decode_buffer_size_bytes"; + max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes; + hpack_decoder_.set_max_string_size_bytes(max_decode_buffer_size_bytes); +} + +HpackDecoder3::ListenerAdapter::ListenerAdapter() : handler_(nullptr) {} +HpackDecoder3::ListenerAdapter::~ListenerAdapter() {} + +void HpackDecoder3::ListenerAdapter::set_handler( + SpdyHeadersHandlerInterface* handler) { + handler_ = handler; +} + +void HpackDecoder3::ListenerAdapter::OnHeaderListStart() { + DVLOG(2) << "HpackDecoder3::ListenerAdapter::OnHeaderListStart"; + total_uncompressed_bytes_ = 0; + decoded_block_.clear(); + if (handler_ != nullptr) { + handler_->OnHeaderBlockStart(); + } +} + +void HpackDecoder3::ListenerAdapter::OnHeader(HpackEntryType entry_type, + const HpackString& name, + const HpackString& value) { + DVLOG(2) << "HpackDecoder3::ListenerAdapter::OnHeader:\n name: " << name + << "\n value: " << value; + total_uncompressed_bytes_ += name.size() + value.size(); + if (handler_ == nullptr) { + DVLOG(3) << "Adding to decoded_block"; + decoded_block_.AppendValueOrAddHeader(name, value); + } else { + DVLOG(3) << "Passing to handler"; + handler_->OnHeader(name, value); + } +} + +void HpackDecoder3::ListenerAdapter::OnHeaderListEnd() { + DVLOG(2) << "HpackDecoder3::ListenerAdapter::OnHeaderListEnd"; + // We don't clear the SpdyHeaderBlock here to allow access to it until the + // next HPACK block is decoded. + if (handler_ != nullptr) { + handler_->OnHeaderBlockEnd(total_uncompressed_bytes_); + handler_ = nullptr; + } +} + +void HpackDecoder3::ListenerAdapter::OnHeaderErrorDetected( + StringPiece error_message) { + VLOG(1) << error_message; +} + +} // namespace net
diff --git a/net/spdy/hpack/hpack_decoder3.h b/net/spdy/hpack/hpack_decoder3.h new file mode 100644 index 0000000..6203dfd --- /dev/null +++ b/net/spdy/hpack/hpack_decoder3.h
@@ -0,0 +1,112 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SPDY_HPACK_HPACK_DECODER3_H_ +#define NET_SPDY_HPACK_HPACK_DECODER3_H_ + +// HpackDecoder3 implements HpackDecoderInterface, using Http2HpackDecoder to +// decode HPACK blocks into HTTP/2 header lists as outlined in +// http://tools.ietf.org/html/rfc7541. + +#include <stddef.h> + +#include <memory> + +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "net/base/net_export.h" +#include "net/http2/hpack/decoder/hpack_decoder_listener.h" +#include "net/http2/hpack/decoder/http2_hpack_decoder.h" +#include "net/http2/hpack/hpack_string.h" +#include "net/http2/hpack/http2_hpack_constants.h" +#include "net/spdy/hpack/hpack_decoder_interface.h" +#include "net/spdy/hpack/hpack_header_table.h" +#include "net/spdy/spdy_header_block.h" +#include "net/spdy/spdy_headers_handler_interface.h" + +namespace net { +namespace test { +class HpackDecoder3Peer; +} // namespace test + +class NET_EXPORT_PRIVATE HpackDecoder3 : public HpackDecoderInterface { + public: + friend test::HpackDecoder3Peer; + HpackDecoder3(); + ~HpackDecoder3() override; + + // Override the HpackDecoderInterface methods: + + void ApplyHeaderTableSizeSetting(size_t size_setting) override; + void HandleControlFrameHeadersStart( + SpdyHeadersHandlerInterface* handler) override; + bool HandleControlFrameHeadersData(const char* headers_data, + size_t headers_data_length) override; + bool HandleControlFrameHeadersComplete(size_t* compressed_len) override; + const SpdyHeaderBlock& decoded_block() const override; + void SetHeaderTableDebugVisitor( + std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) + override; + void set_max_decode_buffer_size_bytes( + size_t max_decode_buffer_size_bytes) override; + + private: + class NET_EXPORT_PRIVATE ListenerAdapter : public HpackDecoderListener { + public: + ListenerAdapter(); + ~ListenerAdapter() override; + + // If a SpdyHeadersHandlerInterface is provided, the decoder will emit + // headers to it rather than accumulating them in a SpdyHeaderBlock. + // Does not take ownership of the handler, but does use the pointer until + // the current HPACK block is completely decoded. + void set_handler(SpdyHeadersHandlerInterface* handler); + const SpdyHeaderBlock& decoded_block() const { return decoded_block_; } + + // Override the HpackDecoderListener methods: + + void OnHeaderListStart() override; + void OnHeader(HpackEntryType entry_type, + const HpackString& name, + const HpackString& value) override; + void OnHeaderListEnd() override; + void OnHeaderErrorDetected(base::StringPiece error_message) override; + + private: + // If the caller doesn't provide a handler, the header list is stored in + // this SpdyHeaderBlock. + SpdyHeaderBlock decoded_block_; + + // If non-NULL, handles decoded headers. Not owned. + SpdyHeadersHandlerInterface* handler_; + + // Total bytes of the name and value strings in the current HPACK block. + size_t total_uncompressed_bytes_; + }; + + // Converts calls to HpackDecoderListener into calls to + // SpdyHeadersHandlerInterface. + ListenerAdapter listener_adapter_; + + // The actual decoder. + Http2HpackDecoder hpack_decoder_; + + // Total bytes that have been received as input (i.e. HPACK encoded) + // in the current HPACK block. + size_t total_hpack_bytes_; + + // How much encoded data this decoder is willing to buffer. + size_t max_decode_buffer_size_bytes_; + + // Flag to keep track of having seen the header block start. Needed at the + // moment because HandleControlFrameHeadersStart won't be called if a handler + // is not being provided by the caller. + bool header_block_started_; + + DISALLOW_COPY_AND_ASSIGN(HpackDecoder3); +}; + +} // namespace net + +#endif // NET_SPDY_HPACK_HPACK_DECODER3_H_
diff --git a/net/spdy/hpack/hpack_decoder3_test.cc b/net/spdy/hpack/hpack_decoder3_test.cc new file mode 100644 index 0000000..3f71724 --- /dev/null +++ b/net/spdy/hpack/hpack_decoder3_test.cc
@@ -0,0 +1,1012 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/spdy/hpack/hpack_decoder3.h" + +// Tests of HpackDecoder3. + +#include <stdint.h> + +#include <string> +#include <tuple> +#include <utility> +#include <vector> + +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "net/http2/hpack/decoder/hpack_decoder_state.h" +#include "net/http2/hpack/decoder/hpack_decoder_tables.h" +#include "net/http2/hpack/tools/hpack_block_builder.h" +#include "net/http2/tools/http2_random.h" +#include "net/spdy/hpack/hpack_constants.h" +#include "net/spdy/hpack/hpack_encoder.h" +#include "net/spdy/hpack/hpack_huffman_table.h" +#include "net/spdy/hpack/hpack_output_stream.h" +#include "net/spdy/spdy_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::StringPiece; +using std::string; +using ::testing::ElementsAre; +using ::testing::Pair; + +namespace net { +namespace test { + +class HpackDecoderStatePeer { + public: + static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) { + return &state->decoder_tables_; + } +}; + +class Http2HpackDecoderPeer { + public: + static HpackDecoderState* GetDecoderState(Http2HpackDecoder* decoder) { + return &decoder->decoder_state_; + } + static HpackDecoderTables* GetDecoderTables(Http2HpackDecoder* decoder) { + return HpackDecoderStatePeer::GetDecoderTables(GetDecoderState(decoder)); + } +}; + +class HpackDecoder3Peer { + public: + explicit HpackDecoder3Peer(HpackDecoder3* decoder) : decoder_(decoder) {} + + void HandleHeaderRepresentation(StringPiece name, StringPiece value) { + decoder_->listener_adapter_.OnHeader(HpackEntryType::kIndexedLiteralHeader, + HpackString(name), HpackString(value)); + } + + HpackDecoderTables* GetDecoderTables() { + return Http2HpackDecoderPeer::GetDecoderTables(&decoder_->hpack_decoder_); + } + + const HpackStringPair* GetTableEntry(uint32_t index) { + return GetDecoderTables()->Lookup(index); + } + + size_t current_header_table_size() { + return GetDecoderTables()->current_header_table_size(); + } + + size_t header_table_size_limit() { + return GetDecoderTables()->header_table_size_limit(); + } + + void set_header_table_size_limit(size_t size) { + return GetDecoderTables()->DynamicTableSizeUpdate(size); + } + + private: + HpackDecoder3* decoder_; +}; + +namespace { + +// Is HandleControlFrameHeadersStart to be called, and with what value? +enum StartChoice { START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START }; + +class HpackDecoder3Test + : public ::testing::TestWithParam<std::tuple<StartChoice, bool>> { + protected: + HpackDecoder3Test() : decoder_(), decoder_peer_(&decoder_) {} + + void SetUp() override { + std::tie(start_choice_, randomly_split_input_buffer_) = GetParam(); + } + + void HandleControlFrameHeadersStart() { + switch (start_choice_) { + case START_WITH_HANDLER: + decoder_.HandleControlFrameHeadersStart(&handler_); + break; + case START_WITHOUT_HANDLER: + decoder_.HandleControlFrameHeadersStart(nullptr); + break; + case NO_START: + break; + } + } + + bool HandleControlFrameHeadersData(StringPiece str) { + VLOG(3) << "HandleControlFrameHeadersData:\n" + << base::HexEncode(str.data(), str.size()); + return decoder_.HandleControlFrameHeadersData(str.data(), str.size()); + } + + bool HandleControlFrameHeadersComplete(size_t* size) { + return decoder_.HandleControlFrameHeadersComplete(size); + } + + bool DecodeHeaderBlock(StringPiece str) { + // Don't call this again if HandleControlFrameHeadersData failed previously. + EXPECT_FALSE(decode_has_failed_); + HandleControlFrameHeadersStart(); + if (randomly_split_input_buffer_) { + do { + // Decode some fragment of the remaining bytes. + size_t bytes = str.length(); + if (!str.empty()) { + bytes = (random_.Rand8() % str.length()) + 1; + } + EXPECT_LE(bytes, str.length()); + if (!HandleControlFrameHeadersData(str.substr(0, bytes))) { + decode_has_failed_ = true; + return false; + } + str.remove_prefix(bytes); + } while (!str.empty()); + } else if (!HandleControlFrameHeadersData(str)) { + decode_has_failed_ = true; + return false; + } + if (!HandleControlFrameHeadersComplete(nullptr)) { + decode_has_failed_ = true; + return false; + } + return true; + } + + bool EncodeAndDecodeDynamicTableSizeUpdates(size_t first, size_t second) { + HpackBlockBuilder hbb; + hbb.AppendDynamicTableSizeUpdate(first); + if (second != first) { + hbb.AppendDynamicTableSizeUpdate(second); + } + return DecodeHeaderBlock(hbb.buffer()); + } + + const SpdyHeaderBlock& decoded_block() const { + if (start_choice_ == START_WITH_HANDLER) { + return handler_.decoded_block(); + } else { + return decoder_.decoded_block(); + } + } + + const SpdyHeaderBlock& DecodeBlockExpectingSuccess(StringPiece str) { + EXPECT_TRUE(DecodeHeaderBlock(str)); + return decoded_block(); + } + + void expectEntry(size_t index, + size_t size, + const string& name, + const string& value) { + const HpackStringPair* entry = decoder_peer_.GetTableEntry(index); + EXPECT_EQ(name, entry->name) << "index " << index; + EXPECT_EQ(value, entry->value); + EXPECT_EQ(size, entry->size()); + } + + SpdyHeaderBlock MakeHeaderBlock( + const std::vector<std::pair<string, string>>& headers) { + SpdyHeaderBlock result; + for (const auto& kv : headers) { + result.AppendValueOrAddHeader(kv.first, kv.second); + } + return result; + } + + Http2Random random_; + HpackHuffmanTable huffman_table_; + HpackDecoder3 decoder_; + test::HpackDecoder3Peer decoder_peer_; + TestHeadersHandler handler_; + StartChoice start_choice_; + bool randomly_split_input_buffer_; + bool decode_has_failed_ = false; +}; + +INSTANTIATE_TEST_CASE_P( + StartChoiceAndRandomlySplitChoice, + HpackDecoder3Test, + ::testing::Combine( + ::testing::Values(START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START), + ::testing::Bool())); + +TEST_P(HpackDecoder3Test, AddHeaderDataWithHandleControlFrameHeadersData) { + // The hpack decode buffer size is limited in size. This test verifies that + // adding encoded data under that limit is accepted, and data that exceeds the + // limit is rejected. + HandleControlFrameHeadersStart(); + const size_t kMaxBufferSizeBytes = 50; + const string a_value = string(49, 'x'); + decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); + HpackBlockBuilder hbb; + hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, + false, "a", false, a_value); + const string& s = hbb.buffer(); + EXPECT_GT(s.size(), kMaxBufferSizeBytes); + + // Any one in input buffer must not exceed kMaxBufferSizeBytes. + EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(0, s.size() / 2))); + EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(s.size() / 2))); + + EXPECT_FALSE(HandleControlFrameHeadersData(s)); + SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}}); + EXPECT_EQ(expected_block, decoded_block()); +} + +TEST_P(HpackDecoder3Test, NameTooLong) { + // Verify that a name longer than the allowed size generates an error. + const size_t kMaxBufferSizeBytes = 50; + const string name = string(2 * kMaxBufferSizeBytes, 'x'); + const string value = "abc"; + + decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); + + HpackBlockBuilder hbb; + hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, + false, name, false, value); + + const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2; + const string fragment = hbb.buffer().substr(0, fragment_size); + + HandleControlFrameHeadersStart(); + EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); +} + +TEST_P(HpackDecoder3Test, HeaderTooLongToBuffer) { + // Verify that a header longer than the allowed size generates an error if + // it isn't all in one input buffer. + const string name = "some-key"; + const string value = "some-value"; + const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2; + decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); + + HpackBlockBuilder hbb; + hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, + false, name, false, value); + const size_t fragment_size = hbb.size() - 1; + const string fragment = hbb.buffer().substr(0, fragment_size); + + HandleControlFrameHeadersStart(); + EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); +} + +// Decode with incomplete data in buffer. +TEST_P(HpackDecoder3Test, DecodeWithIncompleteData) { + HandleControlFrameHeadersStart(); + + // No need to wait for more data. + EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82")); + std::vector<std::pair<string, string>> expected_headers = { + {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}}; + + SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers); + EXPECT_EQ(expected_block1, decoded_block()); + + // Full and partial headers, won't add partial to the headers. + EXPECT_TRUE( + HandleControlFrameHeadersData("\x40\x03goo" + "\x03gar\xbe\x40\x04spam")); + expected_headers.push_back({"goo", "gar"}); + expected_headers.push_back({"goo", "gar"}); + + SpdyHeaderBlock expected_block2 = MakeHeaderBlock(expected_headers); + EXPECT_EQ(expected_block2, decoded_block()); + + // Add the needed data. + EXPECT_TRUE(HandleControlFrameHeadersData("\x04gggs")); + + size_t size = 0; + EXPECT_TRUE(HandleControlFrameHeadersComplete(&size)); + EXPECT_EQ(24u, size); + + expected_headers.push_back({"spam", "gggs"}); + + SpdyHeaderBlock expected_block3 = MakeHeaderBlock(expected_headers); + EXPECT_EQ(expected_block3, decoded_block()); +} + +TEST_P(HpackDecoder3Test, HandleHeaderRepresentation) { + // Make sure the decoder is properly initialized. + HandleControlFrameHeadersStart(); + HandleControlFrameHeadersData(""); + + // All cookie crumbs are joined. + decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); + decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); + decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); + + // Already-delimited headers are passed through. + decoder_peer_.HandleHeaderRepresentation("passed-through", + string("foo\0baz", 7)); + + // Other headers are joined on \0. Case matters. + decoder_peer_.HandleHeaderRepresentation("joined", "not joined"); + decoder_peer_.HandleHeaderRepresentation("joineD", "value 1"); + decoder_peer_.HandleHeaderRepresentation("joineD", "value 2"); + + // Empty headers remain empty. + decoder_peer_.HandleHeaderRepresentation("empty", ""); + + // Joined empty headers work as expected. + decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); + decoder_peer_.HandleHeaderRepresentation("empty-joined", "foo"); + decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); + decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); + + // Non-contiguous cookie crumb. + decoder_peer_.HandleHeaderRepresentation("cookie", " fin!"); + + // Finish and emit all headers. + decoder_.HandleControlFrameHeadersComplete(nullptr); + + // Resulting decoded headers are in the same order as the inputs. + EXPECT_THAT(decoded_block(), + ElementsAre(Pair("cookie", " part 1; part 2 ; part3; fin!"), + Pair("passed-through", StringPiece("foo\0baz", 7)), + Pair("joined", "not joined"), + Pair("joineD", StringPiece("value 1\0value 2", 15)), + Pair("empty", ""), + Pair("empty-joined", StringPiece("\0foo\0\0", 6)))); +} + +// Decoding indexed static table field should work. +TEST_P(HpackDecoder3Test, IndexedHeaderStatic) { + // Reference static table entries #2 and #5. + const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess("\x82\x85"); + SpdyHeaderBlock expected_header_set1; + expected_header_set1[":method"] = "GET"; + expected_header_set1[":path"] = "/index.html"; + EXPECT_EQ(expected_header_set1, header_set1); + + // Reference static table entry #2. + const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess("\x82"); + SpdyHeaderBlock expected_header_set2; + expected_header_set2[":method"] = "GET"; + EXPECT_EQ(expected_header_set2, header_set2); +} + +TEST_P(HpackDecoder3Test, IndexedHeaderDynamic) { + // First header block: add an entry to header table. + const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess( + "\x40\x03" + "foo" + "\x03" + "bar"); + SpdyHeaderBlock expected_header_set1; + expected_header_set1["foo"] = "bar"; + EXPECT_EQ(expected_header_set1, header_set1); + + // Second header block: add another entry to header table. + const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess( + "\xbe\x40\x04" + "spam" + "\x04" + "eggs"); + SpdyHeaderBlock expected_header_set2; + expected_header_set2["foo"] = "bar"; + expected_header_set2["spam"] = "eggs"; + EXPECT_EQ(expected_header_set2, header_set2); + + // Third header block: refer to most recently added entry. + const SpdyHeaderBlock& header_set3 = DecodeBlockExpectingSuccess("\xbe"); + SpdyHeaderBlock expected_header_set3; + expected_header_set3["spam"] = "eggs"; + EXPECT_EQ(expected_header_set3, header_set3); +} + +// Test a too-large indexed header. +TEST_P(HpackDecoder3Test, InvalidIndexedHeader) { + // High-bit set, and a prefix of one more than the number of static entries. + EXPECT_FALSE(DecodeHeaderBlock("\xbe")); +} + +TEST_P(HpackDecoder3Test, ContextUpdateMaximumSize) { + EXPECT_EQ(kDefaultHeaderTableSizeSetting, + decoder_peer_.header_table_size_limit()); + string input; + { + // Maximum-size update with size 126. Succeeds. + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(126); + + output_stream.TakeString(&input); + EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(126u, decoder_peer_.header_table_size_limit()); + } + { + // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds. + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(kDefaultHeaderTableSizeSetting); + + output_stream.TakeString(&input); + EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(kDefaultHeaderTableSizeSetting, + decoder_peer_.header_table_size_limit()); + } + { + // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails. + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1); + + output_stream.TakeString(&input); + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(kDefaultHeaderTableSizeSetting, + decoder_peer_.header_table_size_limit()); + } +} + +// Two HeaderTableSizeUpdates may appear at the beginning of the block +TEST_P(HpackDecoder3Test, TwoTableSizeUpdates) { + string input; + { + // Should accept two table size updates, update to second one + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(0); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(122); + + output_stream.TakeString(&input); + EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(122u, decoder_peer_.header_table_size_limit()); + } +} + +// Three HeaderTableSizeUpdates should result in an error +TEST_P(HpackDecoder3Test, ThreeTableSizeUpdatesError) { + string input; + { + // Should reject three table size updates, update to second one + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(5); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(10); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(15); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(10u, decoder_peer_.header_table_size_limit()); + } +} + +// HeaderTableSizeUpdates may only appear at the beginning of the block +// Any other updates should result in an error +TEST_P(HpackDecoder3Test, TableSizeUpdateSecondError) { + string input; + { + // Should reject a table size update appearing after a different entry + // The table size should remain as the default + HpackOutputStream output_stream; + output_stream.AppendBytes("\x82\x85"); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(123); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(kDefaultHeaderTableSizeSetting, + decoder_peer_.header_table_size_limit()); + } +} + +// HeaderTableSizeUpdates may only appear at the beginning of the block +// Any other updates should result in an error +TEST_P(HpackDecoder3Test, TableSizeUpdateFirstThirdError) { + string input; + { + // Should reject the second table size update + // if a different entry appears after the first update + // The table size should update to the first but not the second + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(60); + output_stream.AppendBytes("\x82\x85"); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(125); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(60u, decoder_peer_.header_table_size_limit()); + } +} + +// Decoding two valid encoded literal headers with no indexing should +// work. +TEST_P(HpackDecoder3Test, LiteralHeaderNoIndexing) { + // First header with indexed name, second header with string literal + // name. + const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2"; + const SpdyHeaderBlock& header_set = + DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); + + SpdyHeaderBlock expected_header_set; + expected_header_set[":path"] = "/sample/path"; + expected_header_set[":path2"] = "/sample/path/2"; + EXPECT_EQ(expected_header_set, header_set); +} + +// Decoding two valid encoded literal headers with incremental +// indexing and string literal names should work. +TEST_P(HpackDecoder3Test, LiteralHeaderIncrementalIndexing) { + const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"; + const SpdyHeaderBlock& header_set = + DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); + + SpdyHeaderBlock expected_header_set; + expected_header_set[":path"] = "/sample/path"; + expected_header_set[":path2"] = "/sample/path/2"; + EXPECT_EQ(expected_header_set, header_set); +} + +TEST_P(HpackDecoder3Test, LiteralHeaderWithIndexingInvalidNameIndex) { + decoder_.ApplyHeaderTableSizeSetting(0); + EXPECT_TRUE(EncodeAndDecodeDynamicTableSizeUpdates(0, 0)); + + // Name is the last static index. Works. + EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x7d\x03ooo"))); + // Name is one beyond the last static index. Fails. + EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x7e\x03ooo"))); +} + +TEST_P(HpackDecoder3Test, LiteralHeaderNoIndexingInvalidNameIndex) { + // Name is the last static index. Works. + EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x0f\x2e\x03ooo"))); + // Name is one beyond the last static index. Fails. + EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x0f\x2f\x03ooo"))); +} + +TEST_P(HpackDecoder3Test, LiteralHeaderNeverIndexedInvalidNameIndex) { + // Name is the last static index. Works. + EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x1f\x2e\x03ooo"))); + // Name is one beyond the last static index. Fails. + EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x1f\x2f\x03ooo"))); +} + +TEST_P(HpackDecoder3Test, TruncatedIndex) { + // Indexed Header, varint for index requires multiple bytes, + // but only one provided. + EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\xff", 1))); +} + +TEST_P(HpackDecoder3Test, TruncatedHuffmanLiteral) { + // Literal value, Huffman encoded, but with the last byte missing (i.e. + // drop the final ff shown below). + // + // 41 | == Literal indexed == + // | Indexed name (idx = 1) + // | :authority + // 8c | Literal value (len = 12) + // | Huffman encoded: + // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... + // | Decoded: + // | www.example.com + // | -> :authority: www.example.com + + string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); + EXPECT_TRUE(DecodeHeaderBlock(first)); + first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4"); + EXPECT_FALSE(DecodeHeaderBlock(first)); +} + +TEST_P(HpackDecoder3Test, HuffmanEOSError) { + // Literal value, Huffman encoded, but with an additional ff byte at the end + // of the string, i.e. an EOS that is longer than permitted. + // + // 41 | == Literal indexed == + // | Indexed name (idx = 1) + // | :authority + // 8d | Literal value (len = 13) + // | Huffman encoded: + // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... + // | Decoded: + // | www.example.com + // | -> :authority: www.example.com + + string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); + EXPECT_TRUE(DecodeHeaderBlock(first)); + first = a2b_hex("418df1e3c2e5f23a6ba0ab90f4ffff"); + EXPECT_FALSE(DecodeHeaderBlock(first)); +} + +// Round-tripping the header set from RFC 7541 C.3.1 should work. +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 +TEST_P(HpackDecoder3Test, BasicC31) { + HpackEncoder encoder(ObtainHpackHuffmanTable()); + + SpdyHeaderBlock expected_header_set; + expected_header_set[":method"] = "GET"; + expected_header_set[":scheme"] = "http"; + expected_header_set[":path"] = "/"; + expected_header_set[":authority"] = "www.example.com"; + + string encoded_header_set; + EXPECT_TRUE( + encoder.EncodeHeaderSet(expected_header_set, &encoded_header_set)); + + EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); + EXPECT_EQ(expected_header_set, decoded_block()); +} + +// RFC 7541, Section C.4: Request Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 +TEST_P(HpackDecoder3Test, SectionC4RequestHuffmanExamples) { + // TODO(jamessynge): Use net/http2/hpack/tools/hpack_example.h to parse the + // example directly, instead of having it as a comment. + // 82 | == Indexed - Add == + // | idx = 2 + // | -> :method: GET + // 86 | == Indexed - Add == + // | idx = 6 + // | -> :scheme: http + // 84 | == Indexed - Add == + // | idx = 4 + // | -> :path: / + // 41 | == Literal indexed == + // | Indexed name (idx = 1) + // | :authority + // 8c | Literal value (len = 12) + // | Huffman encoded: + // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... + // | Decoded: + // | www.example.com + // | -> :authority: www.example.com + string first = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4ff"); + const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); + + EXPECT_THAT(first_header_set, + ElementsAre( + // clang-format off + Pair(":method", "GET"), + Pair(":scheme", "http"), + Pair(":path", "/"), + Pair(":authority", "www.example.com"))); + // clang-format on + + expectEntry(62, 57, ":authority", "www.example.com"); + EXPECT_EQ(57u, decoder_peer_.current_header_table_size()); + + // 82 | == Indexed - Add == + // | idx = 2 + // | -> :method: GET + // 86 | == Indexed - Add == + // | idx = 6 + // | -> :scheme: http + // 84 | == Indexed - Add == + // | idx = 4 + // | -> :path: / + // be | == Indexed - Add == + // | idx = 62 + // | -> :authority: www.example.com + // 58 | == Literal indexed == + // | Indexed name (idx = 24) + // | cache-control + // 86 | Literal value (len = 8) + // | Huffman encoded: + // a8eb 1064 9cbf | ...d.. + // | Decoded: + // | no-cache + // | -> cache-control: no-cache + + string second = a2b_hex("828684be5886a8eb10649cbf"); + const SpdyHeaderBlock& second_header_set = + DecodeBlockExpectingSuccess(second); + + EXPECT_THAT(second_header_set, + ElementsAre( + // clang-format off + Pair(":method", "GET"), + Pair(":scheme", "http"), + Pair(":path", "/"), + Pair(":authority", "www.example.com"), + Pair("cache-control", "no-cache"))); + // clang-format on + + expectEntry(62, 53, "cache-control", "no-cache"); + expectEntry(63, 57, ":authority", "www.example.com"); + EXPECT_EQ(110u, decoder_peer_.current_header_table_size()); + + // 82 | == Indexed - Add == + // | idx = 2 + // | -> :method: GET + // 87 | == Indexed - Add == + // | idx = 7 + // | -> :scheme: https + // 85 | == Indexed - Add == + // | idx = 5 + // | -> :path: /index.html + // bf | == Indexed - Add == + // | idx = 63 + // | -> :authority: www.example.com + // 40 | == Literal indexed == + // 88 | Literal name (len = 10) + // | Huffman encoded: + // 25a8 49e9 5ba9 7d7f | %.I.[.}. + // | Decoded: + // | custom-key + // 89 | Literal value (len = 12) + // | Huffman encoded: + // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... + // | Decoded: + // | custom-value + // | -> custom-key: custom-value + string third = a2b_hex("828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf"); + const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); + + EXPECT_THAT( + third_header_set, + ElementsAre( + // clang-format off + Pair(":method", "GET"), + Pair(":scheme", "https"), + Pair(":path", "/index.html"), + Pair(":authority", "www.example.com"), + Pair("custom-key", "custom-value"))); + // clang-format on + + expectEntry(62, 54, "custom-key", "custom-value"); + expectEntry(63, 53, "cache-control", "no-cache"); + expectEntry(64, 57, ":authority", "www.example.com"); + EXPECT_EQ(164u, decoder_peer_.current_header_table_size()); +} + +// RFC 7541, Section C.6: Response Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6 +TEST_P(HpackDecoder3Test, SectionC6ResponseHuffmanExamples) { + // The example is based on a maximum dynamic table size of 256, + // which allows for testing dynamic table evictions. + decoder_peer_.set_header_table_size_limit(256); + + // 48 | == Literal indexed == + // | Indexed name (idx = 8) + // | :status + // 82 | Literal value (len = 3) + // | Huffman encoded: + // 6402 | d. + // | Decoded: + // | 302 + // | -> :status: 302 + // 58 | == Literal indexed == + // | Indexed name (idx = 24) + // | cache-control + // 85 | Literal value (len = 7) + // | Huffman encoded: + // aec3 771a 4b | ..w.K + // | Decoded: + // | private + // | -> cache-control: private + // 61 | == Literal indexed == + // | Indexed name (idx = 33) + // | date + // 96 | Literal value (len = 29) + // | Huffman encoded: + // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f + // e082 a62d 1bff | ...-.. + // | Decoded: + // | Mon, 21 Oct 2013 20:13:21 + // | GMT + // | -> date: Mon, 21 Oct 2013 + // | 20:13:21 GMT + // 6e | == Literal indexed == + // | Indexed name (idx = 46) + // | location + // 91 | Literal value (len = 23) + // | Huffman encoded: + // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C + // d3 | . + // | Decoded: + // | https://www.example.com + // | -> location: https://www.e + // | xample.com + + string first = a2b_hex( + "488264025885aec3771a4b6196d07abe" + "941054d444a8200595040b8166e082a6" + "2d1bff6e919d29ad171863c78f0b97c8" + "e9ae82ae43d3"); + const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); + + EXPECT_THAT(first_header_set, + ElementsAre( + // clang-format off + Pair(":status", "302"), + Pair("cache-control", "private"), + Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + Pair("location", "https://www.example.com"))); + // clang-format on + + expectEntry(62, 63, "location", "https://www.example.com"); + expectEntry(63, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); + expectEntry(64, 52, "cache-control", "private"); + expectEntry(65, 42, ":status", "302"); + EXPECT_EQ(222u, decoder_peer_.current_header_table_size()); + + // 48 | == Literal indexed == + // | Indexed name (idx = 8) + // | :status + // 83 | Literal value (len = 3) + // | Huffman encoded: + // 640e ff | d.. + // | Decoded: + // | 307 + // | - evict: :status: 302 + // | -> :status: 307 + // c1 | == Indexed - Add == + // | idx = 65 + // | -> cache-control: private + // c0 | == Indexed - Add == + // | idx = 64 + // | -> date: Mon, 21 Oct 2013 + // | 20:13:21 GMT + // bf | == Indexed - Add == + // | idx = 63 + // | -> location: + // | https://www.example.com + string second = a2b_hex("4883640effc1c0bf"); + const SpdyHeaderBlock& second_header_set = + DecodeBlockExpectingSuccess(second); + + EXPECT_THAT(second_header_set, + ElementsAre( + // clang-format off + Pair(":status", "307"), + Pair("cache-control", "private"), + Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + Pair("location", "https://www.example.com"))); + // clang-format on + + expectEntry(62, 42, ":status", "307"); + expectEntry(63, 63, "location", "https://www.example.com"); + expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); + expectEntry(65, 52, "cache-control", "private"); + EXPECT_EQ(222u, decoder_peer_.current_header_table_size()); + + // 88 | == Indexed - Add == + // | idx = 8 + // | -> :status: 200 + // c1 | == Indexed - Add == + // | idx = 65 + // | -> cache-control: private + // 61 | == Literal indexed == + // | Indexed name (idx = 33) + // | date + // 96 | Literal value (len = 22) + // | Huffman encoded: + // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f + // e084 a62d 1bff | ...-.. + // | Decoded: + // | Mon, 21 Oct 2013 20:13:22 + // | GMT + // | - evict: cache-control: + // | private + // | -> date: Mon, 21 Oct 2013 + // | 20:13:22 GMT + // c0 | == Indexed - Add == + // | idx = 64 + // | -> location: + // | https://www.example.com + // 5a | == Literal indexed == + // | Indexed name (idx = 26) + // | content-encoding + // 83 | Literal value (len = 3) + // | Huffman encoded: + // 9bd9 ab | ... + // | Decoded: + // | gzip + // | - evict: date: Mon, 21 Oct + // | 2013 20:13:21 GMT + // | -> content-encoding: gzip + // 77 | == Literal indexed == + // | Indexed name (idx = 55) + // | set-cookie + // ad | Literal value (len = 45) + // | Huffman encoded: + // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` + // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... + // 3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. + // | Decoded: + // | foo=ASDJKHQKBZXOQWEOPIUAXQ + // | WEOIU; max-age=3600; versi + // | on=1 + // | - evict: location: + // | https://www.example.com + // | - evict: :status: 307 + // | -> set-cookie: foo=ASDJKHQ + // | KBZXOQWEOPIUAXQWEOIU; + // | max-age=3600; version=1 + string third = a2b_hex( + "88c16196d07abe941054d444a8200595" + "040b8166e084a62d1bffc05a839bd9ab" + "77ad94e7821dd7f2e6c7b335dfdfcd5b" + "3960d5af27087f3672c1ab270fb5291f" + "9587316065c003ed4ee5b1063d5007"); + const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); + + EXPECT_THAT(third_header_set, + ElementsAre( + // clang-format off + Pair(":status", "200"), + Pair("cache-control", "private"), + Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), + Pair("location", "https://www.example.com"), + Pair("content-encoding", "gzip"), + Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" + " max-age=3600; version=1"))); + // clang-format on + + expectEntry(62, 98, "set-cookie", + "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" + " max-age=3600; version=1"); + expectEntry(63, 52, "content-encoding", "gzip"); + expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); + EXPECT_EQ(215u, decoder_peer_.current_header_table_size()); +} + +// Regression test: Found that entries with dynamic indexed names and literal +// values caused "use after free" MSAN failures if the name was evicted as it +// was being re-used. +TEST_P(HpackDecoder3Test, ReuseNameOfEvictedEntry) { + // Each entry is measured as 32 bytes plus the sum of the lengths of the name + // and the value. Set the size big enough for at most one entry, and a fairly + // small one at that (31 ASCII characters). + decoder_.ApplyHeaderTableSizeSetting(63); + + HpackBlockBuilder hbb; + hbb.AppendDynamicTableSizeUpdate(0); + hbb.AppendDynamicTableSizeUpdate(63); + + const StringPiece name("some-name"); + const StringPiece value1("some-value"); + const StringPiece value2("another-value"); + const StringPiece value3("yet-another-value"); + + // Add an entry that will become the first in the dynamic table, entry 62. + hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false, + name, false, value1); + + // Confirm that entry has been added by re-using it. + hbb.AppendIndexedHeader(62); + + // Add another entry referring to the name of the first. This will evict the + // first. + hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62, + false, value2); + + // Confirm that entry has been added by re-using it. + hbb.AppendIndexedHeader(62); + + // Add another entry referring to the name of the second. This will evict the + // second. + hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62, + false, value3); + + // Confirm that entry has been added by re-using it. + hbb.AppendIndexedHeader(62); + + EXPECT_TRUE(DecodeHeaderBlock(hbb.buffer())); + + SpdyHeaderBlock expected_header_set; + expected_header_set.AppendValueOrAddHeader(name, value1); + expected_header_set.AppendValueOrAddHeader(name, value1); + expected_header_set.AppendValueOrAddHeader(name, value2); + expected_header_set.AppendValueOrAddHeader(name, value2); + expected_header_set.AppendValueOrAddHeader(name, value3); + expected_header_set.AppendValueOrAddHeader(name, value3); + + // SpdyHeaderBlock stores these 6 strings as '\0' separated values. + // Make sure that is what happened. + string joined_values = expected_header_set[name].as_string(); + EXPECT_EQ(joined_values.size(), + 2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5); + + EXPECT_EQ(expected_header_set, decoded_block()); +} + +} // namespace +} // namespace test +} // namespace net
diff --git a/net/spdy/hpack/hpack_decoder_interface.h b/net/spdy/hpack/hpack_decoder_interface.h index 8adb62ff..1103e31 100644 --- a/net/spdy/hpack/hpack_decoder_interface.h +++ b/net/spdy/hpack/hpack_decoder_interface.h
@@ -28,11 +28,13 @@ // If a SpdyHeadersHandlerInterface is provided, the decoder will emit // headers to it rather than accumulating them in a SpdyHeaderBlock. + // Does not take ownership of the handler, but does use the pointer until + // the current HPACK block is completely decoded. virtual void HandleControlFrameHeadersStart( SpdyHeadersHandlerInterface* handler) = 0; // Called as HPACK block fragments arrive. Returns false if an error occurred - // while decoding the block. + // while decoding the block. Does not take ownership of headers_data. virtual bool HandleControlFrameHeadersData(const char* headers_data, size_t headers_data_length) = 0; @@ -57,6 +59,11 @@ std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) = 0; // Set how much encoded data this decoder is willing to buffer. + // TODO(jamessynge): Resolve definition of this value, as it is currently + // too tied to a single implementation. We probably want to limit one or more + // of these: individual name or value strings, header entries, the entire + // header list, or the HPACK block; we probably shouldn't care about the size + // of individual transport buffers. virtual void set_max_decode_buffer_size_bytes( size_t max_decode_buffer_size_bytes) = 0; };
diff --git a/net/spdy/hpack/hpack_decoder_test.cc b/net/spdy/hpack/hpack_decoder_test.cc index a0fe74f..5a26633a 100644 --- a/net/spdy/hpack/hpack_decoder_test.cc +++ b/net/spdy/hpack/hpack_decoder_test.cc
@@ -543,8 +543,9 @@ EXPECT_EQ(21u, input_stream.ParsedBytes()); } -// Round-tripping the header set from E.2.1 should work. -TEST_P(HpackDecoderTest, BasicE21) { +// Round-tripping the header set from RFC 7541 C.3.1 should work. +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 +TEST_P(HpackDecoderTest, BasicC31) { HpackEncoder encoder(ObtainHpackHuffmanTable()); SpdyHeaderBlock expected_header_set; @@ -561,7 +562,9 @@ EXPECT_EQ(expected_header_set, decoded_block()); } -TEST_P(HpackDecoderTest, SectionD4RequestHuffmanExamples) { +// RFC 7541, Section C.4: Request Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 +TEST_P(HpackDecoderTest, SectionC4RequestHuffmanExamples) { // 82 | == Indexed - Add == // | idx = 2 // | -> :method: GET @@ -668,7 +671,9 @@ EXPECT_EQ(164u, decoder_peer_.header_table()->size()); } -TEST_P(HpackDecoderTest, SectionD6ResponseHuffmanExamples) { +// RFC 7541, Section C.6: Response Examples with Huffman Coding +// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6 +TEST_P(HpackDecoderTest, SectionC6ResponseHuffmanExamples) { decoder_.ApplyHeaderTableSizeSetting(256); // 48 | == Literal indexed ==
diff --git a/net/spdy/spdy_flags.cc b/net/spdy/spdy_flags.cc index fa380d4..1f342d8 100644 --- a/net/spdy/spdy_flags.cc +++ b/net/spdy/spdy_flags.cc
@@ -12,9 +12,12 @@ // If true, remove use of SpdyFrameBuilder::OverwriteLength(). bool FLAGS_chromium_http2_flag_remove_rewritelength = true; -// Use //net/http2/hpack/decoder as HPACK decoder. +// Use //net/http2/hpack/decoder as HPACK entry decoder. bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; +// Use //net/http2/hpack/decoder as complete HPACK decoder. +bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; + // If true, increase HPACK table size up to optimal size kOptTableSize if // clients allow it. bool FLAGS_chromium_reloadable_flag_increase_hpack_table_size = false;
diff --git a/net/spdy/spdy_flags.h b/net/spdy/spdy_flags.h index d44cb9de..d448594 100644 --- a/net/spdy/spdy_flags.h +++ b/net/spdy/spdy_flags.h
@@ -14,6 +14,8 @@ NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2; NET_EXPORT_PRIVATE extern bool + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3; +NET_EXPORT_PRIVATE extern bool FLAGS_chromium_reloadable_flag_increase_hpack_table_size; NET_EXPORT_PRIVATE extern bool FLAGS_use_http2_frame_decoder_adapter; NET_EXPORT_PRIVATE extern bool FLAGS_use_nested_spdy_framer_decoder;
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index 85e8426..db06280 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc
@@ -25,6 +25,7 @@ #include "net/spdy/hpack/hpack_constants.h" #include "net/spdy/hpack/hpack_decoder.h" #include "net/spdy/hpack/hpack_decoder2.h" +#include "net/spdy/hpack/hpack_decoder3.h" #include "net/spdy/http2_frame_decoder_adapter.h" #include "net/spdy/spdy_bitmasks.h" #include "net/spdy/spdy_bug_tracker.h" @@ -2471,7 +2472,11 @@ HpackDecoderInterface* SpdyFramer::GetHpackDecoder() { if (hpack_decoder_.get() == nullptr) { - if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2) { + if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3) { + SPDY_BUG_IF(FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2) + << "Both alternate decoders are enabled."; + hpack_decoder_.reset(new HpackDecoder3()); + } else if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2) { hpack_decoder_.reset(new HpackDecoder2()); } else { hpack_decoder_.reset(new HpackDecoder());
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index 90ffade..e3b3fff9 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc
@@ -608,7 +608,7 @@ } enum DecoderChoice { DECODER_SELF, DECODER_NESTED, DECODER_HTTP2 }; -enum HpackChoice { HPACK_DECODER_1, HPACK_DECODER_2 }; +enum HpackChoice { HPACK_DECODER_1, HPACK_DECODER_2, HPACK_DECODER_3 }; class SpdyFramerTest : public ::testing::TestWithParam<std::tuple<DecoderChoice, HpackChoice>> { @@ -632,9 +632,15 @@ switch (std::get<1>(param)) { case HPACK_DECODER_1: FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; break; case HPACK_DECODER_2: FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = true; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; + break; + case HPACK_DECODER_3: + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; + FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = true; break; } } @@ -661,13 +667,12 @@ } }; -INSTANTIATE_TEST_CASE_P(SpdyFramerTests, - SpdyFramerTest, - ::testing::Combine(::testing::Values(DECODER_SELF, - DECODER_NESTED, - DECODER_HTTP2), - ::testing::Values(HPACK_DECODER_1, - HPACK_DECODER_2))); +INSTANTIATE_TEST_CASE_P( + SpdyFramerTests, + SpdyFramerTest, + ::testing::Combine( + ::testing::Values(DECODER_SELF, DECODER_NESTED, DECODER_HTTP2), + ::testing::Values(HPACK_DECODER_1, HPACK_DECODER_2, HPACK_DECODER_3))); // Test that we can encode and decode a SpdyHeaderBlock in serialized form. TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
diff --git a/services/preferences/public/cpp/pref_observer_store.cc b/services/preferences/public/cpp/pref_observer_store.cc index 7b38fe8..2b553d5 100644 --- a/services/preferences/public/cpp/pref_observer_store.cc +++ b/services/preferences/public/cpp/pref_observer_store.cc
@@ -11,14 +11,15 @@ namespace preferences { PrefObserverStore::PrefObserverStore( - prefs::mojom::PreferencesManagerPtr prefs_manager_ptr) + prefs::mojom::PreferencesFactoryPtr pref_factory_ptr) : prefs_binding_(this), - prefs_manager_ptr_(std::move(prefs_manager_ptr)), - initialized_(false) {} + pref_factory_ptr_(std::move(pref_factory_ptr)), + initialized_(false) { + pref_factory_ptr_->Create(prefs_binding_.CreateInterfacePtrAndBind(), + mojo::MakeRequest(&prefs_manager_ptr_)); +} void PrefObserverStore::Subscribe(const std::set<std::string>& keys) { - if (keys_.empty()) - prefs_manager_ptr_->AddObserver(prefs_binding_.CreateInterfacePtrAndBind()); keys_.insert(keys.begin(), keys.end()); std::vector<std::string> pref_array;
diff --git a/services/preferences/public/cpp/pref_observer_store.h b/services/preferences/public/cpp/pref_observer_store.h index 0b723463..67e3f83 100644 --- a/services/preferences/public/cpp/pref_observer_store.h +++ b/services/preferences/public/cpp/pref_observer_store.h
@@ -30,7 +30,7 @@ public prefs::mojom::PreferencesObserver { public: explicit PrefObserverStore( - prefs::mojom::PreferencesManagerPtr prefs_manager_ptr); + prefs::mojom::PreferencesFactoryPtr pref_factory_ptr); // Adds a set of |keys| which PrefObserverStore will handle. Begins listening // for changes to these from |prefs_manager_|. @@ -67,6 +67,7 @@ std::unique_ptr<base::DictionaryValue> preferences) override; mojo::Binding<prefs::mojom::PreferencesObserver> prefs_binding_; + prefs::mojom::PreferencesFactoryPtr pref_factory_ptr_; prefs::mojom::PreferencesManagerPtr prefs_manager_ptr_; std::set<std::string> keys_;
diff --git a/services/preferences/public/cpp/tests/pref_observer_store_unittest.cc b/services/preferences/public/cpp/tests/pref_observer_store_unittest.cc index 9dbd0a5..f5fa5a7 100644 --- a/services/preferences/public/cpp/tests/pref_observer_store_unittest.cc +++ b/services/preferences/public/cpp/tests/pref_observer_store_unittest.cc
@@ -21,37 +21,27 @@ public: TestPreferenceManager( mojo::InterfaceRequest<prefs::mojom::PreferencesManager> request) - : add_observer_called_(false), - set_preferences_called_(false), - binding_(this, std::move(request)) {} + : set_preferences_called_(false), binding_(this, std::move(request)) {} ~TestPreferenceManager() override {} - bool add_observer_called() { return add_observer_called_; } const std::set<std::string>& last_preference_set() { return last_preference_set_; } bool set_preferences_called() { return set_preferences_called_; } // prefs::mojom::TestPreferenceManager: - void AddObserver(prefs::mojom::PreferencesObserverPtr client) override; void SetPreferences( std::unique_ptr<base::DictionaryValue> preferences) override; void Subscribe(const std::vector<std::string>& preferences) override; private: - bool add_observer_called_; std::set<std::string> last_preference_set_; bool set_preferences_called_; - mojo::Binding<PreferencesManager> binding_; + mojo::Binding<prefs::mojom::PreferencesManager> binding_; DISALLOW_COPY_AND_ASSIGN(TestPreferenceManager); }; -void TestPreferenceManager::AddObserver( - prefs::mojom::PreferencesObserverPtr client) { - add_observer_called_ = true; -} - void TestPreferenceManager::SetPreferences( std::unique_ptr<base::DictionaryValue> preferences) { set_preferences_called_ = true; @@ -63,6 +53,33 @@ last_preference_set_.insert(preferences.begin(), preferences.end()); } +// Test implementation of prefs::mojom::PreferencesFactory which simply creates +// the TestPreferenceManager used for testing. +class TestPreferenceFactory : public prefs::mojom::PreferencesFactory { + public: + TestPreferenceFactory( + mojo::InterfaceRequest<prefs::mojom::PreferencesFactory> request) + : binding_(this, std::move(request)) {} + ~TestPreferenceFactory() override {} + + TestPreferenceManager* manager() { return manager_.get(); } + + void Create(prefs::mojom::PreferencesObserverPtr observer, + prefs::mojom::PreferencesManagerRequest manager) override; + + private: + mojo::Binding<prefs::mojom::PreferencesFactory> binding_; + std::unique_ptr<TestPreferenceManager> manager_; + + DISALLOW_COPY_AND_ASSIGN(TestPreferenceFactory); +}; + +void TestPreferenceFactory::Create( + prefs::mojom::PreferencesObserverPtr observer, + prefs::mojom::PreferencesManagerRequest manager) { + manager_.reset(new TestPreferenceManager(std::move(manager))); +} + } // namespace namespace preferences { @@ -72,7 +89,7 @@ PrefObserverStoreTest() {} ~PrefObserverStoreTest() override {} - TestPreferenceManager* manager() { return manager_.get(); } + TestPreferenceManager* manager() { return factory_->manager(); } PrefStoreObserverMock* observer() { return &observer_; } PrefObserverStore* store() { return store_.get(); } @@ -87,8 +104,8 @@ private: scoped_refptr<PrefObserverStore> store_; - prefs::mojom::PreferencesManagerPtr proxy_; - std::unique_ptr<TestPreferenceManager> manager_; + prefs::mojom::PreferencesFactoryPtr factory_proxy_; + std::unique_ptr<TestPreferenceFactory> factory_; PrefStoreObserverMock observer_; // Required by mojo binding code within PrefObserverStore. base::MessageLoop message_loop_; @@ -97,8 +114,9 @@ }; void PrefObserverStoreTest::SetUp() { - manager_.reset(new TestPreferenceManager(mojo::MakeRequest(&proxy_))); - store_ = new PrefObserverStore(std::move(proxy_)); + factory_.reset(new TestPreferenceFactory(mojo::MakeRequest(&factory_proxy_))); + store_ = new PrefObserverStore(std::move(factory_proxy_)); + base::RunLoop().RunUntilIdle(); store_->AddObserver(&observer_); }
diff --git a/services/preferences/public/interfaces/preferences.mojom b/services/preferences/public/interfaces/preferences.mojom index 27d43d31..cae6a15f5 100644 --- a/services/preferences/public/interfaces/preferences.mojom +++ b/services/preferences/public/interfaces/preferences.mojom
@@ -8,6 +8,13 @@ const string kServiceName = "preferences"; +// Used for the creation of a PreferencesManager and to ensure that the +// PreferencesObserver is bound at creation time. +interface PreferencesFactory { + // Creates a PreferencesManager bound to the provided |observer|. + Create(PreferencesObserver observer, PreferencesManager& manager); +}; + // Used to subscribe to preference changes within PreferenceManager. After // requesting to observe, the current values for all requested keys are sent. interface PreferencesObserver { @@ -17,7 +24,6 @@ // Manages actual read/write of preference data. Accepts observers who subscribe // to preferences, notifying them of changes. interface PreferencesManager { - AddObserver(PreferencesObserver client); SetPreferences(mojo.common.mojom.DictionaryValue preferences); Subscribe(array<string> preferences); };
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index f5039e1..2675422 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -44659,6 +44659,11125 @@ } ] }, + "Mac Mini 8GB 10.12 Perf": { + "isolated_scripts": [ + { + "args": [ + "battor.power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.power_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.power_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.power_cases_no_chrome_trace", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.power_cases_no_chrome_trace", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.power_cases_no_chrome_trace", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.power_cases_no_chrome_trace.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.steady_state", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.steady_state.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.tough_video_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "battor.trivial_pages.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.bindings", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.bindings", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.bindings", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.bindings.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.blink_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.blink_gc", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.blink_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.blink_gc.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.canvas", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.canvas", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.canvas", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.canvas.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.css", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.css", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.css", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.css.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.dom", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.dom.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.events", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.events", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.events", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.events.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.layout", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.layout", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.layout", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.layout.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.paint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.paint", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.paint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.paint.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.parser", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.parser", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.parser", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.parser.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.pywebsocket", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.pywebsocket", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.pywebsocket", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.pywebsocket.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.shadow_dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.shadow_dom", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.shadow_dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.shadow_dom.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.svg", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.svg", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.svg", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.svg.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.xml_http_request", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.xml_http_request", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.xml_http_request", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.xml_http_request.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.key_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.key_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.key_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.key_mobile_sites.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.polymer", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.polymer.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.top_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_style.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_style.top_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blob_storage.blob_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blob_storage.blob_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "blob_storage.blob_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blob_storage.blob_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.cssqueryjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.cssqueryjquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.cssqueryjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.cssqueryjquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoreattr", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoreattr", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoreattr", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoreattr.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoremodify", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoremodify", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoremodify", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoremodify.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcorequery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcorequery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcorequery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcorequery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoretraverse", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoretraverse", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoretraverse", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.domcoretraverse.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibattrjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibattrjquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibattrjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibattrjquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibattrprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibattrprototype", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibattrprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibattrprototype.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibeventjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibeventjquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibeventjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibeventjquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibeventprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibeventprototype", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibeventprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibeventprototype.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibmodifyjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibmodifyjquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibmodifyjquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibmodifyjquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibmodifyprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibmodifyprototype", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibmodifyprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibmodifyprototype.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibstylejquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibstylejquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibstylejquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibstylejquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibstyleprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibstyleprototype", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibstyleprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibstyleprototype.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibtraversejquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibtraversejquery", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibtraversejquery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibtraversejquery.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibtraverseprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibtraverseprototype", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.jslibtraverseprototype", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dromaeo.jslibtraverseprototype.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.noisy_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dummy_benchmark.noisy_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.noisy_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dummy_benchmark.noisy_benchmark_1.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.stable_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dummy_benchmark.stable_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.stable_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "dummy_benchmark.stable_benchmark_1.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.gpu_rasterization.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.gpu_rasterization.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.gpu_rasterization.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.gpu_rasterization.top_25_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "gpu_times.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "gpu_times.top_25_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "image_decoding.image_decoding_measurement", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "image_decoding.image_decoding_measurement", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "image_decoding.image_decoding_measurement", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "image_decoding.image_decoding_measurement.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "indexeddb_perf", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "indexeddb_perf", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "indexeddb_perf", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "indexeddb_perf.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "jetstream", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "jetstream", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "jetstream", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "jetstream.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "jitter", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "jitter", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "jitter", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "jitter.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "kraken", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "kraken", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "kraken", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "kraken.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.cluster_telemetry", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "loading.cluster_telemetry", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.cluster_telemetry", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "loading.cluster_telemetry.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "loading.mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 14400, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "loading.mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 14400, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.android.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.android.tough_video_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.chromeOS.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.chromeOS.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.chromeOS.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.chromeOS.tough_video_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.chromeOS4kOnly.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.chromeOS4kOnly.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.chromeOS4kOnly.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.chromeOS4kOnly.tough_video_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.media_cns_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.media_cns_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.media_cns_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.media_cns_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.mse_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.mse_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.mse_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.mse_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.tough_video_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.tough_video_cases_extra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.tough_video_cases_extra", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.tough_video_cases_extra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "media.tough_video_cases_extra.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.blink_memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.blink_memory_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.blink_memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.blink_memory_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.dual_browser_test", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.dual_browser_test", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.dual_browser_test", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.dual_browser_test.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_dual_browser_test", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_dual_browser_test", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_dual_browser_test", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_dual_browser_test.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_background_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_idle_gmail_background_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_background_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_idle_gmail_background_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_idle_gmail_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.long_running_idle_gmail_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.top_10_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.top_10_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile_stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.top_10_mobile_stress", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile_stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "memory.top_10_mobile_stress.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "octane", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "octane", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "octane", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "octane.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.blink_perf_stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.blink_perf_stress", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.blink_perf_stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.blink_perf_stress.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.key_silk_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oilpan_gc_times.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oilpan_gc_times.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oortonline", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oortonline.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oortonline_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "oortonline_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.basic_oopif", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.basic_oopif", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.basic_oopif", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.basic_oopif.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ar_fa_he", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ar_fa_he", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ar_fa_he", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ar_fa_he.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_es_fr_pt-BR", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_es_fr_pt-BR", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_es_fr_pt-BR", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_es_fr_pt-BR.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_hi_ru", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_hi_ru", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_hi_ru", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_hi_ru.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ja_zh", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ja_zh", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ja_zh", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ja_zh.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ko_th_vi", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ko_th_vi", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.intl_ko_th_vi", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.intl_ko_th_vi.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.top_10_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.top_10_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.tough_layout_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.tough_layout_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.tough_layout_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.tough_layout_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.typical_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.typical_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2.typical_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2.typical_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2_site_isolation.basic_oopif", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2_site_isolation.basic_oopif", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "page_cycler_v2_site_isolation.basic_oopif", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "page_cycler_v2_site_isolation.basic_oopif.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.android_acceptance", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.android_acceptance", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.android_acceptance", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.android_acceptance.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.top_10", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.top_10.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.top_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.top_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.typical_10_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.gpu_rasterization.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.gpu_rasterization.typical_10_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.steady_state", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.steady_state.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.top_10", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.top_10.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.top_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.top_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.tough_ad_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.tough_ad_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.trivial_pages.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.typical_10_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.typical_10_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile_reload", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.typical_10_mobile_reload", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile_reload", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "power.typical_10_mobile_reload.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.key_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.key_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.key_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.key_mobile_sites.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.key_silk_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.partial_invalidation", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.partial_invalidation", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.partial_invalidation", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.partial_invalidation.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.polymer", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.polymer.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.top_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "rasterize_and_record_micro.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "rasterize_and_record_micro.top_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "repaint.gpu_rasterization.key_mobile_sites_repaint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "repaint.gpu_rasterization.key_mobile_sites_repaint", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "repaint.gpu_rasterization.key_mobile_sites_repaint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "repaint.gpu_rasterization.key_mobile_sites_repaint.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "repaint.key_mobile_sites_repaint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "repaint.key_mobile_sites_repaint", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "repaint.key_mobile_sites_repaint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "repaint.key_mobile_sites_repaint.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "robohornet_pro", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "robohornet_pro", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "robohornet_pro", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "robohornet_pro.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "scheduler.tough_scheduling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "scheduler.tough_scheduling_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "scheduler.tough_scheduling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "scheduler.tough_scheduling_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "service_worker.service_worker", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "service_worker.service_worker.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker_micro_benchmark", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "service_worker.service_worker_micro_benchmark", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker_micro_benchmark", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "service_worker.service_worker_micro_benchmark.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.desktop_tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.desktop_tough_pinch_zoom_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.desktop_tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.desktop_tough_pinch_zoom_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.polymer", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.polymer.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.top_25_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_filters_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization_and_decoding.image_decoding_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization_and_decoding.image_decoding_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.image_decoding_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.image_decoding_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.image_decoding_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.image_decoding_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_silk_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.maps", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.maps", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.maps", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.maps.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.pathological_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.pathological_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.pathological_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.pathological_mobile_sites.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.scrolling_tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.scrolling_tough_ad_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.scrolling_tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.scrolling_tough_ad_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.simple_mobile_sites.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.sync_scroll.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.sync_scroll.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.top_25_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_ad_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_ad_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_canvas_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_canvas_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_canvas_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_canvas_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_filters_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_path_rendering_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_pinch_zoom_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_pinch_zoom_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_scrolling_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_texture_upload_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_texture_upload_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_texture_upload_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_texture_upload_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_webgl_ad_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_webgl_ad_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_webgl_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_webgl_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "spaceport", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "spaceport", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "spaceport", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "spaceport.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer-ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer-ignition", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer-ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer-ignition.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer-turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer-turbo", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer-turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer-turbo.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "speedometer.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.cold.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_url.cold.startup_pages", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.cold.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_url.cold.startup_pages.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.warm.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_url.warm.startup_pages", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.warm.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_url.warm.startup_pages.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.large_profile.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.large_profile.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.large_profile.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.large_profile.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.large_profile.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.large_profile.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.large_profile.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.large_profile.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.warm.chrome_signin", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.warm.chrome_signin", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "startup.warm.chrome_signin", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "startup.warm.chrome_signin.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "storage.indexeddb_endure", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "storage.indexeddb_endure.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure_tracing", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "storage.indexeddb_endure_tracing", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure_tracing", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "storage.indexeddb_endure_tracing.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "sunspider", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "sunspider", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "sunspider", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "sunspider.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.common_desktop", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.common_desktop.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.common_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.common_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.memory_desktop", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.memory_desktop.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.memory_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.memory_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.webview_startup", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.webview_startup.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup_multiprocess", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.webview_startup_multiprocess", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup_multiprocess", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "system_health.webview_startup_multiprocess.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.five_blank_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.five_blank_pages", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.five_blank_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.five_blank_pages.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.top_10", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.top_10", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.top_10.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.tough_energy_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.tough_energy_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.tough_energy_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.tough_energy_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.tough_image_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.tough_image_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.tough_image_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.tough_image_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.typical_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.typical_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tab_switching.typical_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tab_switching.typical_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "text_selection.character", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "text_selection.character", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "text_selection.character", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "text_selection.character.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "text_selection.direction", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "text_selection.direction", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "text_selection.direction", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "text_selection.direction.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_hit_test_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_hit_test_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_hit_test_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_hit_test_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_idle_power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_idle_power_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_idle_power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_idle_power_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_noop_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_noop_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_noop_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_noop_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.key_silk_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.polymer", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.polymer.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.simple_mobile_sites.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_compositor_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.tough_compositor_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_compositor_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.tough_compositor_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "thread_times.tough_scrolling_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_background_memory_infra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tracing.tracing_with_background_memory_infra", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_background_memory_infra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tracing.tracing_with_background_memory_infra.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_debug_overhead", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tracing.tracing_with_debug_overhead", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_debug_overhead", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "tracing.tracing_with_debug_overhead.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop_ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop_ignition", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop_ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop_ignition.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop_turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop_turbo", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_desktop_turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_desktop_turbo.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile_ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile_ignition", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile_ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile_ignition.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile_turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile_turbo", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile_turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.browsing_mobile_turbo.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.detached_context_age_in_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.detached_context_age_in_gc", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.detached_context_age_in_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.detached_context_age_in_gc.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.google", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.google", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.google", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.google.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll-ignition_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll-ignition_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll-ignition_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll-ignition_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll-turbo_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll-turbo_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll-turbo_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll-turbo_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.infinite_scroll_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build27-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.key_mobile_sites_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.mobile_infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.mobile_infinite_scroll_tbmv2", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.mobile_infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.mobile_infinite_scroll_tbmv2.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.runtime_stats.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.runtime_stats.top_25", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.runtime_stats.top_25", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.runtime_stats.top_25.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build24-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc-ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc-ignition", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc-ignition", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc-ignition.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc-turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc-turbo", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc-turbo", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc-turbo.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.todomvc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.todomvc.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "v8.top_25_smooth.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.datachannel", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.datachannel", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.datachannel", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.datachannel.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.getusermedia", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.getusermedia", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.getusermedia", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.getusermedia.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.peerconnection", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.peerconnection", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.peerconnection", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.peerconnection.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build26-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.stress", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.stress", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.stress.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build28-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.webrtc_smoothness", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.webrtc_smoothness", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc.webrtc_smoothness", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "webrtc.webrtc_smoothness.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 21600, + "hard_timeout": 7200, + "io_timeout": 3600 + } + } + ] + }, "Mac Pro 10.11 Perf": { "isolated_scripts": [ {
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/crash-large-positions.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/crash-large-positions.html new file mode 100644 index 0000000..b4925165 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/crash-large-positions.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<title>Test using huge values for grid-column-* and grid-row-*</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/grid-definitions-parsing-utils.js"></script> + +<div style="display: grid;"> + <div id="item" style="grid-column-start: 5000000000; grid-column-end: -5000000000; grid-row-start: 5000000000; grid-row-end: -5000000000;"></div> +</div> + +<script> + test(function() { + testGridPositionDefinitionsValues(document.getElementById("item"), "1000", "-1000", "1000", "-1000"); + }, "Test that setting and getting grid-column|row-start|end to huge values is properly clamped and does not make the renderer crash."); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/resources/grid-definitions-parsing-utils.js b/third_party/WebKit/LayoutTests/fast/css-grid-layout/resources/grid-definitions-parsing-utils.js index 4273fbe5..0c1b97c4 100644 --- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/resources/grid-definitions-parsing-utils.js +++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/resources/grid-definitions-parsing-utils.js
@@ -77,3 +77,21 @@ shouldBeEqualToString("window.getComputedStyle(" + element + ", '').getPropertyValue('grid-row-gap')", computedRowGap); shouldBeEqualToString("window.getComputedStyle(" + element + ", '').getPropertyValue('grid-column-gap')", computedColumnGap); } + +function testGridPositionDefinitionsValues( + element, computedRowStart, computedRowEnd, computedColumnStart, + computedColumnEnd) { + assert_equals( + window.getComputedStyle(element, '').getPropertyValue('grid-row-start'), + computedRowStart, 'row-start'); + assert_equals( + window.getComputedStyle(element, '').getPropertyValue('grid-row-end'), + computedRowEnd, 'row-end'); + assert_equals( + window.getComputedStyle(element, '') + .getPropertyValue('grid-column-start'), + computedColumnStart, 'column-start'); + assert_equals( + window.getComputedStyle(element, '').getPropertyValue('grid-column-end'), + computedColumnEnd, 'column-end'); +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture-expected.txt index 530cfaad..4c0508c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture-expected.txt
@@ -1,5 +1,3 @@ -CONSOLE ERROR: line 8: Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://127.0.0.1:8000/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture.html' from frame with URL 'http://localhost:8000/security/frameNavigation/resources/iframe-that-performs-top-navigation-without-user-gesture-failed.html'. The frame attempting navigation of the top-level window is sandboxed with the 'allow-top-navigation-with-user-activation' flag, but has no user activation (aka gesture). See https://www.chromestatus.com/feature/5629582019395584. - This tests that an iframe in sandbox with 'allow-top-navigation-with-user-activation' cannot navigate its top level page, if it is not trigged by a user gesture.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture.html b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture.html index 071fdc71..44035a2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/sandbox-DENIED-top-navigation-without-user-gesture.html
@@ -4,7 +4,7 @@ if (window.testRunner) { testRunner.dumpAsText(); testRunner.dumpChildFramesAsText(); - testRunner.setDumpConsoleMessages(true); + testRunner.setDumpConsoleMessages(false); testRunner.waitUntilDone(); }
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining-expected.txt index 03be975..50688c0a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining-expected.txt
@@ -55,7 +55,7 @@ PASS The return value of MediaStreamAudioSourceNode.connect(BiquadFilterNode, 0) matches the destination BiquadFilterNode. PASS The return value of MediaStreamAudioSourceNode.connect(ChannelMergerNode, 0, 1) matches the destination ChannelMergerNode. PASS Connecting with an invalid output threw IndexSizeError: Failed to execute 'connect' on 'AudioNode': output index (1) exceeds number of outputs (1).. -PASS Connecting to a node from the different context threw SyntaxError: Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.. +PASS Connecting to a node from the different context threw InvalidAccessError: Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.. PASS The output of chained connection of gain nodes contains only the constant 0.125. PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html b/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html index 5b27e30..b555bfd9 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html
@@ -125,7 +125,7 @@ // first connection succeeds but the second one should throw. Should('Connecting to a node from the different context', function () { gain1.connect(gain2).connect(contextB.destination); - }).throw('SyntaxError'); + }).throw('InvalidAccessError'); done(); });
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt index 0924a86..87c61261 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt
@@ -64,7 +64,7 @@ PASS node.connect(context.destination, 0, 100) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': input index (100) exceeds number of inputs (1).. PASS node.connect(node2.gain, 100) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).. PASS node.disconnect(99) threw exception IndexSizeError: Failed to execute 'disconnect' on 'AudioNode': The output index provided (99) is outside the range [0, 0].. -PASS node.connect(otherContext.destination) threw exception SyntaxError: Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.. +PASS node.connect(otherContext.destination) threw exception InvalidAccessError: Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.. PASS node.channelCount = 99 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': The channel count provided (99) is outside the range [1, 32].. PASS node.channelCount is not 99 PASS node.channelCountMode = 'fancy' did not throw exception.
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index 9bc7288..a9be2f2 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -356,6 +356,7 @@ "properties/CSSPropertyAPIFontVariantCaps.cpp", "properties/CSSPropertyAPIFontVariantLigatures.cpp", "properties/CSSPropertyAPIFontVariationSettings.cpp", + "properties/CSSPropertyAPIGridAutoFlow.cpp", "properties/CSSPropertyAPILetterAndWordSpacing.cpp", "properties/CSSPropertyAPIOffsetPosition.cpp", "properties/CSSPropertyAPIOutlineColor.cpp", @@ -365,6 +366,7 @@ "properties/CSSPropertyAPIPaintStroke.cpp", "properties/CSSPropertyAPIQuotes.cpp", "properties/CSSPropertyAPIRotate.cpp", + "properties/CSSPropertyAPIScale.cpp", "properties/CSSPropertyAPIScrollSnapCoordinate.cpp", "properties/CSSPropertyAPIShapeMargin.cpp", "properties/CSSPropertyAPISize.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in index e60f292..aca95d02 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.in +++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -270,7 +270,7 @@ flood-color interpolable, svg, converter=convertColor flood-opacity interpolable, svg, converter=convertNumberOrPercentage grid-auto-columns runtime_flag=CSSGridLayout, converter=convertGridTrackSizeList -grid-auto-flow runtime_flag=CSSGridLayout, converter=convertGridAutoFlow, type_name=GridAutoFlow +grid-auto-flow runtime_flag=CSSGridLayout, converter=convertGridAutoFlow, type_name=GridAutoFlow, api_class grid-auto-rows runtime_flag=CSSGridLayout, converter=convertGridTrackSizeList grid-column-end runtime_flag=CSSGridLayout, converter=convertGridPosition grid-column-gap runtime_flag=CSSGridLayout, converter=convertLength @@ -397,7 +397,7 @@ transform-style name_for_methods=TransformStyle3D translate runtime_flag=CSSIndependentTransformProperties, converter=convertTranslate, interpolable, api_class rotate runtime_flag=CSSIndependentTransformProperties, converter=convertRotate, interpolable, api_class -scale runtime_flag=CSSIndependentTransformProperties, converter=convertScale, interpolable +scale runtime_flag=CSSIndependentTransformProperties, converter=convertScale, interpolable, api_class unicode-bidi type_name=UnicodeBidi, keyword_only, keywords=[normal|embed|bidi-override|isolate|plaintext|isolate-override], initial_keyword=normal, field_storage_type=platform/text/UnicodeBidi vector-effect svg vertical-align interpolable, custom_inherit, custom_value, api_class
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index 84588d20..a3a7a79 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -531,29 +531,6 @@ return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative); } -static CSSValue* consumeScale(CSSParserTokenRange& range) { - ASSERT(RuntimeEnabledFeatures::cssIndependentTransformPropertiesEnabled()); - - CSSValueID id = range.peek().id(); - if (id == CSSValueNone) - return consumeIdent(range); - - CSSValue* scale = consumeNumber(range, ValueRangeAll); - if (!scale) - return nullptr; - CSSValueList* list = CSSValueList::createSpaceSeparated(); - list->append(*scale); - scale = consumeNumber(range, ValueRangeAll); - if (scale) { - list->append(*scale); - scale = consumeNumber(range, ValueRangeAll); - if (scale) - list->append(*scale); - } - - return list; -} - static CSSValue* consumeCounter(CSSParserTokenRange& range, int defaultValue) { if (range.peek().id() == CSSValueNone) return consumeIdent(range); @@ -2048,23 +2025,6 @@ CSSValuePair::KeepIdenticalValues); } -static CSSValueList* consumeGridAutoFlow(CSSParserTokenRange& range) { - CSSIdentifierValue* rowOrColumnValue = - consumeIdent<CSSValueRow, CSSValueColumn>(range); - CSSIdentifierValue* denseAlgorithm = consumeIdent<CSSValueDense>(range); - if (!rowOrColumnValue) { - rowOrColumnValue = consumeIdent<CSSValueRow, CSSValueColumn>(range); - if (!rowOrColumnValue && !denseAlgorithm) - return nullptr; - } - CSSValueList* parsedValues = CSSValueList::createSpaceSeparated(); - if (rowOrColumnValue) - parsedValues->append(*rowOrColumnValue); - if (denseAlgorithm) - parsedValues->append(*denseAlgorithm); - return parsedValues; -} - static CSSValue* consumeBackgroundComponent(CSSPropertyID unresolvedProperty, CSSParserTokenRange& range, const CSSParserContext* context) { @@ -2655,8 +2615,6 @@ return consumeFontSize(m_range, m_context->mode(), UnitlessQuirk::Allow); case CSSPropertyLineHeight: return consumeLineHeight(m_range, m_context->mode()); - case CSSPropertyScale: - return consumeScale(m_range); case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: return consumeLength(m_range, m_context->mode(), ValueRangeNonNegative); @@ -2960,9 +2918,6 @@ case CSSPropertyGridTemplateAreas: ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); return consumeGridTemplateAreas(m_range); - case CSSPropertyGridAutoFlow: - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); - return consumeGridAutoFlow(m_range); default: return nullptr; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp index e485e30..c5eb170b 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp
@@ -22,18 +22,18 @@ TEST(CSSPropertyParserTest, GridTrackLimit1) { const CSSValue* value = CSSParser::parseSingleValue( - CSSPropertyGridTemplateColumns, "repeat(999999, 20px)"); + CSSPropertyGridTemplateColumns, "repeat(999, 20px)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit2) { const CSSValue* value = CSSParser::parseSingleValue( - CSSPropertyGridTemplateRows, "repeat(999999, 20px)"); + CSSPropertyGridTemplateRows, "repeat(999, 20px)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit3) { @@ -41,7 +41,7 @@ CSSPropertyGridTemplateColumns, "repeat(1000000, 10%)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit4) { @@ -49,7 +49,7 @@ CSSPropertyGridTemplateRows, "repeat(1000000, 10%)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit5) { @@ -58,7 +58,7 @@ "repeat(1000000, [first] min-content [last])"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit6) { @@ -67,7 +67,7 @@ "repeat(1000000, [first] min-content [last])"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit7) { @@ -75,7 +75,7 @@ CSSPropertyGridTemplateColumns, "repeat(1000001, auto)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit8) { @@ -83,7 +83,7 @@ CSSPropertyGridTemplateRows, "repeat(1000001, auto)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit9) { @@ -92,7 +92,7 @@ "repeat(400000, 2em minmax(10px, max-content) 0.5fr)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit10) { @@ -101,7 +101,7 @@ "repeat(400000, 2em minmax(10px, max-content) 0.5fr)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit11) { @@ -110,7 +110,7 @@ "repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last])"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit12) { @@ -119,7 +119,7 @@ "repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last])"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit13) { @@ -127,7 +127,7 @@ CSSPropertyGridTemplateColumns, "repeat(100000000000000000000, 10% 1fr)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit14) { @@ -135,7 +135,7 @@ CSSPropertyGridTemplateRows, "repeat(100000000000000000000, 10% 1fr)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000000); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit15) { @@ -144,7 +144,7 @@ "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit16) { @@ -153,7 +153,7 @@ "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)"); ASSERT_TRUE(value); ASSERT_TRUE(value->isValueList()); - EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 999999); + EXPECT_EQ(computeNumberOfTracks(toCSSValueList(value)), 994); } static int getGridPositionInteger(const CSSValue& value) { @@ -167,58 +167,58 @@ TEST(CSSPropertyParserTest, GridPositionLimit1) { const CSSValue* value = - CSSParser::parseSingleValue(CSSPropertyGridColumnStart, "999999"); + CSSParser::parseSingleValue(CSSPropertyGridColumnStart, "999"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), 999999); + EXPECT_EQ(getGridPositionInteger(*value), 999); } TEST(CSSPropertyParserTest, GridPositionLimit2) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridColumnEnd, "1000000"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), 1000000); + EXPECT_EQ(getGridPositionInteger(*value), 1000); } TEST(CSSPropertyParserTest, GridPositionLimit3) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridRowStart, "1000001"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), 1000000); + EXPECT_EQ(getGridPositionInteger(*value), 1000); } TEST(CSSPropertyParserTest, GridPositionLimit4) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridRowEnd, "5000000000"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), 1000000); + EXPECT_EQ(getGridPositionInteger(*value), 1000); } TEST(CSSPropertyParserTest, GridPositionLimit5) { const CSSValue* value = - CSSParser::parseSingleValue(CSSPropertyGridColumnStart, "-999999"); + CSSParser::parseSingleValue(CSSPropertyGridColumnStart, "-999"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), -999999); + EXPECT_EQ(getGridPositionInteger(*value), -999); } TEST(CSSPropertyParserTest, GridPositionLimit6) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridColumnEnd, "-1000000"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), -1000000); + EXPECT_EQ(getGridPositionInteger(*value), -1000); } TEST(CSSPropertyParserTest, GridPositionLimit7) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridRowStart, "-1000001"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), -1000000); + EXPECT_EQ(getGridPositionInteger(*value), -1000); } TEST(CSSPropertyParserTest, GridPositionLimit8) { const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyGridRowEnd, "-5000000000"); DCHECK(value); - EXPECT_EQ(getGridPositionInteger(*value), -1000000); + EXPECT_EQ(getGridPositionInteger(*value), -1000); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp new file mode 100644 index 0000000..af14523 --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIGridAutoFlow.cpp
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/properties/CSSPropertyAPIGridAutoFlow.h" + +#include "core/css/CSSIdentifierValue.h" +#include "core/css/CSSValueList.h" +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "platform/RuntimeEnabledFeatures.h" + +namespace blink { + +const CSSValue* CSSPropertyAPIGridAutoFlow::parseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext* context) { + DCHECK(RuntimeEnabledFeatures::cssGridLayoutEnabled()); + CSSIdentifierValue* rowOrColumnValue = + CSSPropertyParserHelpers::consumeIdent<CSSValueRow, CSSValueColumn>( + range); + CSSIdentifierValue* denseAlgorithm = + CSSPropertyParserHelpers::consumeIdent<CSSValueDense>(range); + if (!rowOrColumnValue) { + rowOrColumnValue = + CSSPropertyParserHelpers::consumeIdent<CSSValueRow, CSSValueColumn>( + range); + if (!rowOrColumnValue && !denseAlgorithm) + return nullptr; + } + CSSValueList* parsedValues = CSSValueList::createSpaceSeparated(); + if (rowOrColumnValue) + parsedValues->append(*rowOrColumnValue); + if (denseAlgorithm) + parsedValues->append(*denseAlgorithm); + return parsedValues; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIScale.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIScale.cpp new file mode 100644 index 0000000..7ee7f66 --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIScale.cpp
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/properties/CSSPropertyAPIScale.h" + +#include "core/css/CSSValueList.h" +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "platform/RuntimeEnabledFeatures.h" + +namespace blink { + +const CSSValue* CSSPropertyAPIScale::parseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext* context) { + DCHECK(RuntimeEnabledFeatures::cssIndependentTransformPropertiesEnabled()); + + CSSValueID id = range.peek().id(); + if (id == CSSValueNone) + return CSSPropertyParserHelpers::consumeIdent(range); + + CSSValue* scale = + CSSPropertyParserHelpers::consumeNumber(range, ValueRangeAll); + if (!scale) + return nullptr; + CSSValueList* list = CSSValueList::createSpaceSeparated(); + list->append(*scale); + scale = CSSPropertyParserHelpers::consumeNumber(range, ValueRangeAll); + if (scale) { + list->append(*scale); + scale = CSSPropertyParserHelpers::consumeNumber(range, ValueRangeAll); + if (scale) + list->append(*scale); + } + + return list; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 440e4e3..e9af56f 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -1354,37 +1354,32 @@ FloatSize FrameView::viewportSizeForViewportUnits() const { float zoom = frame().pageZoomFactor(); - if (m_frame->settings() && - !RuntimeEnabledFeatures::inertTopControlsEnabled()) { - FloatSize viewportSize; + FloatSize layoutSize; - LayoutViewItem layoutViewItem = this->layoutViewItem(); - if (layoutViewItem.isNull()) - return viewportSize; + LayoutViewItem layoutViewItem = this->layoutViewItem(); + if (layoutViewItem.isNull()) + return layoutSize; - viewportSize.setWidth(layoutViewItem.viewWidth(IncludeScrollbars) / zoom); - viewportSize.setHeight(layoutViewItem.viewHeight(IncludeScrollbars) / zoom); - return viewportSize; + layoutSize.setWidth(layoutViewItem.viewWidth(IncludeScrollbars) / zoom); + layoutSize.setHeight(layoutViewItem.viewHeight(IncludeScrollbars) / zoom); + + if (RuntimeEnabledFeatures::inertTopControlsEnabled()) { + // We use the layoutSize rather than frameRect to calculate viewport units + // so that we get correct results on mobile where the page is laid out into + // a rect that may be larger than the viewport (e.g. the 980px fallback + // width for desktop pages). Since the layout height is statically set to + // be the viewport with browser controls showing, we add the browser + // controls height, compensating for page scale as well, since we want to + // use the viewport with browser controls hidden for vh (to match Safari). + BrowserControls& browserControls = m_frame->host()->browserControls(); + int viewportWidth = m_frame->host()->visualViewport().size().width(); + if (m_frame->isMainFrame() && layoutSize.width() && viewportWidth) { + float pageScaleAtLayoutWidth = viewportWidth / layoutSize.width(); + layoutSize.expand(0, browserControls.height() / pageScaleAtLayoutWidth); + } } - FloatSize size(layoutSize(IncludeScrollbars)); - - // We use the layoutSize rather than frameRect to calculate viewport units - // so that we get correct results on mobile where the page is laid out into - // a rect that may be larger than the viewport (e.g. the 980px fallback - // width for desktop pages). Since the layout height is statically set to - // be the viewport with browser controls showing, we add the browser controls - // height, compensating for page scale as well, since we want to use the - // viewport with browser controls hidden for vh (to match Safari). - BrowserControls& browserControls = m_frame->host()->browserControls(); - int viewportWidth = m_frame->host()->visualViewport().size().width(); - if (m_frame->isMainFrame() && size.width() && viewportWidth) { - float pageScaleAtLayoutWidth = viewportWidth / size.width(); - size.expand(0, browserControls.height() / pageScaleAtLayoutWidth); - } - - size.scale(1 / zoom); - return size; + return layoutSize; } DocumentLifecycle& FrameView::lifecycle() const {
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 68d1351..363c577f 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -832,27 +832,27 @@ } // Do not use acceleration for small canvas. - if (criteria != IgnoreCanvasSizeAccelerationCriteria) { + if (criteria != IgnoreResourceLimitCriteria) { Settings* settings = document().settings(); if (!settings || canvasPixelCount < settings->getMinimumAccelerated2dCanvasSize()) return false; + + // When GPU allocated memory runs low (due to having created too many + // accelerated canvases), the compositor starves and browser becomes laggy. + // Thus, we should stop allocating more GPU memory to new canvases created + // when the current memory usage exceeds the threshold. + if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage) + return false; + + // Allocating too many GPU resources can makes us run into the driver's + // resource limits. So we need to keep the number of texture resources + // under tight control + if (ImageBuffer::getGlobalAcceleratedImageBufferCount() >= + MaxGlobalAcceleratedImageBufferCount) + return false; } - // When GPU allocated memory runs low (due to having created too many - // accelerated canvases), the compositor starves and browser becomes laggy. - // Thus, we should stop allocating more GPU memory to new canvases created - // when the current memory usage exceeds the threshold. - if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage) - return false; - - // Allocating too many GPU resources can makes us run into the driver's - // resource limits. So we need to keep the number of texture resources - // under tight control - if (ImageBuffer::getGlobalAcceleratedImageBufferCount() >= - MaxGlobalAcceleratedImageBufferCount) - return false; - return true; } @@ -1213,7 +1213,7 @@ void HTMLCanvasElement::willDrawImageTo2DContext(CanvasImageSource* source) { if (ExpensiveCanvasHeuristicParameters::EnableAccelerationToAvoidReadbacks && source->isAccelerated() && !buffer()->isAccelerated() && - shouldAccelerate(IgnoreCanvasSizeAccelerationCriteria)) { + shouldAccelerate(IgnoreResourceLimitCriteria)) { OpacityMode opacityMode = m_context->creationAttributes().alpha() ? NonOpaque : Opaque; int msaaSampleCount = 0;
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h index 4025122..f7a7ff5d 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -254,7 +254,7 @@ enum AccelerationCriteria { NormalAccelerationCriteria, - IgnoreCanvasSizeAccelerationCriteria, + IgnoreResourceLimitCriteria, }; bool shouldAccelerate(AccelerationCriteria) const;
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp index 0895da43..d564e57 100644 --- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -289,9 +289,7 @@ } void HTMLLinkElement::scheduleEvent() { - // TODO(hiroshige): Use DOMManipulation task runner. Unthrottled - // is temporarily used for fixing https://crbug.com/649942 only on M-56. - TaskRunnerHelper::get(TaskType::Unthrottled, &document()) + TaskRunnerHelper::get(TaskType::DOMManipulation, &document()) ->postTask( BLINK_FROM_HERE, WTF::bind(
diff --git a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp index 2dfd1d4..8b7d3d5 100644 --- a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -117,9 +117,7 @@ if (m_firedLoad && isLoadEvent) return; m_loadedSheet = isLoadEvent; - // TODO(hiroshige): Use DOMManipulation task runner. Unthrottled - // is temporarily used for fixing https://crbug.com/649942 only on M-56. - TaskRunnerHelper::get(TaskType::Unthrottled, &document()) + TaskRunnerHelper::get(TaskType::DOMManipulation, &document()) ->postTask( BLINK_FROM_HERE, WTF::bind(
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp index 5a716aa9..06ee1ef 100644 --- a/third_party/WebKit/Source/core/html/ImageDocument.cpp +++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -48,6 +48,7 @@ #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" #include "core/loader/resource/ImageResource.h" +#include "core/page/Page.h" #include "platform/HostWindow.h" #include "wtf/text/StringBuilder.h" #include <limits> @@ -594,7 +595,12 @@ } bool ImageDocument::shouldShrinkToFit() const { - return frame()->isMainFrame(); + // WebView automatically resizes to match the contents, causing an infinite + // loop as the contents then resize to match the window. To prevent this, + // disallow images from shrinking to fit for WebViews. + bool isWrapContentWebView = + page() ? page()->settings().getForceZeroLayoutHeight() : false; + return frame()->isMainFrame() && !isWrapContentWebView; } DEFINE_TRACE(ImageDocument) {
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.h b/third_party/WebKit/Source/core/html/ImageDocument.h index c391bdc..8a1575ec 100644 --- a/third_party/WebKit/Source/core/html/ImageDocument.h +++ b/third_party/WebKit/Source/core/html/ImageDocument.h
@@ -53,6 +53,7 @@ void imageClicked(int x, int y); void imageLoaded(); void updateImageStyle(); + bool shouldShrinkToFit() const; DECLARE_VIRTUAL_TRACE(); @@ -70,7 +71,6 @@ void resizeImageToFit(); void restoreImageSize(); bool imageFitsInWindow() const; - bool shouldShrinkToFit() const; // Calculates the image size multiplier that's needed to fit the image to // the window, taking into account page zoom and device scale. float scale() const;
diff --git a/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp b/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp index 28b344e..e7a752d 100644 --- a/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp +++ b/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp
@@ -6,6 +6,7 @@ #include "core/dom/Document.h" #include "core/dom/DocumentParser.h" +#include "core/frame/Settings.h" #include "core/loader/EmptyClients.h" #include "core/testing/DummyPageHolder.h" #include "testing/gtest/include/gtest/gtest.h" @@ -182,4 +183,26 @@ EXPECT_EQ(10, imageHeight()); } +TEST_F(ImageDocumentTest, ImageNotCenteredWithForceZeroLayoutHeight) { + createDocumentWithoutLoadingImage(80, 70); + document().page()->settings().setForceZeroLayoutHeight(true); + loadImage(); + EXPECT_FALSE(document().shouldShrinkToFit()); + EXPECT_EQ(0, document().imageElement()->offsetLeft()); + EXPECT_EQ(0, document().imageElement()->offsetTop()); + EXPECT_EQ(50, imageWidth()); + EXPECT_EQ(50, imageHeight()); +} + +TEST_F(ImageDocumentTest, ImageCenteredWithoutForceZeroLayoutHeight) { + createDocumentWithoutLoadingImage(80, 70); + document().page()->settings().setForceZeroLayoutHeight(false); + loadImage(); + EXPECT_TRUE(document().shouldShrinkToFit()); + EXPECT_EQ(15, document().imageElement()->offsetLeft()); + EXPECT_EQ(10, document().imageElement()->offsetTop()); + EXPECT_EQ(50, imageWidth()); + EXPECT_EQ(50, imageHeight()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp index 7a9dd5b0..049e1e20 100644 --- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -51,6 +51,8 @@ void LayoutGrid::Grid::ensureGridSize(size_t maximumRowSize, size_t maximumColumnSize) { + DCHECK(maximumRowSize <= kGridMaxTracks * 2); + DCHECK(maximumColumnSize <= kGridMaxTracks * 2); const size_t oldRowSize = numTracks(ForRows); if (maximumRowSize > oldRowSize) { m_grid.grow(maximumRowSize);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index c2c7571..238c3b0 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -184,7 +184,6 @@ NGConstraintSpace* constraint_space, NGBreakToken* break_token) : NGLayoutAlgorithm(kBlockLayoutAlgorithm), - layout_state_(kStateInit), style_(style), first_child_(first_child), constraint_space_(constraint_space), @@ -224,136 +223,113 @@ NGPhysicalFragment* child_fragment, NGPhysicalFragment** fragment_out, NGLayoutAlgorithm** algorithm_out) { - switch (layout_state_) { - case kStateInit: { - WTF::Optional<MinAndMaxContentSizes> sizes; - if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { - sizes = MinAndMaxContentSizes(); - ComputeMinAndMaxContentSizes(&*sizes); - } + WTF::Optional<MinAndMaxContentSizes> sizes; + if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { + // TODO(ikilpatrick): Change ComputeMinAndMaxContentSizes to return + // MinAndMaxContentSizes. + sizes = MinAndMaxContentSizes(); + ComputeMinAndMaxContentSizes(&*sizes); + } - border_and_padding_ = - ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); + border_and_padding_ = + ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); - LayoutUnit inline_size = - ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); - LayoutUnit adjusted_inline_size = - inline_size - border_and_padding_.InlineSum(); - // TODO(layout-ng): For quirks mode, should we pass blockSize instead of - // -1? - LayoutUnit block_size = ComputeBlockSizeForFragment( - ConstraintSpace(), Style(), NGSizeIndefinite); - LayoutUnit adjusted_block_size(block_size); - // Our calculated block-axis size may be indefinite at this point. - // If so, just leave the size as NGSizeIndefinite instead of subtracting - // borders and padding. - if (adjusted_block_size != NGSizeIndefinite) - adjusted_block_size -= border_and_padding_.BlockSum(); + LayoutUnit inline_size = + ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); + LayoutUnit adjusted_inline_size = + inline_size - border_and_padding_.InlineSum(); + // TODO(layout-ng): For quirks mode, should we pass blockSize instead of + // -1? + LayoutUnit block_size = + ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); + LayoutUnit adjusted_block_size(block_size); + // Our calculated block-axis size may be indefinite at this point. + // If so, just leave the size as NGSizeIndefinite instead of subtracting + // borders and padding. + if (adjusted_block_size != NGSizeIndefinite) + adjusted_block_size -= border_and_padding_.BlockSum(); - space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); - if (Style().specifiesColumns()) { - space_builder_->SetFragmentationType(kFragmentColumn); - adjusted_inline_size = - ResolveUsedColumnInlineSize(adjusted_inline_size, Style()); - LayoutUnit inline_progression = - adjusted_inline_size + ResolveUsedColumnGap(Style()); - fragmentainer_mapper_ = - new NGColumnMapper(inline_progression, adjusted_block_size); - } - space_builder_->SetAvailableSize( - NGLogicalSize(adjusted_inline_size, adjusted_block_size)); - space_builder_->SetPercentageResolutionSize( - NGLogicalSize(adjusted_inline_size, adjusted_block_size)); + space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); + if (Style().specifiesColumns()) { + space_builder_->SetFragmentationType(kFragmentColumn); + adjusted_inline_size = + ResolveUsedColumnInlineSize(adjusted_inline_size, Style()); + LayoutUnit inline_progression = + adjusted_inline_size + ResolveUsedColumnGap(Style()); + fragmentainer_mapper_ = + new NGColumnMapper(inline_progression, adjusted_block_size); + } + space_builder_->SetAvailableSize( + NGLogicalSize(adjusted_inline_size, adjusted_block_size)); + space_builder_->SetPercentageResolutionSize( + NGLogicalSize(adjusted_inline_size, adjusted_block_size)); - builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); - builder_->SetDirection(constraint_space_->Direction()); - builder_->SetWritingMode(constraint_space_->WritingMode()); - builder_->SetInlineSize(inline_size).SetBlockSize(block_size); + builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); + builder_->SetDirection(constraint_space_->Direction()); + builder_->SetWritingMode(constraint_space_->WritingMode()); + builder_->SetInlineSize(inline_size).SetBlockSize(block_size); - if (NGBlockBreakToken* token = CurrentBlockBreakToken()) { - // Resume after a previous break. - content_size_ = token->BreakOffset(); - current_child_ = token->InputNode(); - } else { - content_size_ = border_and_padding_.block_start; - current_child_ = first_child_; - } + if (NGBlockBreakToken* token = CurrentBlockBreakToken()) { + // Resume after a previous break. + content_size_ = token->BreakOffset(); + current_child_ = token->InputNode(); + } else { + content_size_ = border_and_padding_.block_start; + current_child_ = first_child_; + } - layout_state_ = kStatePrepareForChildLayout; - return kNotFinished; + while (current_child_) { + EPosition position = current_child_->Style()->position(); + if (position == AbsolutePosition || position == FixedPosition) { + builder_->AddOutOfFlowChildCandidate(current_child_, + GetChildSpaceOffset()); + current_child_ = current_child_->NextSibling(); + continue; } - case kStatePrepareForChildLayout: { - if (current_child_) { - EPosition position = current_child_->Style()->position(); - if ((position == AbsolutePosition || position == FixedPosition)) { - builder_->AddOutOfFlowChildCandidate(current_child_, - GetChildSpaceOffset()); - current_child_ = current_child_->NextSibling(); - return kNotFinished; - } - DCHECK(!ConstraintSpace().HasBlockFragmentation() || - SpaceAvailableForCurrentChild() > LayoutUnit()); - space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); - *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( - current_child_, space_for_current_child_); - layout_state_ = kStateChildLayout; - return kChildAlgorithmRequired; - } - // Prepare for kStateOutOfFlowLayout - content_size_ += border_and_padding_.block_end; + DCHECK(!ConstraintSpace().HasBlockFragmentation() || + SpaceAvailableForCurrentChild() > LayoutUnit()); + space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); - // Recompute the block-axis size now that we know our content size. - LayoutUnit block_size = ComputeBlockSizeForFragment( - ConstraintSpace(), Style(), content_size_); - builder_->SetBlockSize(block_size); + NGFragment* fragment; + current_child_->LayoutSync(space_for_current_child_, &fragment); + NGPhysicalFragment* child_fragment = fragment->PhysicalFragment(); - // Out of flow setup. - out_of_flow_layout_ = - new NGOutOfFlowLayoutPart(&Style(), builder_->Size()); - builder_->GetAndClearOutOfFlowDescendantCandidates( - &out_of_flow_candidates_, &out_of_flow_candidate_positions_); - out_of_flow_candidate_positions_index_ = 0; - current_child_ = nullptr; - layout_state_ = kStateOutOfFlowLayout; - return kNotFinished; - } - case kStateChildLayout: { - DCHECK(current_child_); - DCHECK(child_fragment); + // TODO(layout_ng): Seems like a giant hack to call this here. + current_child_->UpdateLayoutBox(toNGPhysicalBoxFragment(child_fragment), + space_for_current_child_); - // TODO(layout_ng): Seems like a giant hack to call this here. - current_child_->UpdateLayoutBox(toNGPhysicalBoxFragment(child_fragment), - space_for_current_child_); + FinishCurrentChildLayout(new NGBoxFragment( + ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), + toNGPhysicalBoxFragment(child_fragment))); - FinishCurrentChildLayout(new NGBoxFragment( - ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), - toNGPhysicalBoxFragment(child_fragment))); + if (!ProceedToNextUnfinishedSibling(child_fragment)) + break; + } - if (ProceedToNextUnfinishedSibling(child_fragment)) - layout_state_ = kStatePrepareForChildLayout; - else - layout_state_ = kStateFinalize; - return kNotFinished; - } - case kStateOutOfFlowLayout: - if (LayoutOutOfFlowChild()) - layout_state_ = kStateFinalize; - return kNotFinished; - case kStateFinalize: { - builder_->SetInlineOverflow(max_inline_size_) - .SetBlockOverflow(content_size_); + content_size_ += border_and_padding_.block_end; - if (ConstraintSpace().HasBlockFragmentation()) - FinalizeForFragmentation(); + // Recompute the block-axis size now that we know our content size. + block_size = + ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); + builder_->SetBlockSize(block_size); - *fragment_out = builder_->ToBoxFragment(); - layout_state_ = kStateInit; - return kNewFragment; - } - }; - NOTREACHED(); - *fragment_out = nullptr; + // Out of flow setup. + out_of_flow_layout_ = new NGOutOfFlowLayoutPart(&Style(), builder_->Size()); + builder_->GetAndClearOutOfFlowDescendantCandidates( + &out_of_flow_candidates_, &out_of_flow_candidate_positions_); + out_of_flow_candidate_positions_index_ = 0; + current_child_ = nullptr; + + while (!LayoutOutOfFlowChild()) + continue; + + builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); + + if (ConstraintSpace().HasBlockFragmentation()) + FinalizeForFragmentation(); + + *fragment_out = builder_->ToBoxFragment(); return kNewFragment; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 17f33e9..78dc3510 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -146,15 +146,6 @@ const ComputedStyle& Style() const { return *style_; } - enum LayoutState { - kStateInit, - kStatePrepareForChildLayout, - kStateChildLayout, - kStateOutOfFlowLayout, - kStateFinalize - }; - LayoutState layout_state_; - RefPtr<const ComputedStyle> style_; Member<NGBlockNode> first_child_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index 905b8b4..f08222e7 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -40,13 +40,11 @@ NGBlockNode parent(style_.get()); parent.SetFirstChild(first_child); - NGLayoutCoordinator coordinator(&parent, space); + NGBlockLayoutAlgorithm algorithm(style_.get(), first_child, space); + NGPhysicalFragment* fragment; - coordinator.Tick(&fragment); - EXPECT_EQ(kBlockLayoutAlgorithm, - coordinator.GetAlgorithmStackForTesting()[0]->algorithmType()); - while (!coordinator.Tick(&fragment)) - ; + NGLayoutAlgorithm* not_used; + EXPECT_EQ(kNewFragment, algorithm.Layout(nullptr, &fragment, ¬_used)); return toNGPhysicalBoxFragment(fragment); }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp index 6bfb64b4..6cb6483 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
@@ -19,10 +19,6 @@ #include "core/layout/svg/LayoutSVGResourceContainer.h" -#include "core/SVGElementTypeHelpers.h" -#include "core/layout/svg/LayoutSVGResourceClipper.h" -#include "core/layout/svg/LayoutSVGResourceFilter.h" -#include "core/layout/svg/LayoutSVGResourceMasker.h" #include "core/layout/svg/SVGResources.h" #include "core/layout/svg/SVGResourcesCache.h" #include "core/svg/SVGElementProxy.h" @@ -249,14 +245,7 @@ ASSERT(object); if (SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(object)) { - if (LayoutSVGResourceFilter* filter = resources->filter()) - filter->removeClientFromCache(object); - - if (LayoutSVGResourceMasker* masker = resources->masker()) - masker->removeClientFromCache(object); - - if (LayoutSVGResourceClipper* clipper = resources->clipper()) - clipper->removeClientFromCache(object); + resources->removeClientFromCacheAffectingObjectBounds(object); } if (!object->node() || !object->node()->isSVGElement())
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp index 0602e8ac..30ea7c3 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp
@@ -323,6 +323,19 @@ m_linkedResource->layoutIfNeeded(); } +void SVGResources::removeClientFromCacheAffectingObjectBounds( + LayoutObject* object, + bool markForInvalidation) const { + if (!m_clipperFilterMaskerData) + return; + if (LayoutSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper) + clipper->removeClientFromCache(object, markForInvalidation); + if (LayoutSVGResourceFilter* filter = m_clipperFilterMaskerData->filter) + filter->removeClientFromCache(object, markForInvalidation); + if (LayoutSVGResourceMasker* masker = m_clipperFilterMaskerData->masker) + masker->removeClientFromCache(object, markForInvalidation); +} + void SVGResources::removeClientFromCache(LayoutObject* object, bool markForInvalidation) const { if (!hasResourceData()) @@ -336,17 +349,7 @@ return; } - if (m_clipperFilterMaskerData) { - if (m_clipperFilterMaskerData->clipper) - m_clipperFilterMaskerData->clipper->removeClientFromCache( - object, markForInvalidation); - if (m_clipperFilterMaskerData->filter) - m_clipperFilterMaskerData->filter->removeClientFromCache( - object, markForInvalidation); - if (m_clipperFilterMaskerData->masker) - m_clipperFilterMaskerData->masker->removeClientFromCache( - object, markForInvalidation); - } + removeClientFromCacheAffectingObjectBounds(object, markForInvalidation); if (m_markerData) { if (m_markerData->markerStart)
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.h b/third_party/WebKit/Source/core/layout/svg/SVGResources.h index 62a88c68..07cfa56 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.h
@@ -93,6 +93,9 @@ // Methods operating on all cached resources void removeClientFromCache(LayoutObject*, bool markForInvalidation = true) const; + void removeClientFromCacheAffectingObjectBounds( + LayoutObject*, + bool markForInvalidation = true) const; void resourceDestroyed(LayoutSVGResourceContainer*); #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp index ef1fcb2..426de330 100644 --- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp +++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -53,6 +53,8 @@ } PrePaintTreeWalkContext context(parentContext); + // ancestorOverflowLayer does not cross frame boundaries. + context.ancestorOverflowPaintLayer = nullptr; m_propertyTreeBuilder.updateProperties(frameView, context.treeBuilderContext); m_paintInvalidator.invalidatePaintIfNeeded(frameView, context.paintInvalidatorContext);
diff --git a/third_party/WebKit/Source/core/style/GridArea.h b/third_party/WebKit/Source/core/style/GridArea.h index bbc1f97e..daa3a00 100644 --- a/third_party/WebKit/Source/core/style/GridArea.h +++ b/third_party/WebKit/Source/core/style/GridArea.h
@@ -34,13 +34,18 @@ #include "core/style/GridPositionsResolver.h" #include "wtf/Allocator.h" #include "wtf/HashMap.h" +#include "wtf/MathExtras.h" #include "wtf/text/WTFString.h" #include <algorithm> namespace blink { -// Recommended maximum size for both explicit and implicit grids. -const int kGridMaxTracks = 1000000; +// Recommended maximum size for both explicit and implicit grids. Note that this +// actually allows a [-9999,9999] range. The limit is low on purpouse because +// higher values easly trigger OOM situations. That will definitely improve once +// we switch from a vector of vectors based grid representation to a more +// efficient one memory-wise. +const int kGridMaxTracks = 1000; // A span in a single direction (either rows or columns). Note that |startLine| // and |endLine| are grid lines' indexes. @@ -141,15 +146,8 @@ } #endif - if (startLine >= 0) - m_startLine = std::min(startLine, kGridMaxTracks - 1); - else - m_startLine = std::max(startLine, -kGridMaxTracks); - - if (endLine >= 0) - m_endLine = std::min(endLine, kGridMaxTracks); - else - m_endLine = std::max(endLine, -kGridMaxTracks + 1); + m_startLine = clampTo<int>(startLine, -kGridMaxTracks, kGridMaxTracks - 1); + m_endLine = clampTo<int>(endLine, -kGridMaxTracks + 1, kGridMaxTracks); } int m_startLine;
diff --git a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp index 9d1027e..0d78f5b 100644 --- a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp +++ b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.cpp
@@ -4,7 +4,6 @@ #include "modules/geolocation/GeoNotifier.h" -#include "core/dom/TaskRunnerHelper.h" #include "modules/geolocation/Geolocation.h" #include "modules/geolocation/PositionError.h" #include "modules/geolocation/PositionOptions.h" @@ -21,10 +20,7 @@ m_successCallback(successCallback), m_errorCallback(errorCallback), m_options(options), - m_timer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, - geolocation->frame()), - this, - &GeoNotifier::timerFired), + m_timer(this, &GeoNotifier::timerFired), m_useCachedPosition(false) { DCHECK(m_geolocation); DCHECK(m_successCallback);
diff --git a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.h b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.h index ee91c10..e254fe1e 100644 --- a/third_party/WebKit/Source/modules/geolocation/GeoNotifier.h +++ b/third_party/WebKit/Source/modules/geolocation/GeoNotifier.h
@@ -61,7 +61,7 @@ Member<PositionCallback> m_successCallback; Member<PositionErrorCallback> m_errorCallback; const PositionOptions m_options; - TaskRunnerTimer<GeoNotifier> m_timer; + Timer<GeoNotifier> m_timer; Member<PositionError> m_fatalError; bool m_useCachedPosition; };
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp index f13bc61..5474f282 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp
@@ -621,7 +621,7 @@ } if (context() != destination->context()) { - exceptionState.throwDOMException(SyntaxError, + exceptionState.throwDOMException(InvalidAccessError, "cannot connect to a destination " "belonging to a different audio context."); return nullptr;
diff --git a/third_party/WebKit/Source/web/WebFrameSerializer.cpp b/third_party/WebKit/Source/web/WebFrameSerializer.cpp index 9a266f1d..35eb693 100644 --- a/third_party/WebKit/Source/web/WebFrameSerializer.cpp +++ b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
@@ -110,11 +110,12 @@ // be excluded: // 1) All elements that are head or part of head, including head, meta, style, // link and etc. - // 2) Some specific elements in body: meta, datalist, option and etc. + // 2) Some specific elements in body: meta, style, datalist, option and etc. if (element.layoutObject()) return false; if (isHTMLHeadElement(element) || isHTMLMetaElement(element) || - isHTMLDataListElement(element) || isHTMLOptionElement(element)) { + isHTMLStyleElement(element) || isHTMLDataListElement(element) || + isHTMLOptionElement(element)) { return false; } Element* parent = element.parentElement();
diff --git a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp index 41abdf2..23af6aca 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp
@@ -266,6 +266,8 @@ EXPECT_NE(WTF::kNotFound, mhtml.find("<option")); // One for meta in head and another for meta in body. EXPECT_EQ(2, matchSubstring(mhtml, "<meta", 5)); + // One for style in head and another for style in body. + EXPECT_EQ(2, matchSubstring(mhtml, "<style", 6)); // These hidden elements that affect layout should remain intact. EXPECT_NE(WTF::kNotFound, mhtml.find("<h2"));
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 7929d8fa..5ceb8a0a 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -4335,7 +4335,10 @@ WebURL baseURL = URLTestHelpers::toKURL("http://example.com/"); FrameTestHelpers::loadHTMLString(webView->mainFrame(), - "<style>#vw { width: 100vw }</style>" + "<style>" + " body { margin: 0px; }" + " #vw { width: 100vw; height: 100vh; }" + "</style>" "<div id=vw></div>", baseURL); @@ -4345,16 +4348,36 @@ EXPECT_EQ(800, vwElement->offsetWidth()); + FloatSize pageSize(300, 360); + WebPrintParams printParams; - printParams.printContentArea.width = 500; - printParams.printContentArea.height = 500; + printParams.printContentArea.width = pageSize.width(); + printParams.printContentArea.height = pageSize.height(); + + // This needs to match printingMinimumShrinkFactor in PrintContext.cpp. The + // layout is scaled by this factor for printing. + constexpr float minimumShrinkFactor = 1.333f; + + // The expected layout size comes from the calculation done in + // resizePageRectsKeepingRatio which is used from PrintContext::begin to + // scale the page size. + const float ratio = pageSize.height() / (float)pageSize.width(); + const int expectedWidth = floor(pageSize.width() * minimumShrinkFactor); + const int expectedHeight = floor(expectedWidth * ratio); frame->printBegin(printParams, WebNode()); - webView->resize(WebSize(500, 500)); - EXPECT_EQ(500, vwElement->offsetWidth()); + + EXPECT_EQ(expectedWidth, vwElement->offsetWidth()); + EXPECT_EQ(expectedHeight, vwElement->offsetHeight()); + + webView->resize(flooredIntSize(pageSize)); + + EXPECT_EQ(expectedWidth, vwElement->offsetWidth()); + EXPECT_EQ(expectedHeight, vwElement->offsetHeight()); webView->resize(WebSize(800, 600)); frame->printEnd(); + EXPECT_EQ(800, vwElement->offsetWidth()); }
diff --git a/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html b/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html index 7dfe41d..465fc7a 100644 --- a/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html +++ b/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html
@@ -22,6 +22,9 @@ </datalist> </form> <div itemscope> + <style> + #foo { display: block;} + </style> <meta itemprop="name" content="value"> </div> </body>
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py index 9e5f9f8..a47a9381 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py
@@ -46,19 +46,16 @@ A list of try job result dicts, or None if a timeout occurred. """ start = self._host.time() - self._host.print_('Waiting for try jobs (timeout: %d s, poll interval %d s).' % - (timeout_seconds, poll_delay_seconds)) + self._host.print_('Waiting for try jobs (timeout: %d seconds).' % timeout_seconds) while self._host.time() - start < timeout_seconds: self._host.sleep(poll_delay_seconds) try_results = self.fetch_try_results() _log.debug('Fetched try results: %s', try_results) if self.all_jobs_finished(try_results): - self._host.print_() self._host.print_('All jobs finished.') return try_results - self._host.print_('.', end='') + self._host.print_('Waiting. %d seconds passed.' % (self._host.time() - start)) self._host.sleep(poll_delay_seconds) - self._host.print_() self._host.print_('Timed out waiting for try results.') return None
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py index ee9c1db4..7c47ebc 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py
@@ -63,8 +63,14 @@ git_cl.wait_for_try_jobs() self.assertEqual( host.stdout.getvalue(), - 'Waiting for try jobs (timeout: 7200 s, poll interval 600 s).\n' - '......\nTimed out waiting for try results.\n') + 'Waiting for try jobs (timeout: 7200 seconds).\n' + 'Waiting. 600 seconds passed.\n' + 'Waiting. 1800 seconds passed.\n' + 'Waiting. 3000 seconds passed.\n' + 'Waiting. 4200 seconds passed.\n' + 'Waiting. 5400 seconds passed.\n' + 'Waiting. 6600 seconds passed.\n' + 'Timed out waiting for try results.\n') def test_wait_for_try_jobs_done(self): host = MockHost() @@ -79,7 +85,7 @@ git_cl.wait_for_try_jobs() self.assertEqual( host.stdout.getvalue(), - 'Waiting for try jobs (timeout: 7200 s, poll interval 600 s).\n\n' + 'Waiting for try jobs (timeout: 7200 seconds).\n' 'All jobs finished.\n') def test_all_jobs_finished_with_started_jobs(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py index 1264ec2..e1745e3 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
@@ -58,18 +58,26 @@ _log.info('Noting the current Chromium commit.') _, show_ref_output = self.run(['git', 'show-ref', 'HEAD']) - chromium_commitish = show_ref_output.split()[0] + chromium_commit = show_ref_output.split()[0] if options.target == 'wpt': - import_commitish = self.update(WPT_DEST_NAME, WPT_REPO_URL, options.keep_w3c_repos_around, options.revision) + import_commit = self.update(WPT_DEST_NAME, WPT_REPO_URL, options.keep_w3c_repos_around, options.revision) self._copy_resources() elif options.target == 'css': - import_commitish = self.update(CSS_DEST_NAME, CSS_REPO_URL, options.keep_w3c_repos_around, options.revision) + import_commit = self.update(CSS_DEST_NAME, CSS_REPO_URL, options.keep_w3c_repos_around, options.revision) else: raise AssertionError("Unsupported target %s" % options.target) - has_changes = self.commit_changes_if_needed(chromium_commitish, import_commitish) - if options.auto_update and has_changes: + has_changes = self._has_changes() + if not has_changes: + _log.info('Done: no changes to import.') + return 0 + + commit_message = self._commit_message(chromium_commit, import_commit) + self._commit_changes(commit_message) + _log.info('Done: changes imported and committed.') + + if options.auto_update: commit_successful = self.do_auto_update() if not commit_successful: return 1 @@ -229,36 +237,28 @@ return '%s@%s' % (dest_dir_name, master_commitish) - def commit_changes_if_needed(self, chromium_commitish, import_commitish): - if self.run(['git', 'diff', '--quiet', 'HEAD'], exit_on_failure=False)[0]: - _log.info('Committing changes.') - commit_msg = ('Import %s\n' - '\n' - 'Using update-w3c-deps in Chromium %s.\n' - % (import_commitish, chromium_commitish)) - path_to_commit_msg = self.path_from_webkit_base('commit_msg') - _log.debug('cat > %s <<EOF', path_to_commit_msg) - _log.debug(commit_msg) - _log.debug('EOF') - self.fs.write_text_file(path_to_commit_msg, commit_msg) - self.run(['git', 'commit', '-a', '-F', path_to_commit_msg]) - self.remove(path_to_commit_msg) - _log.info('Done: changes imported and committed.') - return True - else: - _log.info('Done: no changes to import.') - return False + def _commit_changes(self, commit_message): + _log.info('Committing changes.') + self.run(['git', 'commit', '--all', '-F', '-'], stdin=commit_message) + + def _has_changes(self): + return_code, _ = self.run(['git', 'diff', '--quiet', 'HEAD'], exit_on_failure=False) + return return_code == 1 + + def _commit_message(self, chromium_commit, import_commit): + return ('Import %s\n\nUsing update-w3c-deps in Chromium %s.\n\n' % + (import_commit, chromium_commit)) @staticmethod def is_baseline(basename): return basename.endswith('-expected.txt') - def run(self, cmd, exit_on_failure=True, cwd=None): + def run(self, cmd, exit_on_failure=True, cwd=None, stdin=''): _log.debug('Running command: %s', ' '.join(cmd)) cwd = cwd or self.finder.webkit_base() - proc = self.executive.popen(cmd, stdout=self.executive.PIPE, stderr=self.executive.PIPE, cwd=cwd) - out, err = proc.communicate() + proc = self.executive.popen(cmd, stdout=self.executive.PIPE, stderr=self.executive.PIPE, stdin=self.executive.PIPE) + out, err = proc.communicate(stdin) if proc.returncode or self.verbose: _log.info('# ret> %d', proc.returncode) if out:
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py index 8b0c9ea7..f5524fe 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
@@ -62,6 +62,21 @@ # Tests for protected methods - pylint: disable=protected-access + def test_commit_changes(self): + host = MockHost() + updater = DepsUpdater(host) + updater._has_changes = lambda: True + updater._commit_changes('dummy message') + self.assertEqual( + host.executive.calls, + [['git', 'commit', '--all', '-F', '-']]) + + def test_commit_message(self): + updater = DepsUpdater(MockHost()) + self.assertEqual( + updater._commit_message('aaaa', '1111'), + 'Import 1111\n\nUsing update-w3c-deps in Chromium aaaa.\n\n') + def test_cl_description_with_empty_environ(self): host = MockHost() host.executive = MockExecutive(output='Last commit message\n')
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index 44383523..5a0d644 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -470,7 +470,7 @@ // from gen/, which is problematic, but DevTools folks don't want to rename // it or split this up. So don't rename it at all. if (name.equals("disable") && - IsMethodOverrideOf(decl, "blink::InspectorAgent")) + IsMethodOverrideOf(decl, "blink::InspectorBaseAgent")) return true; return false;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index fddeff3a..25b765f 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -20398,6 +20398,15 @@ </summary> </histogram> +<histogram name="GPU.ShaderLoadPrefixOK" enum="BooleanMatched"> + <owner>ericrk@chromium.org</owner> + <summary> + Whether or not the shader prefix loaded from disk matched the expected + prefix for the data and system configuration. False indicates either disk + corruption or a system configuration change, and should be rare. + </summary> +</histogram> + <histogram name="GPU.TextureRG" enum="BooleanAvailable"> <owner>reveman@chromium.org</owner> <summary> @@ -26205,6 +26214,11 @@ </histogram> <histogram name="Media.Video.TimeFromForegroundToFirstFrame" units="ms"> + <obsolete> + Deprecated as of 01/18/2017 in issue 670150. Replaced by + Media.Video.TimeFromForegroundToFirstFrame.DisabledTrack and + Media.Video.TimeFromForegroundToFirstFrame.Paused. + </obsolete> <owner>avayvod@chromium.org</owner> <owner>dalecurtis@chromium.org</owner> <summary> @@ -26213,6 +26227,30 @@ </summary> </histogram> +<histogram name="Media.Video.TimeFromForegroundToFirstFrame.DisabledTrack" + units="ms"> + <owner>avayvod@chromium.org</owner> + <owner>dalecurtis@chromium.org</owner> + <summary> + Records the time between the moment when the video element that had video + track disabled in the background is brought to the foreground and when the + video frame compositor outputs the next frame. Recorded even if disabling + video track in the background is turned off to collect data for the control + group. + </summary> +</histogram> + +<histogram name="Media.Video.TimeFromForegroundToFirstFrame.Paused" units="ms"> + <owner>avayvod@chromium.org</owner> + <owner>dalecurtis@chromium.org</owner> + <summary> + Records the time between the moment when the video element that was paused + in the background is brought to the foreground and when the video frame + compositor outputs the next frame. Recorded even if disabling pausing video + in the background is turned off to collect data for the control group. + </summary> +</histogram> + <histogram name="Media.VideoCapture.AspectRatio" units="%"> <owner>mcasas@chromium.org</owner> <summary>
diff --git a/tools/perf/generate_perf_json.py b/tools/perf/generate_perf_json.py index 2da1808..348ba22d 100755 --- a/tools/perf/generate_perf_json.py +++ b/tools/perf/generate_perf_json.py
@@ -412,6 +412,19 @@ ] } ]) + waterfall = add_tester( + waterfall, 'Mac Mini 8GB 10.12 Perf', + 'chromium-rel-mac12-mini-8gb', 'mac', + swarming=[ + { + 'gpu': '8086:0a26', + 'os': 'Mac-10.12', + 'device_ids': [ + 'build24-b1', 'build25-b1', + 'build26-b1', 'build27-b1', 'build28-b1' + ] + } + ]) waterfall = add_tester( waterfall, 'Linux Perf', 'linux-release', 'linux',
diff --git a/ui/events/ozone/evdev/scoped_input_device.h b/ui/events/ozone/evdev/scoped_input_device.h index 24d8aa58..5278dd0 100644 --- a/ui/events/ozone/evdev/scoped_input_device.h +++ b/ui/events/ozone/evdev/scoped_input_device.h
@@ -6,11 +6,12 @@ #define UI_EVENTS_OZONE_EVDEV_SCOPED_INPUT_DEVICE_H_ #include "base/scoped_generic.h" +#include "ui/events/ozone/evdev/events_ozone_evdev_export.h" namespace ui { namespace internal { -struct ScopedInputDeviceCloseTraits { +struct EVENTS_OZONE_EVDEV_EXPORT ScopedInputDeviceCloseTraits { static int InvalidValue() { return -1; } static void Free(int fd); };
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js index 85e8297f..37746d0 100644 --- a/ui/login/account_picker/user_pod_row.js +++ b/ui/login/account_picker/user_pod_row.js
@@ -89,11 +89,13 @@ * @const */ var UserPodTabOrder = { - POD_INPUT: 1, // Password input field, Action box menu button, and - // the pod itself. - POD_CUSTOM_ICON: 2, // Pod custom icon next to password input field. - HEADER_BAR: 3, // Buttons on the header bar (Shutdown, Add User). - POD_MENU_ITEM: 4 // User pad menu items (User info, Remove user). + POD_INPUT: 1, // Password input field, Action box menu button, submit + // button next to password input field and the pod + // itself. + PIN_KEYBOARD: 2, // Pin keyboard below the password input field. + POD_CUSTOM_ICON: 3, // Pod custom icon next to password input field. + HEADER_BAR: 4, // Buttons on the header bar (Shutdown, Add User). + POD_MENU_ITEM: 5 // User pad menu items (User info, Remove user). }; /** @@ -722,6 +724,7 @@ this.pinKeyboard.passwordElement = this.passwordElement; this.pinKeyboard.addEventListener('pin-change', this.handleInputChanged_.bind(this)); + this.pinKeyboard.tabIndex = UserPodTabOrder.PIN_KEYBOARD; } this.actionBoxAreaElement.addEventListener('mousedown', @@ -767,6 +770,7 @@ if (this.submitButton) { this.submitButton.addEventListener('click', this.handleSubmitButtonClick_.bind(this)); + this.submitButton.tabIndex = UserPodTabOrder.POD_INPUT; } this.imageElement.addEventListener('load',