diff --git a/DEPS b/DEPS index bdeef9c..32f03b7 100644 --- a/DEPS +++ b/DEPS
@@ -91,7 +91,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': '0b0dcbc1cffaa47fd225a9276c5cd4e48c2ca891', + 'angle_revision': '41918387cc52553defbfc10ed30b504e628b6fe4', # 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. @@ -103,7 +103,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': '40c223e4ed41e991f81281ca08b3085e218c52dc', + 'pdfium_revision': 'd1ffda2acaee90a7b8a6dd36e0605dce826058e9', # 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. @@ -135,7 +135,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': '6c4a8ca2e9bc7d1d8fc526efe3c2e8ce087b730c', + 'catapult_revision': '1446cf3fe8a3b827432365c3fdaf902d6bd033a7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -206,7 +206,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '7d2e0214553aba8b5bb09fbe023df0f0dc48005a', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'dd21af4fef24ddb42d39e9610b84109273c50899', 'condition': 'checkout_ios', }, @@ -397,7 +397,7 @@ }, 'src/third_party/googletest/src': - Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '703b4a85a21e394252560a89cc856b384b48c286', + Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + 'a325ad2db5deb623eab740527e559b81c0f39d65', # GNU binutils assembler for x86-32. 'src/third_party/gnu_binutils': { @@ -657,7 +657,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '3c1cb0203b6cfc10389e85a350b2ea6ca29d01ce', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'a12b1d625cc992de704b9947c4d11957ebfbc0f8', # commit position 21742 + Var('webrtc_git') + '/src.git' + '@' + '853715c9a90611486aa191219a103a4acd7a664f', # commit position 21742 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1004,7 +1004,7 @@ ] }, { - 'name': 'content_shell_fonts', + 'name': 'test_fonts', 'pattern': '.', 'condition': 'checkout_linux or (checkout_android or checkout_fuchsia)', 'action': [ 'download_from_google_storage', @@ -1012,7 +1012,7 @@ '--extract', '--no_auth', '--bucket', 'chromium-fonts', - '-s', 'src/third_party/content_shell_fonts/content_shell_test_fonts.tar.gz.sha1', + '-s', 'src/third_party/test_fonts/test_fonts.tar.gz.sha1', ], }, # Pull order files for the win/clang build.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java index c52deb4..17259197 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
@@ -21,7 +21,6 @@ import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.TestFileUtil; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper; @@ -971,7 +970,6 @@ @Test @SmallTest @Feature({"AndroidWebView"}) - @DisabledTest // Enable when renderer-side navigation is removed. crbug.com/769126 public void testLoadDataWithBaseUrlTriggersShouldInterceptRequest() throws Throwable { String data = "foo"; String mimeType = "text/plain"; @@ -984,7 +982,7 @@ mContentsClient.getOnPageFinishedHelper(), data, mimeType, isBase64Encoded, baseUrl, historyUrl); Assert.assertEquals(callCount + 1, mShouldInterceptRequestHelper.getCallCount()); - // Not checking the URL yet. It's the empty data URL which should be fixed in + // TODO(boliu): Not checking the URL yet. It's the empty data URL which should be fixed in // crbug.com/669885. }
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 7c898725..5d46ea4 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -508,7 +508,7 @@ display::Screen::GetScreen() ->GetDisplayNearestWindow(Shell::GetRootWindowForNewWindows()) .id(), - app_list::kSearchKey); + app_list::kSearchKey, accelerator.time_stamp()); } void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 2422a61e..46059a28 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -250,7 +250,7 @@ } void AppListControllerImpl::DismissAppList() { - presenter_.Dismiss(); + presenter_.Dismiss(base::TimeTicks()); } void AppListControllerImpl::GetAppInfoDialogBounds( @@ -270,7 +270,7 @@ // TODO(calamity): This may cause the app list to show briefly before the // state change. If this becomes an issue, add the ability to ash::Shell to // load the app list without showing it. - presenter_.Show(GetDisplayIdToShowAppListOn()); + presenter_.Show(GetDisplayIdToShowAppListOn(), base::TimeTicks()); app_list_was_open = false; app_list_view = presenter_.GetView(); DCHECK(app_list_view); @@ -285,7 +285,7 @@ } void AppListControllerImpl::ShowAppList() { - presenter_.Show(GetDisplayIdToShowAppListOn()); + presenter_.Show(GetDisplayIdToShowAppListOn(), base::TimeTicks()); } //////////////////////////////////////////////////////////////////////////////// @@ -318,10 +318,11 @@ } void AppListControllerImpl::Show(int64_t display_id, - app_list::AppListShowSource show_source) { + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp) { UMA_HISTOGRAM_ENUMERATION(app_list::kAppListToggleMethodHistogram, show_source, app_list::kMaxAppListToggleMethod); - presenter_.Show(display_id); + presenter_.Show(display_id, event_time_stamp); } void AppListControllerImpl::UpdateYPositionAndOpacity( @@ -343,12 +344,13 @@ void AppListControllerImpl::ToggleAppList( int64_t display_id, - app_list::AppListShowSource show_source) { + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp) { if (!IsVisible()) { UMA_HISTOGRAM_ENUMERATION(app_list::kAppListToggleMethodHistogram, show_source, app_list::kMaxAppListToggleMethod); } - presenter_.ToggleAppList(display_id); + presenter_.ToggleAppList(display_id, event_time_stamp); } app_list::AppListViewState AppListControllerImpl::GetAppListViewState() {
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index efe3fc49..3f47f4a 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -101,13 +101,16 @@ // Methods used in ash: bool GetTargetVisibility() const; bool IsVisible() const; - void Show(int64_t display_id, app_list::AppListShowSource show_source); + void Show(int64_t display_id, + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp); void UpdateYPositionAndOpacity(int y_position_in_screen, float background_opacity); void EndDragFromShelf(app_list::AppListViewState app_list_state); void ProcessMouseWheelEvent(const ui::MouseWheelEvent& event); void ToggleAppList(int64_t display_id, - app_list::AppListShowSource show_source); + app_list::AppListShowSource show_source, + base::TimeTicks event_time_stamp); app_list::AppListViewState GetAppListViewState(); // Methods of |client_|:
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc index f10d1b5..e167c53 100644 --- a/ash/app_list/app_list_presenter_delegate.cc +++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -198,7 +198,7 @@ aura::Window* window = view_->GetWidget()->GetNativeView()->parent(); if (!window->Contains(target) && !presenter_->Back() && !app_list::switches::ShouldNotDismissOnBlur()) { - presenter_->Dismiss(); + presenter_->Dismiss(event->time_stamp()); } } @@ -222,7 +222,7 @@ // AppListPresenterDelegate, ShellObserver implementation: void AppListPresenterDelegate::OnOverviewModeStarting() { if (is_visible_) - presenter_->Dismiss(); + presenter_->Dismiss(base::TimeTicks()); } void AppListPresenterDelegate::OnTabletModeStarted() {
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc index 587d601..6fb0716 100644 --- a/ash/app_list/app_list_presenter_impl.cc +++ b/ash/app_list/app_list_presenter_impl.cc
@@ -13,6 +13,7 @@ #include "base/metrics/user_metrics.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_features.h" +#include "ui/app_list/app_list_metrics.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/pagination_model.h" @@ -48,6 +49,25 @@ DISALLOW_COPY_AND_ASSIGN(StateAnimationMetricsReporter); }; +// Callback from the compositor when it presented a valid frame. Used to +// record UMA of input latency. +void DidPresentCompositorFrame(base::TimeTicks event_time_stamp, + bool is_showing, + base::TimeTicks present_time, + base::TimeDelta refresh, + uint32_t flags) { + if (present_time.is_null() || event_time_stamp.is_null() || + present_time < event_time_stamp) { + return; + } + const base::TimeDelta input_latency = present_time - event_time_stamp; + if (is_showing) { + UMA_HISTOGRAM_TIMES(kAppListShowInputLatencyHistogram, input_latency); + } else { + UMA_HISTOGRAM_TIMES(kAppListHideInputLatencyHistogram, input_latency); + } +} + } // namespace AppListPresenterImpl::AppListPresenterImpl( @@ -61,7 +81,7 @@ } AppListPresenterImpl::~AppListPresenterImpl() { - Dismiss(); + Dismiss(base::TimeTicks()); presenter_delegate_.reset(); // Ensures app list view goes before the controller since pagination model // lives in the controller and app list view would access it on destruction. @@ -76,14 +96,16 @@ return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : nullptr; } -void AppListPresenterImpl::Show(int64_t display_id) { +void AppListPresenterImpl::Show(int64_t display_id, + base::TimeTicks event_time_stamp) { if (is_visible_) { if (display_id != GetDisplayId()) - Dismiss(); + Dismiss(event_time_stamp); return; } is_visible_ = true; + RequestPresentationTime(display_id, event_time_stamp); NotifyTargetVisibilityChanged(GetTargetVisibility()); NotifyVisibilityChanged(GetTargetVisibility(), display_id); @@ -103,7 +125,7 @@ view_delegate_->ViewShown(display_id); } -void AppListPresenterImpl::Dismiss() { +void AppListPresenterImpl::Dismiss(base::TimeTicks event_time_stamp) { if (!is_visible_) return; @@ -111,8 +133,10 @@ DCHECK(view_); is_visible_ = false; + const int64_t display_id = GetDisplayId(); + RequestPresentationTime(display_id, event_time_stamp); NotifyTargetVisibilityChanged(GetTargetVisibility()); - NotifyVisibilityChanged(GetTargetVisibility(), GetDisplayId()); + NotifyVisibilityChanged(GetTargetVisibility(), display_id); // The dismissal may have occurred in response to the app list losing // activation. Otherwise, our widget is currently active. When the animation // completes we'll hide the widget, changing activation. If a menu is shown @@ -138,12 +162,13 @@ return view_->app_list_main_view()->contents_view()->Back(); } -void AppListPresenterImpl::ToggleAppList(int64_t display_id) { +void AppListPresenterImpl::ToggleAppList(int64_t display_id, + base::TimeTicks event_time_stamp) { if (IsVisible()) { - Dismiss(); + Dismiss(event_time_stamp); return; } - Show(display_id); + Show(display_id, event_time_stamp); } bool AppListPresenterImpl::IsVisible() const { @@ -290,7 +315,7 @@ if (applist_container->Contains(lost_focus) && (!gained_focus || !applist_container->Contains(gained_focus)) && !switches::ShouldNotDismissOnBlur()) { - Dismiss(); + Dismiss(base::TimeTicks()); } } } @@ -311,7 +336,7 @@ void AppListPresenterImpl::OnWidgetDestroying(views::Widget* widget) { DCHECK_EQ(view_->GetWidget(), widget); if (is_visible_) - Dismiss(); + Dismiss(base::TimeTicks()); ResetView(); } @@ -337,4 +362,20 @@ void AppListPresenterImpl::TransitionEnded() {} +void AppListPresenterImpl::RequestPresentationTime( + int64_t display_id, + base::TimeTicks event_time_stamp) { + if (event_time_stamp.is_null()) + return; + aura::Window* root_window = + ash::Shell::Get()->GetRootWindowForDisplayId(display_id); + if (!root_window) + return; + ui::Compositor* compositor = root_window->layer()->GetCompositor(); + if (!compositor) + return; + compositor->RequestPresentationTimeForNextFrame(base::BindOnce( + &DidPresentCompositorFrame, event_time_stamp, is_visible_)); +} + } // namespace app_list
diff --git a/ash/app_list/app_list_presenter_impl.h b/ash/app_list/app_list_presenter_impl.h index 78bfcc2..2c48395 100644 --- a/ash/app_list/app_list_presenter_impl.h +++ b/ash/app_list/app_list_presenter_impl.h
@@ -62,18 +62,24 @@ // Returns app list view if one exists, or NULL otherwise. AppListView* GetView() { return view_; } - // Show the app list window on the display with the given id. - void Show(int64_t display_id); + // Show the app list window on the display with the given id. If + // |event_time_stamp| is not 0, it means |Show()| was triggered by one of the + // AppListShowSources: kSearchKey, kShelfButton, or kSwipeFromShelf. + void Show(int64_t display_id, base::TimeTicks event_time_stamp); // Hide the open app list window. This may leave the view open but hidden. - void Dismiss(); + // If |event_time_stamp| is not 0, it means |Dismiss()| was triggered by + // one AppListShowSource or focusing out side of the launcher. + void Dismiss(base::TimeTicks event_time_stamp); // Performs the 'back' action for the active page. Returns whether the action // was handled. bool Back(); - // Show the app list if it is visible, hide it if it is hidden. - void ToggleAppList(int64_t display_id); + // Show the app list if it is visible, hide it if it is hidden. If + // |event_time_stamp| is not 0, it means |ToggleAppList()| was triggered by + // one of the AppListShowSources: kSearchKey or kShelfButton. + void ToggleAppList(int64_t display_id, base::TimeTicks event_time_stamp); // Returns current visibility of the app list. bool IsVisible() const; @@ -129,6 +135,11 @@ void TransitionChanged() override; void TransitionEnded() override; + // Registers a callback that is run when the next frame successfully makes it + // to the screen. + void RequestPresentationTime(int64_t display_id, + base::TimeTicks event_time_stamp); + // The factory for the presenter's delegate. std::unique_ptr<AppListPresenterDelegateFactory> factory_;
diff --git a/ash/app_list/app_list_view_delegate_mash.cc b/ash/app_list/app_list_view_delegate_mash.cc index 3988748..34e3aa79 100644 --- a/ash/app_list/app_list_view_delegate_mash.cc +++ b/ash/app_list/app_list_view_delegate_mash.cc
@@ -49,7 +49,7 @@ } void AppListViewDelegateMash::Dismiss() { - owner_->presenter()->Dismiss(); + owner_->presenter()->Dismiss(base::TimeTicks()); } void AppListViewDelegateMash::ViewClosing() {
diff --git a/ash/app_list/presenter/app_list_presenter_impl_unittest.cc b/ash/app_list/presenter/app_list_presenter_impl_unittest.cc index ae22192..0f3b397 100644 --- a/ash/app_list/presenter/app_list_presenter_impl_unittest.cc +++ b/ash/app_list/presenter/app_list_presenter_impl_unittest.cc
@@ -156,7 +156,7 @@ aura::client::FocusClient* focus_client = aura::client::GetFocusClient(root_window()); - presenter()->Show(GetDisplayId()); + presenter()->Show(GetDisplayId(), base::TimeTicks()); EXPECT_TRUE(delegate()->init_called()); EXPECT_TRUE(delegate()->on_shown_called()); EXPECT_FALSE(delegate()->on_dismissed_called()); @@ -182,7 +182,7 @@ aura::client::FocusClient* focus_client = aura::client::GetFocusClient(root_window()); - presenter()->Show(GetDisplayId()); + presenter()->Show(GetDisplayId(), base::TimeTicks()); focus_client->FocusWindow(presenter()->GetWindow()); EXPECT_TRUE(presenter()->GetTargetVisibility()); EXPECT_TRUE(delegate()->init_called()); @@ -206,7 +206,7 @@ if (features::IsFullscreenAppListEnabled()) return; - presenter()->Show(GetDisplayId()); + presenter()->Show(GetDisplayId(), base::TimeTicks()); EXPECT_TRUE(presenter()->GetTargetVisibility()); presenter()->GetView()->GetWidget()->CloseNow(); EXPECT_FALSE(presenter()->GetTargetVisibility());
diff --git a/ash/app_list/test/app_list_test_helper.cc b/ash/app_list/test/app_list_test_helper.cc index 13e723b..c78f109b5 100644 --- a/ash/app_list/test/app_list_test_helper.cc +++ b/ash/app_list/test/app_list_test_helper.cc
@@ -40,7 +40,7 @@ void AppListTestHelper::ShowAndRunLoop( uint64_t display_id, app_list::AppListShowSource show_source) { - app_list_controller_->Show(display_id, show_source); + app_list_controller_->Show(display_id, show_source, base::TimeTicks()); WaitUntilIdle(); } @@ -56,7 +56,8 @@ void AppListTestHelper::ToggleAndRunLoop( uint64_t display_id, app_list::AppListShowSource show_source) { - app_list_controller_->ToggleAppList(display_id, show_source); + app_list_controller_->ToggleAppList(display_id, show_source, + base::TimeTicks()); WaitUntilIdle(); }
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.1x.icon index ed82bb8..968f1d2 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.1x.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 4.45f, 4.41f, LINE_TO, 12.45f, 5, LINE_TO, 13.5f, 6.04f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.icon index 673d57c..1fddea3 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_down.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 8.9f, 8.82f, LINE_TO, 24.9f, 10, LINE_TO, 27, 12.09f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.1x.icon index 5271a7f..d2cadf7b 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.1x.icon
@@ -9,5 +9,4 @@ R_LINE_TO, -4.41f, -4.45f, R_LINE_TO, 4.41f, -4.45f, R_LINE_TO, -1.04f, -1.05f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.icon index a5c0ad1..1f88f2f 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_left.icon
@@ -9,5 +9,4 @@ R_LINE_TO, -8.82f, -8.9f, LINE_TO, 22.5f, 7.6f, LINE_TO, 20.41f, 5.5f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.1x.icon index 69819d7..ca0cacf 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.1x.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 4.41f, -4.45f, LINE_TO, 4.75f, 3.8f, LINE_TO, 5.79f, 2.75f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.icon index dd17694..e86867b 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_right.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 8.82f, -8.9f, LINE_TO, 9.5f, 7.6f, LINE_TO, 11.59f, 5.5f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.1x.icon index d4b3fb4..0016c7f 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.1x.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 4.45f, -4.41f, R_LINE_TO, 4.45f, 4.41f, R_LINE_TO, 1.05f, -1.04f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.icon b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.icon index f8c9a72..1d6cffc 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_arrow_up.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 8.9f, -8.82f, LINE_TO, 24.9f, 23, LINE_TO, 27, 20.91f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.1x.icon index 0a52101..fb9ebec 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.1x.icon
@@ -26,5 +26,4 @@ LINE_TO, 10.68f, 9.06f, LINE_TO, 11.82f, 7.91f, LINE_TO, 10.68f, 6.76f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.icon b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.icon index 788987e67..8d42331 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_down.icon
@@ -26,5 +26,4 @@ LINE_TO, 21.35f, 18.11f, LINE_TO, 23.64f, 15.82f, LINE_TO, 21.35f, 13.53f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.1x.icon index 0a06d200..6e4c72e 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.1x.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, -2.22f, R_LINE_TO, 1.57f, -1.57f, R_LINE_TO, -1.57f, -1.57f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.icon b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.icon index 87fbd256..6e3dcf7f 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_brightness_up.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, -4.44f, R_LINE_TO, 3.14f, -3.14f, R_LINE_TO, -3.14f, -3.14f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.1x.icon index 86935b03f..b902618 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.1x.icon
@@ -12,5 +12,4 @@ V_LINE_TO, 7.45f, H_LINE_TO, 6.07f, R_LINE_TO, 2.84f, -2.81f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.icon b/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.icon index ce6926a..7d3990b 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_browser_back.icon
@@ -12,5 +12,4 @@ R_V_LINE_TO, -3.21f, H_LINE_TO, 12.13f, R_LINE_TO, 5.67f, -5.62f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.1x.icon index 4e5bded..d2ea6609 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.1x.icon
@@ -12,5 +12,4 @@ V_LINE_TO, 7.45f, R_H_LINE_TO, 6.93f, LINE_TO, 7.1f, 4.64f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.icon b/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.icon index a893357..92e1c712 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_browser_forward.icon
@@ -12,5 +12,4 @@ R_V_LINE_TO, -3.21f, R_H_LINE_TO, 13.87f, LINE_TO, 14.2f, 9.27f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.1x.icon index 5d536489..5e2ac30 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.1x.icon
@@ -34,5 +34,4 @@ H_LINE_TO, 13, V_LINE_TO, 9.35f, R_H_LINE_TO, -1.32f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.icon b/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.icon index 0555eb276..f2c9b0db 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_fullscreen.icon
@@ -34,5 +34,4 @@ R_H_LINE_TO, 8.23f, R_V_LINE_TO, -6.3f, R_H_LINE_TO, -2.64f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_mute.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_mute.1x.icon index 59033b2..0305760 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_mute.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_mute.1x.icon
@@ -38,5 +38,4 @@ LINE_TO, 9.11f, 6.99f, LINE_TO, 10.47f, 8.35f, CUBIC_TO, 10.49f, 8.24f, 10.5f, 8.12f, 10.5f, 8, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_mute.icon b/ash/components/shortcut_viewer/vector_icons/ksv_mute.icon index f57a16c..2d4d688 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_mute.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_mute.icon
@@ -38,5 +38,4 @@ LINE_TO, 18.22f, 13.98f, LINE_TO, 20.94f, 16.7f, CUBIC_TO, 20.98f, 16.48f, 21, 16.25f, 21, 16, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_overview.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_overview.1x.icon index b0254a4..c2f4f72 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_overview.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_overview.1x.icon
@@ -24,5 +24,4 @@ R_H_LINE_TO, 1, R_V_LINE_TO, -7, R_H_LINE_TO, -1, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_overview.icon b/ash/components/shortcut_viewer/vector_icons/ksv_overview.icon index d5b942a..a810a00 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_overview.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_overview.icon
@@ -24,5 +24,4 @@ R_H_LINE_TO, 2, V_LINE_TO, 9, R_H_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_reload.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_reload.1x.icon index 97f9d9f..392be2a8 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_reload.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_reload.1x.icon
@@ -20,6 +20,5 @@ CUBIC_TO, 8.96f, 4.42f, 9.9f, 4.89f, 10.54f, 5.65f, LINE_TO, 8.92f, 7.27f, LINE_TO, 13.19f, 7.27f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_reload.icon b/ash/components/shortcut_viewer/vector_icons/ksv_reload.icon index ce946af..1d62433a 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_reload.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_reload.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 17.91f, 8.84f, 19.79f, 9.78f, 21.07f, 11.3f, LINE_TO, 17.84f, 14.53f, LINE_TO, 26.37f, 14.53f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_back.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_back.1x.icon index 2ebd257..b2c2931a 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_back.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_back.1x.icon
@@ -12,5 +12,4 @@ R_LINE_TO, 1.15f, -1.15f, LINE_TO, 6.45f, 10.5f, H_LINE_TO, 16, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_back.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_back.icon index b501e4a..33f08fa5 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_back.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_back.icon
@@ -12,5 +12,4 @@ R_LINE_TO, 2.3f, -2.3f, LINE_TO, 12.89f, 21, H_LINE_TO, 33, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.1x.icon index eef7777..3b4cd225 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.1x.icon
@@ -20,5 +20,4 @@ R_ARC_TO, 3.75f, 3.75f, 0, 0, 1, 3.75f, -3.75f, R_ARC_TO, 3.75f, 3.75f, 0, 0, 1, 3.75f, 3.75f, R_ARC_TO, 3.75f, 3.75f, 0, 0, 1, -3.75f, 3.75f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.icon index 62361a2..5988315 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_bar.icon
@@ -22,5 +22,4 @@ R_CUBIC_TO, 0, -4.15f, 3.35f, -7.5f, 7.5f, -7.5f, R_CUBIC_TO, 4.15f, 0, 7.5f, 3.35f, 7.5f, 7.5f, R_CUBIC_TO, 0, 4.15f, -3.35f, 7.5f, -7.5f, 7.5f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_close.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_close.1x.icon index e7f3f225..db1d582 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_close.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_close.1x.icon
@@ -22,5 +22,4 @@ R_LINE_TO, 0.79f, -0.79f, R_LINE_TO, -3.1f, -3.1f, R_LINE_TO, 3.1f, -3.1f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_close.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_close.icon index 411555e4..340b406 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_close.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_close.icon
@@ -22,5 +22,4 @@ R_LINE_TO, 1.57f, -1.57f, R_LINE_TO, -6.21f, -6.2f, R_LINE_TO, 6.21f, -6.21f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.1x.icon index 5a587c3..2d5b56b6 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.1x.icon
@@ -57,5 +57,4 @@ R_CUBIC_TO, 0, -5.59f, 4.54f, -10.12f, 10.14f, -10.12f, R_CUBIC_TO, 5.6f, 0, 10.14f, 4.53f, 10.14f, 10.13f, R_CUBIC_TO, 0, 5.6f, -4.54f, 10.13f, -10.14f, 10.13f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.icon b/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.icon index 7cb0b2f..d0578a3 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_search_no_result.icon
@@ -58,5 +58,4 @@ R_CUBIC_TO, 0, -11.18f, 9.08f, -20.25f, 20.28f, -20.25f, R_CUBIC_TO, 11.2f, 0, 20.28f, 9.07f, 20.28f, 20.25f, R_CUBIC_TO, 0, 11.18f, -9.08f, 20.25f, -20.28f, 20.25f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.1x.icon index 1cb0f87..1882cfb 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.1x.icon
@@ -15,5 +15,4 @@ R_H_LINE_TO, 2, R_V_LINE_TO, 3, R_H_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.icon b/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.icon index 65b0911..f71544c 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_separator_plus.icon
@@ -15,5 +15,4 @@ R_H_LINE_TO, 4, R_V_LINE_TO, 6, R_H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.1x.icon index cf5063d..1e55f0ce 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.1x.icon
@@ -15,5 +15,4 @@ CUBIC_TO, 11.59f, 7, 11.02f, 6.15f, 10.19f, 5.73f, LINE_TO, 10.19f, 10.26f, CUBIC_TO, 11.02f, 9.85f, 11.59f, 9, 11.59f, 8, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.icon b/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.icon index 8427713..d24273cb 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_volume_down.icon
@@ -15,5 +15,4 @@ CUBIC_TO, 23.19f, 14.01f, 22.04f, 12.3f, 20.37f, 11.47f, LINE_TO, 20.37f, 20.52f, CUBIC_TO, 22.04f, 19.7f, 23.19f, 17.99f, 23.19f, 16, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.1x.icon b/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.1x.icon index b0a1da0..f59c157 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.1x.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.1x.icon
@@ -23,5 +23,4 @@ LINE_TO, 8.06f, 3.43f, LINE_TO, 5.25f, 6.24f, LINE_TO, 3, 6.24f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.icon b/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.icon index 55dfe52..4a77d47 100644 --- a/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.icon +++ b/ash/components/shortcut_viewer/vector_icons/ksv_volume_up.icon
@@ -23,5 +23,4 @@ LINE_TO, 16.11f, 6.87f, LINE_TO, 10.49f, 12.48f, LINE_TO, 6, 12.48f, -CLOSE, -END +CLOSE
diff --git a/ash/components/shortcut_viewer_strings.grdp b/ash/components/shortcut_viewer_strings.grdp index 4a8b59f6..50d3c5ee 100644 --- a/ash/components/shortcut_viewer_strings.grdp +++ b/ash/components/shortcut_viewer_strings.grdp
@@ -112,7 +112,7 @@ Press and hold <ph name="alt">$1<ex>Alt</ex></ph>, tap <ph name="tab">$2<ex>v</ex></ph> until you get to the window you want to open, then release. </message> <message name="IDS_KSV_DESCRIPTION_CYCLE_BACKWARD_MRU" desc="Description of the command in keyboard shortcut viewer."> - Open the window you used least recently + Open the window that has been unused for the longest time </message> <message name="IDS_KSV_SHORTCUT_CYCLE_BACKWARD_MRU" desc="Human readable version of the keyboard shortcut."> Press and hold <ph name="alt">$1<ex>Alt</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="shift">$3<ex>Shift</ex></ph>, tap <ph name="tab">$4<ex>v</ex></ph> until you get to the window you want to open, then release.
diff --git a/ash/public/cpp/vector_icons/notification_captive_portal.icon b/ash/public/cpp/vector_icons/notification_captive_portal.icon index 74a3f8ae..aa44f60 100644 --- a/ash/public/cpp/vector_icons/notification_captive_portal.icon +++ b/ash/public/cpp/vector_icons/notification_captive_portal.icon
@@ -59,5 +59,4 @@ R_LINE_TO, -8.24f, 8.85f, LINE_TO, 86.67f, 75.76f, LINE_TO, 75.76f, 86.67f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_cellular_alert.1x.icon b/ash/public/cpp/vector_icons/notification_cellular_alert.1x.icon index bd7c4e5..b1c722fb 100644 --- a/ash/public/cpp/vector_icons/notification_cellular_alert.1x.icon +++ b/ash/public/cpp/vector_icons/notification_cellular_alert.1x.icon
@@ -32,5 +32,4 @@ H_LINE_TO, 16, V_LINE_TO, 8, H_LINE_TO, 14, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_cellular_alert.icon b/ash/public/cpp/vector_icons/notification_cellular_alert.icon index def7350..92ed360 100644 --- a/ash/public/cpp/vector_icons/notification_cellular_alert.icon +++ b/ash/public/cpp/vector_icons/notification_cellular_alert.icon
@@ -32,5 +32,4 @@ H_LINE_TO, 32, V_LINE_TO, 16, H_LINE_TO, 28, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_download.icon b/ash/public/cpp/vector_icons/notification_download.icon index 6112097..cb54cfb 100644 --- a/ash/public/cpp/vector_icons/notification_download.icon +++ b/ash/public/cpp/vector_icons/notification_download.icon
@@ -17,5 +17,4 @@ R_H_LINE_TO, 56, R_V_LINE_TO, -8, H_LINE_TO, 20, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_end_of_support.icon b/ash/public/cpp/vector_icons/notification_end_of_support.icon index 78502ea..475ccda 100644 --- a/ash/public/cpp/vector_icons/notification_end_of_support.icon +++ b/ash/public/cpp/vector_icons/notification_end_of_support.icon
@@ -40,5 +40,4 @@ R_H_LINE_TO, 9, R_V_LINE_TO, 15, R_H_LINE_TO, 20, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_google.icon b/ash/public/cpp/vector_icons/notification_google.icon index 42135ac..45d9211 100644 --- a/ash/public/cpp/vector_icons/notification_google.icon +++ b/ash/public/cpp/vector_icons/notification_google.icon
@@ -23,5 +23,4 @@ R_LINE_TO, 8.19f, -8.03f, CUBIC_TO, 62.74f, 22.78f, 56.28f, 20, 48.57f, 20, CUBIC_TO, 32.79f, 20, 20, 32.54f, 20, 48, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_image.icon b/ash/public/cpp/vector_icons/notification_image.icon index b698f4c..ad5746c 100644 --- a/ash/public/cpp/vector_icons/notification_image.icon +++ b/ash/public/cpp/vector_icons/notification_image.icon
@@ -19,5 +19,4 @@ R_LINE_TO, 18, 24, H_LINE_TO, 20, R_LINE_TO, 14, -18, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_installed.icon b/ash/public/cpp/vector_icons/notification_installed.icon index 348d1db..1089044 100644 --- a/ash/public/cpp/vector_icons/notification_installed.icon +++ b/ash/public/cpp/vector_icons/notification_installed.icon
@@ -16,5 +16,4 @@ R_LINE_TO, 30.36f, -30.36f, LINE_TO, 76, 32, LINE_TO, 40, 68, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_mobile_data.icon b/ash/public/cpp/vector_icons/notification_mobile_data.icon index 7ab9e42..d78be61 100644 --- a/ash/public/cpp/vector_icons/notification_mobile_data.icon +++ b/ash/public/cpp/vector_icons/notification_mobile_data.icon
@@ -6,5 +6,4 @@ MOVE_TO, 12, 84, R_H_LINE_TO, 72, V_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_mobile_data_off.icon b/ash/public/cpp/vector_icons/notification_mobile_data_off.icon index 70494c3..b4531401 100644 --- a/ash/public/cpp/vector_icons/notification_mobile_data_off.icon +++ b/ash/public/cpp/vector_icons/notification_mobile_data_off.icon
@@ -16,5 +16,4 @@ LINE_TO, 84, 8, R_V_LINE_TO, 60.36f, LINE_TO, 53.82f, 38.18f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_play_prism.icon b/ash/public/cpp/vector_icons/notification_play_prism.icon index f7293f99..3f3f637 100644 --- a/ash/public/cpp/vector_icons/notification_play_prism.icon +++ b/ash/public/cpp/vector_icons/notification_play_prism.icon
@@ -33,5 +33,4 @@ V_LINE_TO, 79.78f, R_CUBIC_TO, 0, 0.95f, 0.68f, 1.39f, 1.35f, 0.7f, LINE_TO, 48, 49, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_printing.icon b/ash/public/cpp/vector_icons/notification_printing.icon index ff9384a..2c93ce9 100644 --- a/ash/public/cpp/vector_icons/notification_printing.icon +++ b/ash/public/cpp/vector_icons/notification_printing.icon
@@ -32,5 +32,4 @@ R_V_LINE_TO, 16, R_H_LINE_TO, 48, V_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_printing_done.icon b/ash/public/cpp/vector_icons/notification_printing_done.icon index 626b6df..c60eda4d 100644 --- a/ash/public/cpp/vector_icons/notification_printing_done.icon +++ b/ash/public/cpp/vector_icons/notification_printing_done.icon
@@ -45,5 +45,4 @@ R_LINE_TO, -5.13f, -5.5f, LINE_TO, 62, 72.32f, LINE_TO, 69.14f, 80, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_printing_warning.icon b/ash/public/cpp/vector_icons/notification_printing_warning.icon index 984fc20..9d54e1a 100644 --- a/ash/public/cpp/vector_icons/notification_printing_warning.icon +++ b/ash/public/cpp/vector_icons/notification_printing_warning.icon
@@ -49,5 +49,4 @@ R_H_LINE_TO, 4, R_V_LINE_TO, -4, R_H_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_storage_full.icon b/ash/public/cpp/vector_icons/notification_storage_full.icon index c344066..ac9835d 100644 --- a/ash/public/cpp/vector_icons/notification_storage_full.icon +++ b/ash/public/cpp/vector_icons/notification_storage_full.icon
@@ -42,5 +42,4 @@ R_H_LINE_TO, 4, R_V_LINE_TO, -4, R_H_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_vpn.icon b/ash/public/cpp/vector_icons/notification_vpn.icon index 9a54dda..8aa5fb5a 100644 --- a/ash/public/cpp/vector_icons/notification_vpn.icon +++ b/ash/public/cpp/vector_icons/notification_vpn.icon
@@ -21,5 +21,4 @@ R_CUBIC_TO, 0, -4.4f, 3.6f, -8, 8, -8, R_CUBIC_TO, 4.4f, 0, 8, 3.6f, 8, 8, R_CUBIC_TO, 0, 4.4f, -3.6f, 8, -8, 8, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_warning.icon b/ash/public/cpp/vector_icons/notification_warning.icon index b90da17..146fa3c 100644 --- a/ash/public/cpp/vector_icons/notification_warning.icon +++ b/ash/public/cpp/vector_icons/notification_warning.icon
@@ -20,5 +20,4 @@ R_H_LINE_TO, 8, R_V_LINE_TO, -8, R_H_LINE_TO, -8, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/notification_wifi_off.icon b/ash/public/cpp/vector_icons/notification_wifi_off.icon index 63e879a..b868c416 100644 --- a/ash/public/cpp/vector_icons/notification_wifi_off.icon +++ b/ash/public/cpp/vector_icons/notification_wifi_off.icon
@@ -21,5 +21,4 @@ R_LINE_TO, 5.18f, -5.15f, LINE_TO, 12.31f, 8, R_LINE_TO, -5.18f, 5.15f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_close.1x.icon b/ash/public/cpp/vector_icons/window_control_close.1x.icon index 94d36a0f..813445e 100644 --- a/ash/public/cpp/vector_icons/window_control_close.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_close.1x.icon
@@ -16,5 +16,4 @@ R_LINE_TO, 3.54f, -3.54f, LINE_TO, 9.54f, 1.05f, LINE_TO, 6, 4.59f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_close.icon b/ash/public/cpp/vector_icons/window_control_close.icon index 1e6fb80..d9d780e 100644 --- a/ash/public/cpp/vector_icons/window_control_close.icon +++ b/ash/public/cpp/vector_icons/window_control_close.icon
@@ -16,5 +16,4 @@ LINE_TO, 23, 20.78f, LINE_TO, 14.22f, 12, LINE_TO, 23, 3.22f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon b/ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon index 0899d308..b5bfa0e 100644 --- a/ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon
@@ -11,5 +11,4 @@ LINE_TO, 6.6f, 1, LINE_TO, 1.7f, 5.38f, LINE_TO, 1, 6, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_left_snapped.icon b/ash/public/cpp/vector_icons/window_control_left_snapped.icon index f764dc7..694f178e1 100644 --- a/ash/public/cpp/vector_icons/window_control_left_snapped.icon +++ b/ash/public/cpp/vector_icons/window_control_left_snapped.icon
@@ -12,5 +12,4 @@ R_LINE_TO, 5, -4.77f, LINE_TO, 12.86f, 0, LINE_TO, 15, 2.05f, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_maximize.1x.icon b/ash/public/cpp/vector_icons/window_control_maximize.1x.icon index f1c56bb..d5b91ae 100644 --- a/ash/public/cpp/vector_icons/window_control_maximize.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_maximize.1x.icon
@@ -14,5 +14,4 @@ V_LINE_TO, 3, R_H_LINE_TO, 6, R_V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_maximize.icon b/ash/public/cpp/vector_icons/window_control_maximize.icon index c186d5f..9eef1c7 100644 --- a/ash/public/cpp/vector_icons/window_control_maximize.icon +++ b/ash/public/cpp/vector_icons/window_control_maximize.icon
@@ -14,5 +14,4 @@ V_LINE_TO, 4, R_H_LINE_TO, 16, R_V_LINE_TO, 16, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_minimize.1x.icon b/ash/public/cpp/vector_icons/window_control_minimize.1x.icon index da77c268..3064a7c8 100644 --- a/ash/public/cpp/vector_icons/window_control_minimize.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_minimize.1x.icon
@@ -7,5 +7,4 @@ R_H_LINE_TO, 10, R_V_LINE_TO, 2, H_LINE_TO, 1, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_minimize.icon b/ash/public/cpp/vector_icons/window_control_minimize.icon index 98629c7..680228f 100644 --- a/ash/public/cpp/vector_icons/window_control_minimize.icon +++ b/ash/public/cpp/vector_icons/window_control_minimize.icon
@@ -7,5 +7,4 @@ R_H_LINE_TO, 22, R_V_LINE_TO, 3, H_LINE_TO, 1, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_restore.1x.icon b/ash/public/cpp/vector_icons/window_control_restore.1x.icon index 99449dd..3836338 100644 --- a/ash/public/cpp/vector_icons/window_control_restore.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_restore.1x.icon
@@ -22,5 +22,4 @@ V_LINE_TO, 9, H_LINE_TO, 3, V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_restore.icon b/ash/public/cpp/vector_icons/window_control_restore.icon index f511b4c..037ad4e 100644 --- a/ash/public/cpp/vector_icons/window_control_restore.icon +++ b/ash/public/cpp/vector_icons/window_control_restore.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, -3, H_LINE_TO, 4, V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon b/ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon index 448e72c..2c6add2 100644 --- a/ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon +++ b/ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon
@@ -11,5 +11,4 @@ LINE_TO, 5.4f, 1, R_LINE_TO, 4.9f, 4.38f, LINE_TO, 11, 6, -CLOSE, -END +CLOSE
diff --git a/ash/public/cpp/vector_icons/window_control_right_snapped.icon b/ash/public/cpp/vector_icons/window_control_right_snapped.icon index f446d371..fc6cff21 100644 --- a/ash/public/cpp/vector_icons/window_control_right_snapped.icon +++ b/ash/public/cpp/vector_icons/window_control_right_snapped.icon
@@ -12,5 +12,4 @@ R_LINE_TO, -5, -4.77f, LINE_TO, 11.14f, 0, LINE_TO, 9, 2.05f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/captive_portal.1x.icon b/ash/resources/vector_icons/captive_portal.1x.icon index e8fdc72..32f691f 100644 --- a/ash/resources/vector_icons/captive_portal.1x.icon +++ b/ash/resources/vector_icons/captive_portal.1x.icon
@@ -57,5 +57,4 @@ R_H_LINE_TO, 5.5f, R_LINE_TO, -2, 1.5f, LINE_TO, 18, 16, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/captive_portal.icon b/ash/resources/vector_icons/captive_portal.icon index 64ba3f84..255f47d 100644 --- a/ash/resources/vector_icons/captive_portal.icon +++ b/ash/resources/vector_icons/captive_portal.icon
@@ -57,5 +57,4 @@ R_H_LINE_TO, 10.9f, R_LINE_TO, -3.29f, 3.31f, LINE_TO, 34, 30.72f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/check_circle.1x.icon b/ash/resources/vector_icons/check_circle.1x.icon index 1fe038c..2ed8bab 100644 --- a/ash/resources/vector_icons/check_circle.1x.icon +++ b/ash/resources/vector_icons/check_circle.1x.icon
@@ -16,5 +16,4 @@ R_LINE_TO, 6.07f, -6.07f, LINE_TO, 15.6f, 6.8f, LINE_TO, 8.4f, 14, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/check_circle.icon b/ash/resources/vector_icons/check_circle.icon index 7a320d7..f2ef12f 100644 --- a/ash/resources/vector_icons/check_circle.icon +++ b/ash/resources/vector_icons/check_circle.icon
@@ -18,5 +18,4 @@ R_LINE_TO, 12.14f, -12.14f, LINE_TO, 31.2f, 13.6f, LINE_TO, 16.8f, 28, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_emoticon.1x.icon b/ash/resources/vector_icons/ime_menu_emoticon.1x.icon index 3766c426..c31d4f0 100644 --- a/ash/resources/vector_icons/ime_menu_emoticon.1x.icon +++ b/ash/resources/vector_icons/ime_menu_emoticon.1x.icon
@@ -36,5 +36,4 @@ LINE_TO, 5.91f, 11, CUBIC_TO, 6.55f, 12.75f, 8.14f, 14, 10, 14, LINE_TO, 10, 14, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_emoticon.icon b/ash/resources/vector_icons/ime_menu_emoticon.icon index 22d6e0d..fa34c76a 100644 --- a/ash/resources/vector_icons/ime_menu_emoticon.icon +++ b/ash/resources/vector_icons/ime_menu_emoticon.icon
@@ -36,5 +36,4 @@ LINE_TO, 11.82f, 23, CUBIC_TO, 13.1f, 26.5f, 16.27f, 29, 20, 29, LINE_TO, 20, 29, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_microphone.1x.icon b/ash/resources/vector_icons/ime_menu_microphone.1x.icon index 1d370e85..05253cc 100644 --- a/ash/resources/vector_icons/ime_menu_microphone.1x.icon +++ b/ash/resources/vector_icons/ime_menu_microphone.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 13.67f, 14.83f, 16, 12.46f, 16, 9.58f, LINE_TO, 14.54f, 9.58f, LINE_TO, 14.54f, 9.58f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_microphone.icon b/ash/resources/vector_icons/ime_menu_microphone.icon index ba3a720..c248111d 100644 --- a/ash/resources/vector_icons/ime_menu_microphone.icon +++ b/ash/resources/vector_icons/ime_menu_microphone.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 27.13f, 30.67f, 31.67f, 25.92f, 31.67f, 20.16f, LINE_TO, 28.83f, 20.16f, LINE_TO, 28.83f, 20.16f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_on_screen_keyboard.1x.icon b/ash/resources/vector_icons/ime_menu_on_screen_keyboard.1x.icon index 27ef535..d21e3ac2a 100644 --- a/ash/resources/vector_icons/ime_menu_on_screen_keyboard.1x.icon +++ b/ash/resources/vector_icons/ime_menu_on_screen_keyboard.1x.icon
@@ -54,5 +54,4 @@ R_V_LINE_TO, 1, R_H_LINE_TO, -1, R_V_LINE_TO, -1, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_on_screen_keyboard.icon b/ash/resources/vector_icons/ime_menu_on_screen_keyboard.icon index 34569528..0830899 100644 --- a/ash/resources/vector_icons/ime_menu_on_screen_keyboard.icon +++ b/ash/resources/vector_icons/ime_menu_on_screen_keyboard.icon
@@ -66,5 +66,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_write.1x.icon b/ash/resources/vector_icons/ime_menu_write.1x.icon index 4eed1d9..f261758 100644 --- a/ash/resources/vector_icons/ime_menu_write.1x.icon +++ b/ash/resources/vector_icons/ime_menu_write.1x.icon
@@ -23,5 +23,4 @@ LINE_TO, 12, 4.81f, LINE_TO, 15.19f, 8, LINE_TO, 16.75f, 6.44f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/ime_menu_write.icon b/ash/resources/vector_icons/ime_menu_write.icon index 184715ba..2d2ca449 100644 --- a/ash/resources/vector_icons/ime_menu_write.icon +++ b/ash/resources/vector_icons/ime_menu_write.icon
@@ -23,5 +23,4 @@ LINE_TO, 25.22f, 8.53f, LINE_TO, 31.47f, 14.78f, LINE_TO, 34.52f, 11.73f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_alert.1x.icon b/ash/resources/vector_icons/lock_screen_alert.1x.icon index c6c7d679..a22a1ae 100644 --- a/ash/resources/vector_icons/lock_screen_alert.1x.icon +++ b/ash/resources/vector_icons/lock_screen_alert.1x.icon
@@ -19,5 +19,4 @@ LINE_TO, 9.17f, 8.33f, LINE_TO, 10.83f, 8.33f, LINE_TO, 10.83f, 11.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_alert.icon b/ash/resources/vector_icons/lock_screen_alert.icon index 02ef97e8..cc8f849 100644 --- a/ash/resources/vector_icons/lock_screen_alert.icon +++ b/ash/resources/vector_icons/lock_screen_alert.icon
@@ -19,5 +19,4 @@ LINE_TO, 18, 16, LINE_TO, 22, 16, LINE_TO, 22, 23, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_arrow.1x.icon b/ash/resources/vector_icons/lock_screen_arrow.1x.icon index 4ddf012..079394de 100644 --- a/ash/resources/vector_icons/lock_screen_arrow.1x.icon +++ b/ash/resources/vector_icons/lock_screen_arrow.1x.icon
@@ -12,5 +12,4 @@ R_LINE_TO, -3.77f, 3.78f, LINE_TO, 10.42f, 15.83, R_LINE_TO, 5.42f, -5.42f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_arrow.icon b/ash/resources/vector_icons/lock_screen_arrow.icon index 6ab6ea7b..61c1ed8 100644 --- a/ash/resources/vector_icons/lock_screen_arrow.icon +++ b/ash/resources/vector_icons/lock_screen_arrow.icon
@@ -11,5 +11,4 @@ LINE_TO, 21.71f, 34.71f, LINE_TO, 24, 37, R_LINE_TO, 13, -13, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_backspace.1x.icon b/ash/resources/vector_icons/lock_screen_backspace.1x.icon index c804d87..1a675fe 100644 --- a/ash/resources/vector_icons/lock_screen_backspace.1x.icon +++ b/ash/resources/vector_icons/lock_screen_backspace.1x.icon
@@ -27,5 +27,4 @@ LINE_TO, 14.67f, 7.61f, LINE_TO, 12.27f, 10, LINE_TO, 14.67f, 12.39f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_backspace.icon b/ash/resources/vector_icons/lock_screen_backspace.icon index a989bef..c047d5a 100644 --- a/ash/resources/vector_icons/lock_screen_backspace.icon +++ b/ash/resources/vector_icons/lock_screen_backspace.icon
@@ -27,5 +27,4 @@ LINE_TO, 29.33f, 15.21f, LINE_TO, 24.55f, 20, LINE_TO, 29.33f, 24.79f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_caps_lock.1x.icon b/ash/resources/vector_icons/lock_screen_caps_lock.1x.icon index b5ced06..18a1e754 100644 --- a/ash/resources/vector_icons/lock_screen_caps_lock.1x.icon +++ b/ash/resources/vector_icons/lock_screen_caps_lock.1x.icon
@@ -26,5 +26,4 @@ LINE_TO, 15, 13.5f, LINE_TO, 5, 13.5f, LINE_TO, 5, 15, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_caps_lock.icon b/ash/resources/vector_icons/lock_screen_caps_lock.icon index 53a6d8a..d04a5099 100644 --- a/ash/resources/vector_icons/lock_screen_caps_lock.icon +++ b/ash/resources/vector_icons/lock_screen_caps_lock.icon
@@ -28,5 +28,4 @@ LINE_TO, 30, 27, LINE_TO, 10, 27, LINE_TO, 10, 30, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_dropdown.1x.icon b/ash/resources/vector_icons/lock_screen_dropdown.1x.icon index c1cbfa2f..c926e74 100644 --- a/ash/resources/vector_icons/lock_screen_dropdown.1x.icon +++ b/ash/resources/vector_icons/lock_screen_dropdown.1x.icon
@@ -10,5 +10,4 @@ LINE_TO, 6, 10, R_LINE_TO, 6, 6, R_LINE_TO, 6, -6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/lock_screen_dropdown.icon b/ash/resources/vector_icons/lock_screen_dropdown.icon index 884944c..45090b59 100644 --- a/ash/resources/vector_icons/lock_screen_dropdown.icon +++ b/ash/resources/vector_icons/lock_screen_dropdown.icon
@@ -9,5 +9,4 @@ LINE_TO, 12, 20, R_LINE_TO, 12, 12, R_LINE_TO, 12, -12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/login_screen_enterprise.1x.icon b/ash/resources/vector_icons/login_screen_enterprise.1x.icon index bb0c84fd..af92587 100644 --- a/ash/resources/vector_icons/login_screen_enterprise.1x.icon +++ b/ash/resources/vector_icons/login_screen_enterprise.1x.icon
@@ -84,5 +84,4 @@ V_LINE_TO, 5, R_H_LINE_TO, 4, R_V_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/login_screen_enterprise.icon b/ash/resources/vector_icons/login_screen_enterprise.icon index 523a4d2..44715279 100644 --- a/ash/resources/vector_icons/login_screen_enterprise.icon +++ b/ash/resources/vector_icons/login_screen_enterprise.icon
@@ -84,5 +84,4 @@ R_H_LINE_TO, 20, V_LINE_TO, 7, H_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_add_other.1x.icon b/ash/resources/vector_icons/network_badge_add_other.1x.icon index 6fdf200d..5d081e32 100644 --- a/ash/resources/vector_icons/network_badge_add_other.1x.icon +++ b/ash/resources/vector_icons/network_badge_add_other.1x.icon
@@ -23,5 +23,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2, R_V_LINE_TO, -2, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_add_other.icon b/ash/resources/vector_icons/network_badge_add_other.icon index 43f7c8a9..17e3002 100644 --- a/ash/resources/vector_icons/network_badge_add_other.icon +++ b/ash/resources/vector_icons/network_badge_add_other.icon
@@ -23,5 +23,4 @@ R_V_LINE_TO, 4, R_H_LINE_TO, -4, R_V_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_captive_portal.1x.icon b/ash/resources/vector_icons/network_badge_captive_portal.1x.icon index ebe1ed0..8f616d7 100644 --- a/ash/resources/vector_icons/network_badge_captive_portal.1x.icon +++ b/ash/resources/vector_icons/network_badge_captive_portal.1x.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, 1, H_LINE_TO, 4, V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_captive_portal.icon b/ash/resources/vector_icons/network_badge_captive_portal.icon index 83d3718..c592eb1 100644 --- a/ash/resources/vector_icons/network_badge_captive_portal.icon +++ b/ash/resources/vector_icons/network_badge_captive_portal.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 7, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_off.1x.icon b/ash/resources/vector_icons/network_badge_off.1x.icon index d48903a..6fab9ad2 100644 --- a/ash/resources/vector_icons/network_badge_off.1x.icon +++ b/ash/resources/vector_icons/network_badge_off.1x.icon
@@ -11,5 +11,4 @@ CAP_SQUARE, STROKE, 2, MOVE_TO, 2, 1.5f, -R_LINE_TO, 14, 14, -END +R_LINE_TO, 14, 14
diff --git a/ash/resources/vector_icons/network_badge_off.icon b/ash/resources/vector_icons/network_badge_off.icon index d68754eb..3726648 100644 --- a/ash/resources/vector_icons/network_badge_off.icon +++ b/ash/resources/vector_icons/network_badge_off.icon
@@ -11,5 +11,4 @@ CAP_SQUARE, STROKE, 3, MOVE_TO, 4, 4, -R_LINE_TO, 28, 28, -END +R_LINE_TO, 28, 28
diff --git a/ash/resources/vector_icons/network_badge_roaming.1x.icon b/ash/resources/vector_icons/network_badge_roaming.1x.icon index 4841e2b..a028fb08 100644 --- a/ash/resources/vector_icons/network_badge_roaming.1x.icon +++ b/ash/resources/vector_icons/network_badge_roaming.1x.icon
@@ -6,5 +6,4 @@ MOVE_TO, 3.5f, 2, LINE_TO, 1, 6, R_H_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_roaming.icon b/ash/resources/vector_icons/network_badge_roaming.icon index 849c3ce1..1395081 100644 --- a/ash/resources/vector_icons/network_badge_roaming.icon +++ b/ash/resources/vector_icons/network_badge_roaming.icon
@@ -6,5 +6,4 @@ MOVE_TO, 8, 4, R_LINE_TO, -5, 8, R_H_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_secure.1x.icon b/ash/resources/vector_icons/network_badge_secure.1x.icon index 8d94712..d341cd2 100644 --- a/ash/resources/vector_icons/network_badge_secure.1x.icon +++ b/ash/resources/vector_icons/network_badge_secure.1x.icon
@@ -36,5 +36,4 @@ R_H_LINE_TO, -3, V_LINE_TO, 0, R_H_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_secure.icon b/ash/resources/vector_icons/network_badge_secure.icon index 07e54be..16b32d6 100644 --- a/ash/resources/vector_icons/network_badge_secure.icon +++ b/ash/resources/vector_icons/network_badge_secure.icon
@@ -32,5 +32,4 @@ H_LINE_TO, 6, V_LINE_TO, 5, CUBIC_TO, 6, 3.89f, 6.89f, 3, 8, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_1x.1x.icon b/ash/resources/vector_icons/network_badge_technology_1x.1x.icon index 817ce4a..68940a1 100644 --- a/ash/resources/vector_icons/network_badge_technology_1x.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_1x.1x.icon
@@ -40,5 +40,4 @@ R_V_LINE_TO, 1, H_LINE_TO, 5, V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_1x.icon b/ash/resources/vector_icons/network_badge_technology_1x.icon index cfab3cc..cb39af6 100644 --- a/ash/resources/vector_icons/network_badge_technology_1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_1x.icon
@@ -40,5 +40,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_3g.1x.icon b/ash/resources/vector_icons/network_badge_technology_3g.1x.icon index 82c3f3c..3fc0c19 100644 --- a/ash/resources/vector_icons/network_badge_technology_3g.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_3g.1x.icon
@@ -32,5 +32,4 @@ R_V_LINE_TO, 1, H_LINE_TO, 0, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_3g.icon b/ash/resources/vector_icons/network_badge_technology_3g.icon index d32b539..b599cbb5 100644 --- a/ash/resources/vector_icons/network_badge_technology_3g.icon +++ b/ash/resources/vector_icons/network_badge_technology_3g.icon
@@ -28,5 +28,4 @@ H_LINE_TO, 2, R_V_LINE_TO, 2, R_H_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_4g.1x.icon b/ash/resources/vector_icons/network_badge_technology_4g.1x.icon index 93701b10..e3671d6 100644 --- a/ash/resources/vector_icons/network_badge_technology_4g.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_4g.1x.icon
@@ -43,5 +43,4 @@ H_LINE_TO, 6, V_LINE_TO, 1, R_H_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_4g.icon b/ash/resources/vector_icons/network_badge_technology_4g.icon index 2d5b3f7..0476d56 100644 --- a/ash/resources/vector_icons/network_badge_technology_4g.icon +++ b/ash/resources/vector_icons/network_badge_technology_4g.icon
@@ -43,5 +43,4 @@ R_H_LINE_TO, -4, V_LINE_TO, 2, R_H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_edge.1x.icon b/ash/resources/vector_icons/network_badge_technology_edge.1x.icon index 3201fc5..eb063f0 100644 --- a/ash/resources/vector_icons/network_badge_technology_edge.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_edge.1x.icon
@@ -15,5 +15,4 @@ V_LINE_TO, 1, R_H_LINE_TO, 2, V_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_edge.icon b/ash/resources/vector_icons/network_badge_technology_edge.icon index 750e5f3..d49cbc6 100644 --- a/ash/resources/vector_icons/network_badge_technology_edge.icon +++ b/ash/resources/vector_icons/network_badge_technology_edge.icon
@@ -15,5 +15,4 @@ V_LINE_TO, 2, R_H_LINE_TO, 4, V_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_evdo.1x.icon b/ash/resources/vector_icons/network_badge_technology_evdo.1x.icon index 760ed29a..1fd544b 100644 --- a/ash/resources/vector_icons/network_badge_technology_evdo.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_evdo.1x.icon
@@ -44,5 +44,4 @@ R_V_LINE_TO, 1, H_LINE_TO, 6, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_evdo.icon b/ash/resources/vector_icons/network_badge_technology_evdo.icon index 9127e6b..899db78 100644 --- a/ash/resources/vector_icons/network_badge_technology_evdo.icon +++ b/ash/resources/vector_icons/network_badge_technology_evdo.icon
@@ -44,5 +44,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2, V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_gprs.1x.icon b/ash/resources/vector_icons/network_badge_technology_gprs.1x.icon index 52a3a64..6eb86f0 100644 --- a/ash/resources/vector_icons/network_badge_technology_gprs.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_gprs.1x.icon
@@ -15,5 +15,4 @@ H_LINE_TO, 1, V_LINE_TO, 1, R_H_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_gprs.icon b/ash/resources/vector_icons/network_badge_technology_gprs.icon index 0510519..5067630 100644 --- a/ash/resources/vector_icons/network_badge_technology_gprs.icon +++ b/ash/resources/vector_icons/network_badge_technology_gprs.icon
@@ -15,5 +15,4 @@ H_LINE_TO, 2, V_LINE_TO, 2, R_H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_hspa.1x.icon b/ash/resources/vector_icons/network_badge_technology_hspa.1x.icon index f09c088..fcc4378 100644 --- a/ash/resources/vector_icons/network_badge_technology_hspa.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_hspa.1x.icon
@@ -15,5 +15,4 @@ H_LINE_TO, 1, R_V_LINE_TO, 2, H_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_hspa.icon b/ash/resources/vector_icons/network_badge_technology_hspa.icon index 658476b..e739db6 100644 --- a/ash/resources/vector_icons/network_badge_technology_hspa.icon +++ b/ash/resources/vector_icons/network_badge_technology_hspa.icon
@@ -15,5 +15,4 @@ H_LINE_TO, 2, R_V_LINE_TO, 4, H_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_hspa_plus.1x.icon b/ash/resources/vector_icons/network_badge_technology_hspa_plus.1x.icon index 16033ae..531bd6c 100644 --- a/ash/resources/vector_icons/network_badge_technology_hspa_plus.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_hspa_plus.1x.icon
@@ -28,5 +28,4 @@ R_H_LINE_TO, 1, V_LINE_TO, 1, H_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_hspa_plus.icon b/ash/resources/vector_icons/network_badge_technology_hspa_plus.icon index 0795621f..3b02ec6 100644 --- a/ash/resources/vector_icons/network_badge_technology_hspa_plus.icon +++ b/ash/resources/vector_icons/network_badge_technology_hspa_plus.icon
@@ -27,5 +27,4 @@ H_LINE_TO, 2, R_V_LINE_TO, 4, H_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_lte.1x.icon b/ash/resources/vector_icons/network_badge_technology_lte.1x.icon index 6c3513d6..a29b7d2 100644 --- a/ash/resources/vector_icons/network_badge_technology_lte.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_lte.1x.icon
@@ -29,5 +29,4 @@ V_LINE_TO, 1, R_H_LINE_TO, 2, V_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_lte.icon b/ash/resources/vector_icons/network_badge_technology_lte.icon index 216a9e1b..ef5d14f 100644 --- a/ash/resources/vector_icons/network_badge_technology_lte.icon +++ b/ash/resources/vector_icons/network_badge_technology_lte.icon
@@ -29,5 +29,4 @@ V_LINE_TO, 2, R_H_LINE_TO, 4, V_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_lte_advanced.1x.icon b/ash/resources/vector_icons/network_badge_technology_lte_advanced.1x.icon index f6bbf39f..d4df8a6 100644 --- a/ash/resources/vector_icons/network_badge_technology_lte_advanced.1x.icon +++ b/ash/resources/vector_icons/network_badge_technology_lte_advanced.1x.icon
@@ -42,5 +42,4 @@ R_H_LINE_TO, 1, V_LINE_TO, 1, R_H_LINE_TO, -1, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_technology_lte_advanced.icon b/ash/resources/vector_icons/network_badge_technology_lte_advanced.icon index c5b67158..88e954a 100644 --- a/ash/resources/vector_icons/network_badge_technology_lte_advanced.icon +++ b/ash/resources/vector_icons/network_badge_technology_lte_advanced.icon
@@ -41,5 +41,4 @@ V_LINE_TO, 3, R_H_LINE_TO, -3, V_LINE_TO, 0, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_vpn.1x.icon b/ash/resources/vector_icons/network_badge_vpn.1x.icon index 442103a..c324612 100644 --- a/ash/resources/vector_icons/network_badge_vpn.1x.icon +++ b/ash/resources/vector_icons/network_badge_vpn.1x.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 1, H_LINE_TO, 2, V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_badge_vpn.icon b/ash/resources/vector_icons/network_badge_vpn.icon index 0b41ec5d..7d67067e 100644 --- a/ash/resources/vector_icons/network_badge_vpn.icon +++ b/ash/resources/vector_icons/network_badge_vpn.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 4, V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_ethernet.1x.icon b/ash/resources/vector_icons/network_ethernet.1x.icon index 118076b..06e490e 100644 --- a/ash/resources/vector_icons/network_ethernet.1x.icon +++ b/ash/resources/vector_icons/network_ethernet.1x.icon
@@ -36,5 +36,4 @@ LINE_TO, 17, 10.5f, LINE_TO, 12.99f, 6, LINE_TO, 12, 6.77f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_ethernet.icon b/ash/resources/vector_icons/network_ethernet.icon index ac773a1..2d03672 100644 --- a/ash/resources/vector_icons/network_ethernet.icon +++ b/ash/resources/vector_icons/network_ethernet.icon
@@ -36,5 +36,4 @@ LINE_TO, 34, 20, R_LINE_TO, -7.23f, -8, LINE_TO, 25, 13.37f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_mobile_not_connected_x.1x.icon b/ash/resources/vector_icons/network_mobile_not_connected_x.1x.icon index cfd01f5..ed4b5087 100644 --- a/ash/resources/vector_icons/network_mobile_not_connected_x.1x.icon +++ b/ash/resources/vector_icons/network_mobile_not_connected_x.1x.icon
@@ -15,5 +15,4 @@ LINE_TO, 8.8f, 9.5f, R_LINE_TO, 0.71f, -0.7f, LINE_TO, 6.71f, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_mobile_not_connected_x.icon b/ash/resources/vector_icons/network_mobile_not_connected_x.icon index 5b3dc34..01e70a8 100644 --- a/ash/resources/vector_icons/network_mobile_not_connected_x.icon +++ b/ash/resources/vector_icons/network_mobile_not_connected_x.icon
@@ -15,5 +15,4 @@ R_LINE_TO, 5.75f, 5.75f, R_LINE_TO, 1.45f, -1.45f, LINE_TO, 13.45f, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_vpn.1x.icon b/ash/resources/vector_icons/network_vpn.1x.icon index f571630..4bb19e3 100644 --- a/ash/resources/vector_icons/network_vpn.1x.icon +++ b/ash/resources/vector_icons/network_vpn.1x.icon
@@ -21,5 +21,4 @@ CUBIC_TO_SHORTHAND, 5.56f, 8, 6.36f, 8, R_CUBIC_TO, 0.8f, 0, 1.45f, 0.68f, 1.45f, 1.5f, CUBIC_TO_SHORTHAND, 7.16f, 11, 6.36f, 11, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/network_vpn.icon b/ash/resources/vector_icons/network_vpn.icon index 14ee56d..bf71962 100644 --- a/ash/resources/vector_icons/network_vpn.icon +++ b/ash/resources/vector_icons/network_vpn.icon
@@ -21,5 +21,4 @@ R_CUBIC_TO, 0, -1.65f, 1.31f, -3, 2.91f, -3, R_CUBIC_TO, 1.6f, 0, 2.91f, 1.35f, 2.91f, 3, R_CUBIC_TO, 0, 1.65f, -1.31f, 3, -2.91f, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_accessibility.icon b/ash/resources/vector_icons/notification_accessibility.icon index f421616..7daef85 100644 --- a/ash/resources/vector_icons/notification_accessibility.icon +++ b/ash/resources/vector_icons/notification_accessibility.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, -8, R_H_LINE_TO, 72, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_accessibility_braille.icon b/ash/resources/vector_icons/notification_accessibility_braille.icon index da8f4451..203bc18 100644 --- a/ash/resources/vector_icons/notification_accessibility_braille.icon +++ b/ash/resources/vector_icons/notification_accessibility_braille.icon
@@ -44,5 +44,4 @@ R_CUBIC_TO, 0, -4.42f, -3.58f, -8, -8, -8, R_CUBIC_TO, -4.42f, 0, -8, 3.58f, -8, 8, R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_battery_critical.icon b/ash/resources/vector_icons/notification_battery_critical.icon index 392effe..48de6c91 100644 --- a/ash/resources/vector_icons/notification_battery_critical.icon +++ b/ash/resources/vector_icons/notification_battery_critical.icon
@@ -40,5 +40,4 @@ H_LINE_TO, 33, R_CUBIC_TO, -3.31f, 0, -6, -2.69f, -6, -6, V_LINE_TO, 72, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_battery_fluctuating.icon b/ash/resources/vector_icons/notification_battery_fluctuating.icon index 55987dd0..5de9b4e 100644 --- a/ash/resources/vector_icons/notification_battery_fluctuating.icon +++ b/ash/resources/vector_icons/notification_battery_fluctuating.icon
@@ -46,5 +46,4 @@ R_CUBIC_TO, 5.59f, 0, 10.28f, -2.99f, 11.94f, -7.13f, R_CUBIC_TO, 0.03f, 4.39f, -1.3f, 7.95f, -3.97f, 10.69f, CUBIC_TO, 80.35f, 46.63f, 76.91f, 48, 72.68f, 48, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_battery_low.icon b/ash/resources/vector_icons/notification_battery_low.icon index 392effe..48de6c91 100644 --- a/ash/resources/vector_icons/notification_battery_low.icon +++ b/ash/resources/vector_icons/notification_battery_low.icon
@@ -40,5 +40,4 @@ H_LINE_TO, 33, R_CUBIC_TO, -3.31f, 0, -6, -2.69f, -6, -6, V_LINE_TO, 72, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_bluetooth.icon b/ash/resources/vector_icons/notification_bluetooth.icon index e60c6c32e..42cf2c1b 100644 --- a/ash/resources/vector_icons/notification_bluetooth.icon +++ b/ash/resources/vector_icons/notification_bluetooth.icon
@@ -34,5 +34,4 @@ R_LINE_TO, 4.7f, 4.8f, R_LINE_TO, -4.7f, 4.8f, R_V_LINE_TO, -9.6f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_bluetooth_battery_warning.icon b/ash/resources/vector_icons/notification_bluetooth_battery_warning.icon index af8cf513..d5d94aa 100644 --- a/ash/resources/vector_icons/notification_bluetooth_battery_warning.icon +++ b/ash/resources/vector_icons/notification_bluetooth_battery_warning.icon
@@ -66,5 +66,4 @@ R_LINE_TO, -4.44f, 4.32f, R_V_LINE_TO, -8.65f, R_LINE_TO, 4.44f, 4.32f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_capslock.icon b/ash/resources/vector_icons/notification_capslock.icon index adc9730..3342321 100644 --- a/ash/resources/vector_icons/notification_capslock.icon +++ b/ash/resources/vector_icons/notification_capslock.icon
@@ -26,5 +26,4 @@ H_LINE_TO, 28, R_V_LINE_TO, 6, R_H_LINE_TO, 40, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_all_done.icon b/ash/resources/vector_icons/notification_center_all_done.icon index 64945ba2..830202c2 100644 --- a/ash/resources/vector_icons/notification_center_all_done.icon +++ b/ash/resources/vector_icons/notification_center_all_done.icon
@@ -24,5 +24,4 @@ R_LINE_TO, 2.82f, -2.82f, LINE_TO, 22, 26.34f, LINE_TO, 41.18f, 7.16f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_clear_all.icon b/ash/resources/vector_icons/notification_center_clear_all.icon index d44a3959a..9fdd51a 100644 --- a/ash/resources/vector_icons/notification_center_clear_all.icon +++ b/ash/resources/vector_icons/notification_center_clear_all.icon
@@ -20,5 +20,4 @@ R_H_LINE_TO, 24, R_V_LINE_TO, -4, H_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_collapse.icon b/ash/resources/vector_icons/notification_center_collapse.icon index c6c3ae2..712c430 100644 --- a/ash/resources/vector_icons/notification_center_collapse.icon +++ b/ash/resources/vector_icons/notification_center_collapse.icon
@@ -9,5 +9,4 @@ LINE_TO, 32, 15.05f, LINE_TO, 20, 28, LINE_TO, 8, 15.05f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_do_not_disturb_off.icon b/ash/resources/vector_icons/notification_center_do_not_disturb_off.icon index 89ea4240..c2cc68d0 100644 --- a/ash/resources/vector_icons/notification_center_do_not_disturb_off.icon +++ b/ash/resources/vector_icons/notification_center_do_not_disturb_off.icon
@@ -29,5 +29,4 @@ R_H_LINE_TO, 2.5f, R_LINE_TO, 3, 4, H_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_do_not_disturb_on.icon b/ash/resources/vector_icons/notification_center_do_not_disturb_on.icon index 04c1bb3..fa642b5f 100644 --- a/ash/resources/vector_icons/notification_center_do_not_disturb_on.icon +++ b/ash/resources/vector_icons/notification_center_do_not_disturb_on.icon
@@ -14,5 +14,4 @@ R_V_LINE_TO, -4, R_H_LINE_TO, 16, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_empty.icon b/ash/resources/vector_icons/notification_center_empty.icon index 470c6c0..c86965e 100644 --- a/ash/resources/vector_icons/notification_center_empty.icon +++ b/ash/resources/vector_icons/notification_center_empty.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4, R_CUBIC_TO, 2.21f, 0, 4, -1.79f, 4, -4, R_CUBIC_TO, 0, -2.21f, -1.79f, -4, -4, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_center_settings.icon b/ash/resources/vector_icons/notification_center_settings.icon index 1b9b193..30268cc 100644 --- a/ash/resources/vector_icons/notification_center_settings.icon +++ b/ash/resources/vector_icons/notification_center_settings.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, 0, -3.09f, 2.58f, -5.6f, 5.76f, -5.6f, R_CUBIC_TO, 3.17f, 0, 5.76f, 2.51f, 5.76f, 5.6f, R_CUBIC_TO, 0, 3.09f, -2.58f, 5.6f, -5.76f, 5.6f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_charging_usb_c.icon b/ash/resources/vector_icons/notification_charging_usb_c.icon index 00901903..98ac5957 100644 --- a/ash/resources/vector_icons/notification_charging_usb_c.icon +++ b/ash/resources/vector_icons/notification_charging_usb_c.icon
@@ -34,5 +34,4 @@ R_CUBIC_TO, -3.87f, 0, -7, -3.13f, -7, -7, V_LINE_TO, 36, R_CUBIC_TO, 0, -3.87f, 3.13f, -7, 7, -7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_chromevox.icon b/ash/resources/vector_icons/notification_chromevox.icon index 3f3370d..8764241 100644 --- a/ash/resources/vector_icons/notification_chromevox.icon +++ b/ash/resources/vector_icons/notification_chromevox.icon
@@ -38,5 +38,4 @@ R_CUBIC_TO, -1.09f, -3.06f, -2.49f, -6.01f, -4.06f, -8.85f, R_CUBIC_TO, -2.63f, -4.77f, -4.74f, -9.81f, -7.68f, -14.42f, R_CUBIC_TO, -0.55f, -0.02f, -1.13f, -0.04f, -1.73f, -0.08f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_keyboard.icon b/ash/resources/vector_icons/notification_keyboard.icon index 7869427..fb722a9 100644 --- a/ash/resources/vector_icons/notification_keyboard.icon +++ b/ash/resources/vector_icons/notification_keyboard.icon
@@ -78,5 +78,4 @@ R_V_LINE_TO, -8, R_H_LINE_TO, 8, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_low_power_charger.icon b/ash/resources/vector_icons/notification_low_power_charger.icon index 55987dd0..5de9b4e 100644 --- a/ash/resources/vector_icons/notification_low_power_charger.icon +++ b/ash/resources/vector_icons/notification_low_power_charger.icon
@@ -46,5 +46,4 @@ R_CUBIC_TO, 5.59f, 0, 10.28f, -2.99f, 11.94f, -7.13f, R_CUBIC_TO, 0.03f, 4.39f, -1.3f, 7.95f, -3.97f, 10.69f, CUBIC_TO, 80.35f, 46.63f, 76.91f, 48, 72.68f, 48, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_monitor_warning.icon b/ash/resources/vector_icons/notification_monitor_warning.icon index bd17076..81420a9 100644 --- a/ash/resources/vector_icons/notification_monitor_warning.icon +++ b/ash/resources/vector_icons/notification_monitor_warning.icon
@@ -38,5 +38,4 @@ R_H_LINE_TO, 4, R_V_LINE_TO, -4, R_H_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_screen.icon b/ash/resources/vector_icons/notification_screen.icon index 1c94d63..250b1c10 100644 --- a/ash/resources/vector_icons/notification_screen.icon +++ b/ash/resources/vector_icons/notification_screen.icon
@@ -22,5 +22,4 @@ R_H_LINE_TO, 64, V_LINE_TO, 24, H_LINE_TO, 16, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_screenshare.icon b/ash/resources/vector_icons/notification_screenshare.icon index 248789d..8352493 100644 --- a/ash/resources/vector_icons/notification_screenshare.icon +++ b/ash/resources/vector_icons/notification_screenshare.icon
@@ -26,5 +26,4 @@ LINE_TO, 68, 48, LINE_TO, 53.46f, 63, V_LINE_TO, 52.62f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_settings.icon b/ash/resources/vector_icons/notification_settings.icon index 9b861f29..133f039 100644 --- a/ash/resources/vector_icons/notification_settings.icon +++ b/ash/resources/vector_icons/notification_settings.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, 0, -1.66f, 1.34f, -3, 3, -3, R_CUBIC_TO, 1.66f, 0, 3, 1.34f, 3, 3, R_CUBIC_TO, 0, 1.66f, -1.34f, 3, -3, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_sms_sync.icon b/ash/resources/vector_icons/notification_sms_sync.icon index ea0b8778..26fc6f6 100644 --- a/ash/resources/vector_icons/notification_sms_sync.icon +++ b/ash/resources/vector_icons/notification_sms_sync.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, 8, R_H_LINE_TO, 18, R_V_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_stylus_battery_warning.icon b/ash/resources/vector_icons/notification_stylus_battery_warning.icon index 478d28aa5..6ed0b4c 100644 --- a/ash/resources/vector_icons/notification_stylus_battery_warning.icon +++ b/ash/resources/vector_icons/notification_stylus_battery_warning.icon
@@ -68,5 +68,4 @@ R_CUBIC_TO, -2.65f, 0, -4.8f, -2.39f, -4.8f, -5.33f, V_LINE_TO, 77, R_H_LINE_TO, 24, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_supervised.icon b/ash/resources/vector_icons/notification_supervised.icon index c3f490a..c4de8d59 100644 --- a/ash/resources/vector_icons/notification_supervised.icon +++ b/ash/resources/vector_icons/notification_supervised.icon
@@ -25,5 +25,4 @@ R_LINE_TO, 6.11f, -9.32f, LINE_TO, 76.8f, 38.41f, LINE_TO, 49.54f, 9.6f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/notification_timer.icon b/ash/resources/vector_icons/notification_timer.icon index c98846d..25038b6 100644 --- a/ash/resources/vector_icons/notification_timer.icon +++ b/ash/resources/vector_icons/notification_timer.icon
@@ -30,5 +30,4 @@ R_CUBIC_TO, 0, -15.48f, 12.52f, -28, 28, -28, R_CUBIC_TO, 15.48f, 0, 28, 12.52f, 28, 28, R_CUBIC_TO, 0, 15.48f, -12.52f, 28, -28, 28, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/overview_text_filter_search.icon b/ash/resources/vector_icons/overview_text_filter_search.icon index 60f612d..363f869 100644 --- a/ash/resources/vector_icons/overview_text_filter_search.icon +++ b/ash/resources/vector_icons/overview_text_filter_search.icon
@@ -20,5 +20,4 @@ R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, 3.6f, -3.6f, R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, 3.6f, 3.6f, R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, -3.6f, 3.6f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/overview_window_close.icon b/ash/resources/vector_icons/overview_window_close.icon index 07a9f48..4ee6ebb 100644 --- a/ash/resources/vector_icons/overview_window_close.icon +++ b/ash/resources/vector_icons/overview_window_close.icon
@@ -15,5 +15,4 @@ LINE_TO, 17.59f, 19, LINE_TO, 19, 17.59f, LINE_TO, 13.42f, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_capture_region.1x.icon b/ash/resources/vector_icons/palette_action_capture_region.1x.icon index 7934c78..38166de 100644 --- a/ash/resources/vector_icons/palette_action_capture_region.1x.icon +++ b/ash/resources/vector_icons/palette_action_capture_region.1x.icon
@@ -91,5 +91,4 @@ R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, R_H_LINE_TO, -2, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_capture_region.icon b/ash/resources/vector_icons/palette_action_capture_region.icon index d08e5d9..ec36ff1c 100644 --- a/ash/resources/vector_icons/palette_action_capture_region.icon +++ b/ash/resources/vector_icons/palette_action_capture_region.icon
@@ -91,5 +91,4 @@ R_CUBIC_TO, 1.65f, 0, 3, -1.35f, 3, -3, R_H_LINE_TO, -3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_capture_screen.1x.icon b/ash/resources/vector_icons/palette_action_capture_screen.1x.icon index 01a9fc0..e31838c 100644 --- a/ash/resources/vector_icons/palette_action_capture_screen.1x.icon +++ b/ash/resources/vector_icons/palette_action_capture_screen.1x.icon
@@ -79,5 +79,4 @@ LINE_TO, 17, 15.5f, LINE_TO, 14.5f, 13, LINE_TO, 13, 14.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_capture_screen.icon b/ash/resources/vector_icons/palette_action_capture_screen.icon index 3e23bd0f..58384359 100644 --- a/ash/resources/vector_icons/palette_action_capture_screen.icon +++ b/ash/resources/vector_icons/palette_action_capture_screen.icon
@@ -79,5 +79,4 @@ R_V_LINE_TO, 4.49f, R_LINE_TO, -4.5f, -4.1f, R_LINE_TO, -2.38f, 2.29f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_create_note.1x.icon b/ash/resources/vector_icons/palette_action_create_note.1x.icon index 5668b89..5130810 100644 --- a/ash/resources/vector_icons/palette_action_create_note.1x.icon +++ b/ash/resources/vector_icons/palette_action_create_note.1x.icon
@@ -31,5 +31,4 @@ R_V_LINE_TO, 2, R_LINE_TO, 2, 0.02f, R_V_LINE_TO, 2.02f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_action_create_note.icon b/ash/resources/vector_icons/palette_action_create_note.icon index 3e009ae..7fff6de 100644 --- a/ash/resources/vector_icons/palette_action_create_note.icon +++ b/ash/resources/vector_icons/palette_action_create_note.icon
@@ -31,5 +31,4 @@ R_V_LINE_TO, 4.5f, H_LINE_TO, 26, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_laser_pointer.1x.icon b/ash/resources/vector_icons/palette_mode_laser_pointer.1x.icon index 103cd67..da1e02f 100644 --- a/ash/resources/vector_icons/palette_mode_laser_pointer.1x.icon +++ b/ash/resources/vector_icons/palette_mode_laser_pointer.1x.icon
@@ -39,5 +39,4 @@ R_LINE_TO, 0.01f, -0.01f, R_CUBIC_TO, 0.16f, -0.11f, 0.32f, -0.24f, 0.45f, -0.38f, CUBIC_TO, 8.67f, 17.56f, 9, 16.82f, 9, 16, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_laser_pointer.icon b/ash/resources/vector_icons/palette_mode_laser_pointer.icon index 8a0139b..7fbb157 100644 --- a/ash/resources/vector_icons/palette_mode_laser_pointer.icon +++ b/ash/resources/vector_icons/palette_mode_laser_pointer.icon
@@ -38,5 +38,4 @@ R_LINE_TO, 0.02f, -0.01f, R_CUBIC_TO, 0.33f, -0.22f, 0.63f, -0.48f, 0.91f, -0.76f, CUBIC_TO, 17.34f, 35.69f, 18, 34.21f, 18, 32.57f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_magnify.1x.icon b/ash/resources/vector_icons/palette_mode_magnify.1x.icon index fe3d5fa..d78a6bd 100644 --- a/ash/resources/vector_icons/palette_mode_magnify.1x.icon +++ b/ash/resources/vector_icons/palette_mode_magnify.1x.icon
@@ -32,5 +32,4 @@ R_CUBIC_TO, 0, 2.76f, 2.24f, 5, 5, 5, R_CUBIC_TO, 2.76f, 0, 5, -2.24f, 5, -5, R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_magnify.icon b/ash/resources/vector_icons/palette_mode_magnify.icon index 53f1c380..9dc94580 100644 --- a/ash/resources/vector_icons/palette_mode_magnify.icon +++ b/ash/resources/vector_icons/palette_mode_magnify.icon
@@ -32,5 +32,4 @@ R_CUBIC_TO, 0, 5.51f, 4.49f, 10, 10, 10, R_CUBIC_TO, 5.51f, 0, 10, -4.49f, 10, -10, R_CUBIC_TO, 0, -5.51f, -4.49f, -10, -10, -10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_metalayer.1x.icon b/ash/resources/vector_icons/palette_mode_metalayer.1x.icon index 787ebf33..af625a90 100644 --- a/ash/resources/vector_icons/palette_mode_metalayer.1x.icon +++ b/ash/resources/vector_icons/palette_mode_metalayer.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 4.12f, 2.92f, 2.21f, 4.83f, 2.21f, 7.19f, CUBIC_TO, 2.21f, 9.55f, 4.12f, 11.46f, 6.48f, 11.46f, CUBIC_TO, 8.83f, 11.46f, 10.74f, 9.55f, 10.74f, 7.19f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_mode_metalayer.icon b/ash/resources/vector_icons/palette_mode_metalayer.icon index 3f9b3c8..30f7b153 100644 --- a/ash/resources/vector_icons/palette_mode_metalayer.icon +++ b/ash/resources/vector_icons/palette_mode_metalayer.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 8.24f, 5.84f, 4.42f, 9.66f, 4.42f, 14.38f, CUBIC_TO, 4.42f, 19.09f, 8.24f, 22.91f, 12.96f, 22.91f, CUBIC_TO, 17.67f, 22.91f, 21.49f, 19.09f, 21.49f, 14.38f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon b/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon index 7e79e42f..fc023d8 100644 --- a/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_capture_region.1x.icon
@@ -91,5 +91,4 @@ R_CUBIC_TO, 0.83f, 0, 1.5f, -0.67f, 1.5f, -1.5f, H_LINE_TO, 13, V_LINE_TO, 14, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_capture_region.icon b/ash/resources/vector_icons/palette_tray_icon_capture_region.icon index 6084e354..e625132 100644 --- a/ash/resources/vector_icons/palette_tray_icon_capture_region.icon +++ b/ash/resources/vector_icons/palette_tray_icon_capture_region.icon
@@ -91,5 +91,4 @@ R_CUBIC_TO, 1.65f, 0, 3, -1.35f, 3, -3, R_H_LINE_TO, -3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_default.1x.icon b/ash/resources/vector_icons/palette_tray_icon_default.1x.icon index 9fbd3357..4fc848e9 100644 --- a/ash/resources/vector_icons/palette_tray_icon_default.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_default.1x.icon
@@ -24,5 +24,4 @@ R_LINE_TO, 5.03f, -5.02f, R_LINE_TO, -2.5f, -2.5f, LINE_TO, 2, 11.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_default.icon b/ash/resources/vector_icons/palette_tray_icon_default.icon index 05da1c7e..6a13e8b 100644 --- a/ash/resources/vector_icons/palette_tray_icon_default.icon +++ b/ash/resources/vector_icons/palette_tray_icon_default.icon
@@ -24,5 +24,4 @@ R_LINE_TO, 10.05f, -10.04f, R_LINE_TO, -5, -5, LINE_TO, 4, 23, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon index c14a706..640bf3a 100644 --- a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon
@@ -38,5 +38,4 @@ R_LINE_TO, 0.01f, 0, R_CUBIC_TO, 0.13f, -0.09f, 0.25f, -0.19f, 0.36f, -0.3f, R_CUBIC_TO, 0.43f, -0.43f, 0.69f, -1.02f, 0.69f, -1.68f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon index f853141..66f7e02 100644 --- a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon +++ b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.icon
@@ -38,5 +38,4 @@ R_LINE_TO, 0.02f, -0.01f, R_CUBIC_TO, 0.26f, -0.18f, 0.51f, -0.38f, 0.73f, -0.61f, R_CUBIC_TO, 0.85f, -0.87f, 1.38f, -2.05f, 1.38f, -3.36f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon index ec89944f..fd09e3d 100644 --- a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon
@@ -32,5 +32,4 @@ R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4, R_CUBIC_TO, 2.2f, 0, 4, -1.79f, 4, -4, R_CUBIC_TO, 0, -2.21f, -1.8f, -4, -4, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.icon index 317e26f..229edf3 100644 --- a/ash/resources/vector_icons/palette_tray_icon_magnify.icon +++ b/ash/resources/vector_icons/palette_tray_icon_magnify.icon
@@ -32,5 +32,4 @@ R_CUBIC_TO, 0, 4.41f, 3.59f, 8, 8, 8, R_CUBIC_TO, 4.41f, 0, 8, -3.59f, 8, -8, R_CUBIC_TO, 0, -4.41f, -3.59f, -8, -8, -8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon index 2116990..cda823b 100644 --- a/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 3.3f, 2.34f, 1.77f, 3.87f, 1.77f, 5.75f, CUBIC_TO, 1.77f, 7.64f, 3.3f, 9.16f, 5.18f, 9.16f, CUBIC_TO, 7.07f, 9.16f, 8.6f, 7.64f, 8.6f, 5.75f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/palette_tray_icon_metalayer.icon b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon index 326b4430..485fe19 100644 --- a/ash/resources/vector_icons/palette_tray_icon_metalayer.icon +++ b/ash/resources/vector_icons/palette_tray_icon_metalayer.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 6.59f, 4.68f, 3.54f, 7.73f, 3.54f, 11.5f, CUBIC_TO, 3.54f, 15.27f, 6.59f, 18.33f, 10.36f, 18.33f, CUBIC_TO, 14.13f, 18.33f, 17.19f, 15.27f, 17.19f, 11.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_add_person_button.1x.icon b/ash/resources/vector_icons/shelf_add_person_button.1x.icon index f0833e4..8ddc616f 100644 --- a/ash/resources/vector_icons/shelf_add_person_button.1x.icon +++ b/ash/resources/vector_icons/shelf_add_person_button.1x.icon
@@ -25,5 +25,4 @@ R_CUBIC_TO, 0.62f, 0, 1.22f, -0.07f, 1.8f, -0.21f, R_CUBIC_TO, 0.17f, 0.57f, 0.26f, 1.18f, 0.26f, 1.81f, R_CUBIC_TO, 0, 3.53f, -2.87f, 6.4f, -6.4f, 6.4f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_add_person_button.icon b/ash/resources/vector_icons/shelf_add_person_button.icon index 6a49c948..0095061 100644 --- a/ash/resources/vector_icons/shelf_add_person_button.icon +++ b/ash/resources/vector_icons/shelf_add_person_button.icon
@@ -25,5 +25,4 @@ R_CUBIC_TO, 1.25f, 0, 2.45f, -0.14f, 3.6f, -0.42f, R_CUBIC_TO, 0.34f, 1.14f, 0.53f, 2.35f, 0.53f, 3.62f, R_CUBIC_TO, 0, 7.06f, -5.74f, 12.8f, -12.8f, 12.8f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_back.1x.icon b/ash/resources/vector_icons/shelf_back.1x.icon index fe152e3..01836db5 100644 --- a/ash/resources/vector_icons/shelf_back.1x.icon +++ b/ash/resources/vector_icons/shelf_back.1x.icon
@@ -14,5 +14,4 @@ R_LINE_TO, 6.9f, -7, LINE_TO, 10, 2.2f, LINE_TO, 5.2f, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_back.icon b/ash/resources/vector_icons/shelf_back.icon index 193bf72..2b21689 100644 --- a/ash/resources/vector_icons/shelf_back.icon +++ b/ash/resources/vector_icons/shelf_back.icon
@@ -13,5 +13,4 @@ R_LINE_TO, -9.86f, 9.99f, H_LINE_TO, 29, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_browse_as_guest_button.1x.icon b/ash/resources/vector_icons/shelf_browse_as_guest_button.1x.icon index 1f37af71..65e2be2 100644 --- a/ash/resources/vector_icons/shelf_browse_as_guest_button.1x.icon +++ b/ash/resources/vector_icons/shelf_browse_as_guest_button.1x.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 1.66f, 0, 4.97f, 0.95f, 5, 2.69f, R_CUBIC_TO, -1.07f, 1.69f, -2.92f, 2.81f, -5, 2.81f, R_CUBIC_TO, -2.08f, 0, -3.92f, -1.12f, -5, -2.81f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_browse_as_guest_button.icon b/ash/resources/vector_icons/shelf_browse_as_guest_button.icon index 3f7b0473..7e8882f 100644 --- a/ash/resources/vector_icons/shelf_browse_as_guest_button.icon +++ b/ash/resources/vector_icons/shelf_browse_as_guest_button.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 3.32f, 0, 9.95f, 1.9f, 10, 5.38f, CUBIC_TO, 27.85f, 29.77f, 24.17f, 32, 20, 32, R_CUBIC_TO, -4.17f, 0, -7.85f, -2.23f, -10, -5.62f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_cancel_button.1x.icon b/ash/resources/vector_icons/shelf_cancel_button.1x.icon index bb20d0d..afb813a 100644 --- a/ash/resources/vector_icons/shelf_cancel_button.1x.icon +++ b/ash/resources/vector_icons/shelf_cancel_button.1x.icon
@@ -9,5 +9,4 @@ R_CUBIC_TO, 2.94f, 0, 5.44f, 2.05f, 6.31f, 4.89f, LINE_TO, 18, 12.31f, CUBIC_TO, 16.85f, 8.58f, 13.58f, 5.89f, 9.72f, 5.89f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_cancel_button.icon b/ash/resources/vector_icons/shelf_cancel_button.icon index 38097bbb..049be591 100644 --- a/ash/resources/vector_icons/shelf_cancel_button.icon +++ b/ash/resources/vector_icons/shelf_cancel_button.icon
@@ -9,5 +9,4 @@ R_CUBIC_TO, 5.88f, 0, 10.88f, 3.85f, 12.62f, 9.17f, LINE_TO, 37, 24.7f, R_CUBIC_TO, -2.31f, -6.98f, -8.84f, -12.03f, -16.56f, -12.03f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_keyboard.1x.icon b/ash/resources/vector_icons/shelf_keyboard.1x.icon index 16f2a693..f1e2695 100644 --- a/ash/resources/vector_icons/shelf_keyboard.1x.icon +++ b/ash/resources/vector_icons/shelf_keyboard.1x.icon
@@ -78,5 +78,4 @@ R_H_LINE_TO, 5, R_V_LINE_TO, 1, H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_keyboard.icon b/ash/resources/vector_icons/shelf_keyboard.icon index 6875e8e..a7baa914 100644 --- a/ash/resources/vector_icons/shelf_keyboard.icon +++ b/ash/resources/vector_icons/shelf_keyboard.icon
@@ -78,5 +78,4 @@ R_V_LINE_TO, -3, R_H_LINE_TO, 3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_logout.1x.icon b/ash/resources/vector_icons/shelf_logout.1x.icon index a2e068f3..87915739 100644 --- a/ash/resources/vector_icons/shelf_logout.1x.icon +++ b/ash/resources/vector_icons/shelf_logout.1x.icon
@@ -31,5 +31,4 @@ R_V_LINE_TO, -8.9f, CUBIC_TO, 15, 2, 13.96f, 1.03f, 12.46f, 1.03f, R_H_LINE_TO, -8.9f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_logout.icon b/ash/resources/vector_icons/shelf_logout.icon index d695acc..aeca144b 100644 --- a/ash/resources/vector_icons/shelf_logout.icon +++ b/ash/resources/vector_icons/shelf_logout.icon
@@ -31,5 +31,4 @@ V_LINE_TO, 6.33f, CUBIC_TO, 29, 4.5f, 27.5f, 3, 25.67f, 3, H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_notifications.1x.icon b/ash/resources/vector_icons/shelf_notifications.1x.icon index 9c194d0..9ecfd7d 100644 --- a/ash/resources/vector_icons/shelf_notifications.1x.icon +++ b/ash/resources/vector_icons/shelf_notifications.1x.icon
@@ -22,5 +22,4 @@ R_H_LINE_TO, 10, R_V_LINE_TO, -0.71f, LINE_TO, 12, 10.1f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_notifications.icon b/ash/resources/vector_icons/shelf_notifications.icon index 5f5989d..780a14d0 100644 --- a/ash/resources/vector_icons/shelf_notifications.icon +++ b/ash/resources/vector_icons/shelf_notifications.icon
@@ -22,5 +22,4 @@ R_H_LINE_TO, 22, R_V_LINE_TO, -1.5f, LINE_TO, 24, 21, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_overflow.1x.icon b/ash/resources/vector_icons/shelf_overflow.1x.icon index 6caccb9..a13a532 100644 --- a/ash/resources/vector_icons/shelf_overflow.1x.icon +++ b/ash/resources/vector_icons/shelf_overflow.1x.icon
@@ -15,5 +15,4 @@ R_CUBIC_TO, 0.46f, 0, 0.83f, -0.38f, 0.83f, -0.86f, R_ARC_TO, 0.87f, 0.87f, 0, 0, 0, -0.24f, -0.61f, LINE_TO, 8.59f, 5.25f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_overflow.icon b/ash/resources/vector_icons/shelf_overflow.icon index 00b4db1..7886947 100644 --- a/ash/resources/vector_icons/shelf_overflow.icon +++ b/ash/resources/vector_icons/shelf_overflow.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 0.92f, 0, 1.67f, -0.77f, 1.67f, -1.71f, R_CUBIC_TO, 0, -0.47f, -0.19f, -0.9f, -0.49f, -1.21f, R_LINE_TO, -8.33f, -8.57f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_overview.1x.icon b/ash/resources/vector_icons/shelf_overview.1x.icon index 1a6790c..bc606772 100644 --- a/ash/resources/vector_icons/shelf_overview.1x.icon +++ b/ash/resources/vector_icons/shelf_overview.1x.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, 8, R_H_LINE_TO, -1, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_overview.icon b/ash/resources/vector_icons/shelf_overview.icon index 17f9031..b3b6e65 100644 --- a/ash/resources/vector_icons/shelf_overview.icon +++ b/ash/resources/vector_icons/shelf_overview.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, 18, R_H_LINE_TO, -3, V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_shutdown_button.1x.icon b/ash/resources/vector_icons/shelf_shutdown_button.1x.icon index 89e91cf..b6f277af 100644 --- a/ash/resources/vector_icons/shelf_shutdown_button.1x.icon +++ b/ash/resources/vector_icons/shelf_shutdown_button.1x.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 0, 4.14f, 3.36f, 7.5f, 7.5f, 7.5f, R_CUBIC_TO, 4.14f, 0, 7.5f, -3.36f, 7.5f, -7.5f, R_CUBIC_TO, 0, -2.28f, -1.02f, -4.32f, -2.64f, -5.69f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_shutdown_button.icon b/ash/resources/vector_icons/shelf_shutdown_button.icon index e177d6d..c7a3582 100644 --- a/ash/resources/vector_icons/shelf_shutdown_button.icon +++ b/ash/resources/vector_icons/shelf_shutdown_button.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 0, 8.28f, 6.72f, 15, 15, 15, R_CUBIC_TO, 8.28f, 0, 15, -6.72f, 15, -15, R_CUBIC_TO, 0, -4.57f, -2.05f, -8.63f, -5.28f, -11.38f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_sign_out_button.1x.icon b/ash/resources/vector_icons/shelf_sign_out_button.1x.icon index c2c4819..0d2816b 100644 --- a/ash/resources/vector_icons/shelf_sign_out_button.1x.icon +++ b/ash/resources/vector_icons/shelf_sign_out_button.1x.icon
@@ -27,5 +27,4 @@ V_LINE_TO, 4, R_CUBIC_TO, 0, -1, -1.02f, -2, -2, -2, H_LINE_TO, 4, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_sign_out_button.icon b/ash/resources/vector_icons/shelf_sign_out_button.icon index 8b7ac52..cb67a00 100644 --- a/ash/resources/vector_icons/shelf_sign_out_button.icon +++ b/ash/resources/vector_icons/shelf_sign_out_button.icon
@@ -27,5 +27,4 @@ V_LINE_TO, 8.33f, CUBIC_TO, 35, 6.5f, 33.5f, 5, 31.67f, 5, H_LINE_TO, 8.33f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/shelf_unlock_button.1x.icon b/ash/resources/vector_icons/shelf_unlock_button.1x.icon index 5dbfa40..6f02f39 100644 --- a/ash/resources/vector_icons/shelf_unlock_button.1x.icon +++ b/ash/resources/vector_icons/shelf_unlock_button.1x.icon
@@ -28,5 +28,4 @@ V_LINE_TO, 10, R_H_LINE_TO, 12, R_V_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/shelf_unlock_button.icon b/ash/resources/vector_icons/shelf_unlock_button.icon index 93f4156..05d82af 100644 --- a/ash/resources/vector_icons/shelf_unlock_button.icon +++ b/ash/resources/vector_icons/shelf_unlock_button.icon
@@ -28,5 +28,4 @@ V_LINE_TO, 20, R_H_LINE_TO, 24, R_V_LINE_TO, 20, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility.1x.icon b/ash/resources/vector_icons/system_menu_accessibility.1x.icon index bd185994b..1db087d 100644 --- a/ash/resources/vector_icons/system_menu_accessibility.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility.1x.icon
@@ -21,5 +21,4 @@ MOVE_TO, 10, 5, R_ARC_TO, 2, 2, 0, 1, 0, 0, -4, R_ARC_TO, 2, 2, 0, 0, 0, 0, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility.icon b/ash/resources/vector_icons/system_menu_accessibility.icon index 11bae49..c5033fb1 100644 --- a/ash/resources/vector_icons/system_menu_accessibility.icon +++ b/ash/resources/vector_icons/system_menu_accessibility.icon
@@ -21,5 +21,4 @@ R_MOVE_TO, 0, -2, R_ARC_TO, 3.5f, 3.5f, 0, 1, 0, 0, -7, R_ARC_TO, 3.5f, 3.5f, 0, 0, 0, 0, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_auto_click.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_auto_click.1x.icon index 2d2f1bb..85c15d8e 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_auto_click.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_auto_click.1x.icon
@@ -44,5 +44,4 @@ V_LINE_TO, 2, R_H_LINE_TO, 1, R_V_LINE_TO, 1, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_auto_click.icon b/ash/resources/vector_icons/system_menu_accessibility_auto_click.icon index 9545200..b81c373 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_auto_click.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_auto_click.icon
@@ -37,5 +37,4 @@ R_V_LINE_TO, -1.94f, R_CUBIC_TO, 2.86f, 0, 5.17f, -2.31f, 5.17f, -5.17f, R_CUBIC_TO, 0, -1.01f, -0.3f, -1.96f, -0.8f, -2.75f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon index 97e8c052..0720f3b 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon
@@ -38,5 +38,4 @@ R_CUBIC_TO, -0.22f, -0.61f, -0.5f, -1.2f, -0.81f, -1.77f, R_CUBIC_TO, -0.53f, -0.95f, -0.95f, -1.96f, -1.54f, -2.88f, LINE_TO, 8.42f, 3.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon b/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon index 2626248..319b8bee 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon
@@ -38,5 +38,4 @@ R_CUBIC_TO, -0.43f, -1.23f, -0.99f, -2.4f, -1.62f, -3.54f, R_CUBIC_TO, -1.05f, -1.91f, -1.89f, -3.93f, -3.07f, -5.77f, R_CUBIC_TO, -0.22f, -0.01f, -0.45f, -0.02f, -0.69f, -0.03f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_contrast.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_contrast.1x.icon index e607728..974f9352 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_contrast.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_contrast.1x.icon
@@ -13,5 +13,4 @@ R_CUBIC_TO, 3.38f, 0, 6.12f, 2.74f, 6.12f, 6.12f, R_CUBIC_TO, 0, 3.38f, -2.74f, 6.12f, -6.12f, 6.12f, V_LINE_TO, 3.88f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_contrast.icon b/ash/resources/vector_icons/system_menu_accessibility_contrast.icon index 94bdd469f..c5f5813 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_contrast.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_contrast.icon
@@ -13,5 +13,4 @@ R_CUBIC_TO, 6.76f, 0, 12.24f, 5.48f, 12.24f, 12.24f, CUBIC_TO_SHORTHAND, 26.76f, 32.24f, 20, 32.24f, V_LINE_TO, 7.77f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.1x.icon index 07b01daf..cb822666 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.1x.icon
@@ -32,5 +32,4 @@ LINE_TO, 16, 8, LINE_TO, 16, 9, LINE_TO, 14, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.icon b/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.icon index d2bc59b..b0f1f77 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_docked_magnifier.icon
@@ -32,5 +32,4 @@ LINE_TO, 33, 14, LINE_TO, 33, 16, LINE_TO, 30, 16, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.1x.icon index 2f9bbc0..e266dbdd 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.1x.icon
@@ -32,5 +32,4 @@ LINE_TO, 16, 8, LINE_TO, 16, 9, LINE_TO, 14, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.icon b/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.icon index a1a64d0..5bd7acb 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_fullscreen_magnifier.icon
@@ -32,5 +32,4 @@ LINE_TO, 33, 14, LINE_TO, 33, 16, LINE_TO, 30, 16, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.1x.icon index d3c43ef..12336cc 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.1x.icon
@@ -47,5 +47,4 @@ LINE_TO, 10.89f, 14, CUBIC_TO, 12.67f, 13.58f, 14, 11.95f, 14, 10, CUBIC_TO, 14, 8.05f, 12.67f, 6.42f, 10.89f, 6, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.icon b/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.icon index 756a7da..bdbc301c 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_select_to_speak.icon
@@ -47,5 +47,4 @@ LINE_TO, 21.78f, 28, CUBIC_TO, 25.34f, 27.17f, 28, 23.9f, 28, 20, CUBIC_TO, 28, 16.1f, 25.34f, 12.83f, 21.78f, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_add_connection.1x.icon b/ash/resources/vector_icons/system_menu_add_connection.1x.icon index 5d11a0a..534bcfbd 100644 --- a/ash/resources/vector_icons/system_menu_add_connection.1x.icon +++ b/ash/resources/vector_icons/system_menu_add_connection.1x.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, 4, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_add_connection.icon b/ash/resources/vector_icons/system_menu_add_connection.icon index c2b7fe4a..33d74ed 100644 --- a/ash/resources/vector_icons/system_menu_add_connection.icon +++ b/ash/resources/vector_icons/system_menu_add_connection.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 4, R_H_LINE_TO, 7, R_V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_arrow_back.1x.icon b/ash/resources/vector_icons/system_menu_arrow_back.1x.icon index 7ac36be4..d45b7e6 100644 --- a/ash/resources/vector_icons/system_menu_arrow_back.1x.icon +++ b/ash/resources/vector_icons/system_menu_arrow_back.1x.icon
@@ -12,5 +12,4 @@ R_LINE_TO, -4, -4, R_H_LINE_TO, 9, V_LINE_TO, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_arrow_back.icon b/ash/resources/vector_icons/system_menu_arrow_back.icon index f4ce8649..128b826 100644 --- a/ash/resources/vector_icons/system_menu_arrow_back.icon +++ b/ash/resources/vector_icons/system_menu_arrow_back.icon
@@ -12,5 +12,4 @@ R_LINE_TO, -9.3f, -9.21f, H_LINE_TO, 33, R_V_LINE_TO, -3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_arrow_right.1x.icon b/ash/resources/vector_icons/system_menu_arrow_right.1x.icon index 30ee32c..21b5b76 100644 --- a/ash/resources/vector_icons/system_menu_arrow_right.1x.icon +++ b/ash/resources/vector_icons/system_menu_arrow_right.1x.icon
@@ -6,5 +6,4 @@ MOVE_TO, 8, 14, R_LINE_TO, 4, -4, R_LINE_TO, -4, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_arrow_right.icon b/ash/resources/vector_icons/system_menu_arrow_right.icon index 2dc5eac..5ea2cb4 100644 --- a/ash/resources/vector_icons/system_menu_arrow_right.icon +++ b/ash/resources/vector_icons/system_menu_arrow_right.icon
@@ -6,5 +6,4 @@ MOVE_TO, 16, 28, R_LINE_TO, 8, -8, R_LINE_TO, -8, -8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_audio_input.1x.icon b/ash/resources/vector_icons/system_menu_audio_input.1x.icon index 291b6547..384d224 100644 --- a/ash/resources/vector_icons/system_menu_audio_input.1x.icon +++ b/ash/resources/vector_icons/system_menu_audio_input.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 5.86f, 2, 2.5f, 5.31f, 2.5f, 9.39f, R_CUBIC_TO, 0, 2.25f, 1.02f, 4.25f, 2.64f, 5.61f, R_LINE_TO, 1.18f, -1.17f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_audio_input.icon b/ash/resources/vector_icons/system_menu_audio_input.icon index 3328457a..1cfda15c 100644 --- a/ash/resources/vector_icons/system_menu_audio_input.icon +++ b/ash/resources/vector_icons/system_menu_audio_input.icon
@@ -23,5 +23,4 @@ R_CUBIC_TO, 0, -8.28f, -6.72f, -15, -15, -15, CUBIC_TO, 11.72f, 3, 5, 9.72f, 5, 18, R_CUBIC_TO, 0, 4.57f, 2.05f, 8.63f, 5.28f, 11.38f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_audio_output.1x.icon b/ash/resources/vector_icons/system_menu_audio_output.1x.icon index 0a25ef73..2d0b8066 100644 --- a/ash/resources/vector_icons/system_menu_audio_output.1x.icon +++ b/ash/resources/vector_icons/system_menu_audio_output.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 5.86f, 2, 2.5f, 5.31f, 2.5f, 9.39f, R_CUBIC_TO, 0, 2.25f, 1.02f, 4.25f, 2.64f, 5.61f, R_LINE_TO, 1.18f, -1.17f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_audio_output.icon b/ash/resources/vector_icons/system_menu_audio_output.icon index 6689be5..10e8663 100644 --- a/ash/resources/vector_icons/system_menu_audio_output.icon +++ b/ash/resources/vector_icons/system_menu_audio_output.icon
@@ -23,5 +23,4 @@ R_CUBIC_TO, 0, -8.28f, -6.72f, -15, -15, -15, CUBIC_TO, 11.72f, 3, 5, 9.72f, 5, 18, R_CUBIC_TO, 0, 4.57f, 2.05f, 8.63f, 5.28f, 11.38f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth.1x.icon b/ash/resources/vector_icons/system_menu_bluetooth.1x.icon index 12eb297..5b61141b 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth.1x.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth.1x.icon
@@ -28,5 +28,4 @@ R_V_LINE_TO, -3.13f, R_LINE_TO, 1.59f, 1.57f, R_LINE_TO, -1.59f, 1.57f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth.icon b/ash/resources/vector_icons/system_menu_bluetooth.icon index 613ea32e..fa4daafe 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth.icon
@@ -28,5 +28,4 @@ R_V_LINE_TO, -6.27f, R_LINE_TO, 3.18f, 3.13f, R_LINE_TO, -3.18f, 3.13f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth_connected.1x.icon b/ash/resources/vector_icons/system_menu_bluetooth_connected.1x.icon index 81682cc..8fa4f96 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth_connected.1x.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth_connected.1x.icon
@@ -40,5 +40,4 @@ R_V_LINE_TO, -3.13f, R_LINE_TO, 1.59f, 1.57f, R_LINE_TO, -1.59f, 1.57f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth_connected.icon b/ash/resources/vector_icons/system_menu_bluetooth_connected.icon index 5287568..94b7c40 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth_connected.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth_connected.icon
@@ -40,5 +40,4 @@ R_LINE_TO, 3, 3, R_LINE_TO, -3, 3, R_LINE_TO, -3, -3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth_disabled.1x.icon b/ash/resources/vector_icons/system_menu_bluetooth_disabled.1x.icon index 1ccee625..b166bd1b 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth_disabled.1x.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth_disabled.1x.icon
@@ -31,5 +31,4 @@ R_LINE_TO, 1.53f, 1.57f, R_LINE_TO, -1.53f, 1.57f, R_V_LINE_TO, -3.13f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_bluetooth_disabled.icon b/ash/resources/vector_icons/system_menu_bluetooth_disabled.icon index c2c0029..d8f054a 100644 --- a/ash/resources/vector_icons/system_menu_bluetooth_disabled.icon +++ b/ash/resources/vector_icons/system_menu_bluetooth_disabled.icon
@@ -31,5 +31,4 @@ R_LINE_TO, 3.06f, 3.13f, R_LINE_TO, -3.05f, 3.13f, R_V_LINE_TO, -6.27f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_brightness.1x.icon b/ash/resources/vector_icons/system_menu_brightness.1x.icon index 1228566..58eac7f 100644 --- a/ash/resources/vector_icons/system_menu_brightness.1x.icon +++ b/ash/resources/vector_icons/system_menu_brightness.1x.icon
@@ -30,5 +30,4 @@ R_MOVE_TO, 0, -1, R_ARC_TO, 3, 3, 0, 1, 0, 0, -6, R_ARC_TO, 3, 3, 0, 0, 0, 0, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_brightness.icon b/ash/resources/vector_icons/system_menu_brightness.icon index fdb50dc..daa5d6e 100644 --- a/ash/resources/vector_icons/system_menu_brightness.icon +++ b/ash/resources/vector_icons/system_menu_brightness.icon
@@ -30,5 +30,4 @@ R_MOVE_TO, 0, -2, R_ARC_TO, 6, 6, 0, 1, 0, 0, -12, R_ARC_TO, 6, 6, 0, 0, 0, 0, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_business.1x.icon b/ash/resources/vector_icons/system_menu_business.1x.icon index 5afdf44..8044ff29 100644 --- a/ash/resources/vector_icons/system_menu_business.1x.icon +++ b/ash/resources/vector_icons/system_menu_business.1x.icon
@@ -58,5 +58,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 4, V_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_business.icon b/ash/resources/vector_icons/system_menu_business.icon index 79ee98b..433fba4 100644 --- a/ash/resources/vector_icons/system_menu_business.icon +++ b/ash/resources/vector_icons/system_menu_business.icon
@@ -84,5 +84,4 @@ R_V_LINE_TO, 3, R_H_LINE_TO, 3, R_V_LINE_TO, -3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_caps_lock.1x.icon b/ash/resources/vector_icons/system_menu_caps_lock.1x.icon index 0ca0484..e090c70 100644 --- a/ash/resources/vector_icons/system_menu_caps_lock.1x.icon +++ b/ash/resources/vector_icons/system_menu_caps_lock.1x.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, -2, H_LINE_TO, 5, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_caps_lock.icon b/ash/resources/vector_icons/system_menu_caps_lock.icon index e6856480..725eb542 100644 --- a/ash/resources/vector_icons/system_menu_caps_lock.icon +++ b/ash/resources/vector_icons/system_menu_caps_lock.icon
@@ -26,5 +26,4 @@ R_V_LINE_TO, -3, H_LINE_TO, 10, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast.1x.icon b/ash/resources/vector_icons/system_menu_cast.1x.icon index 3b87f097..35401944 100644 --- a/ash/resources/vector_icons/system_menu_cast.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast.1x.icon
@@ -34,5 +34,4 @@ V_LINE_TO, 5.44f, CUBIC_TO, 18, 4.65f, 17.35f, 4, 16.55f, 4, H_LINE_TO, 3.46f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast.icon b/ash/resources/vector_icons/system_menu_cast.icon index 8276ab9..f9aa938 100644 --- a/ash/resources/vector_icons/system_menu_cast.icon +++ b/ash/resources/vector_icons/system_menu_cast.icon
@@ -34,5 +34,4 @@ V_LINE_TO, 10.89f, CUBIC_TO, 36, 9.3f, 34.69f, 8, 33.09f, 8, H_LINE_TO, 6.91f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_audio.1x.icon b/ash/resources/vector_icons/system_menu_cast_audio.1x.icon index 1ad9839..e02895b 100644 --- a/ash/resources/vector_icons/system_menu_cast_audio.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_audio.1x.icon
@@ -30,5 +30,4 @@ R_CUBIC_TO, 0, 1.11f, 0.89f, 2, 2, 2, R_CUBIC_TO, 1.11f, 0, 2, -0.89f, 2, -2, R_CUBIC_TO, 0, -1.11f, -0.89f, -2, -2, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_audio.icon b/ash/resources/vector_icons/system_menu_cast_audio.icon index 86804198..b1f7e4e 100644 --- a/ash/resources/vector_icons/system_menu_cast_audio.icon +++ b/ash/resources/vector_icons/system_menu_cast_audio.icon
@@ -30,5 +30,4 @@ R_CUBIC_TO, 0, 2.77f, 2.23f, 5, 5, 5, R_CUBIC_TO, 2.77f, 0, 5, -2.23f, 5, -5, R_CUBIC_TO, 0, -2.77f, -2.23f, -5, -5, -5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_audio_group.1x.icon b/ash/resources/vector_icons/system_menu_cast_audio_group.1x.icon index 5733fe29..7a67c1a 100644 --- a/ash/resources/vector_icons/system_menu_cast_audio_group.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_audio_group.1x.icon
@@ -34,5 +34,4 @@ R_V_LINE_TO, -2, H_LINE_TO, 5, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_audio_group.icon b/ash/resources/vector_icons/system_menu_cast_audio_group.icon index 702e44e..510789a 100644 --- a/ash/resources/vector_icons/system_menu_cast_audio_group.icon +++ b/ash/resources/vector_icons/system_menu_cast_audio_group.icon
@@ -34,5 +34,4 @@ R_V_LINE_TO, -4, H_LINE_TO, 10, V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_device.1x.icon b/ash/resources/vector_icons/system_menu_cast_device.1x.icon index ef8c28dd..82e40fe 100644 --- a/ash/resources/vector_icons/system_menu_cast_device.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_device.1x.icon
@@ -39,5 +39,4 @@ R_H_LINE_TO, 3.83f, R_CUBIC_TO, 0.3f, 0.74f, 0.47f, 1.55f, 0.47f, 2.4f, R_CUBIC_TO, 0, 3.54f, -2.86f, 6.4f, -6.4f, 6.4f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_device.icon b/ash/resources/vector_icons/system_menu_cast_device.icon index 9605bab..9c633d8 100644 --- a/ash/resources/vector_icons/system_menu_cast_device.icon +++ b/ash/resources/vector_icons/system_menu_cast_device.icon
@@ -39,5 +39,4 @@ R_H_LINE_TO, 7.66f, R_CUBIC_TO, 0.61f, 1.49f, 0.94f, 3.1f, 0.94f, 4.8f, R_CUBIC_TO, 0, 7.07f, -5.73f, 12.8f, -12.8f, 12.8f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_education.1x.icon b/ash/resources/vector_icons/system_menu_cast_education.1x.icon index a39e7a4..34da227a 100644 --- a/ash/resources/vector_icons/system_menu_cast_education.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_education.1x.icon
@@ -48,5 +48,4 @@ R_LINE_TO, 4.5f, 2.33f, R_LINE_TO, 4.5f, -2.33f, R_LINE_TO, -4.5f, -2.33f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_education.icon b/ash/resources/vector_icons/system_menu_cast_education.icon index c1eca4e..e4fde4e 100644 --- a/ash/resources/vector_icons/system_menu_cast_education.icon +++ b/ash/resources/vector_icons/system_menu_cast_education.icon
@@ -48,5 +48,4 @@ R_LINE_TO, 9, 4.67f, R_LINE_TO, 9, -4.67f, R_LINE_TO, -9, -4.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_enabled.1x.icon b/ash/resources/vector_icons/system_menu_cast_enabled.1x.icon index e64c418..cdefe94 100644 --- a/ash/resources/vector_icons/system_menu_cast_enabled.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_enabled.1x.icon
@@ -41,5 +41,4 @@ H_LINE_TO, 15, V_LINE_TO, 7, H_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_enabled.icon b/ash/resources/vector_icons/system_menu_cast_enabled.icon index a1dfd2e..6efd4ab 100644 --- a/ash/resources/vector_icons/system_menu_cast_enabled.icon +++ b/ash/resources/vector_icons/system_menu_cast_enabled.icon
@@ -41,5 +41,4 @@ H_LINE_TO, 30, V_LINE_TO, 14, H_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_generic.1x.icon b/ash/resources/vector_icons/system_menu_cast_generic.1x.icon index b57b0da..96b67ab0 100644 --- a/ash/resources/vector_icons/system_menu_cast_generic.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_generic.1x.icon
@@ -22,5 +22,4 @@ V_LINE_TO, 4.56f, R_H_LINE_TO, 15, V_LINE_TO, 13.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_generic.icon b/ash/resources/vector_icons/system_menu_cast_generic.icon index dc4cd94c..5c8a6703 100644 --- a/ash/resources/vector_icons/system_menu_cast_generic.icon +++ b/ash/resources/vector_icons/system_menu_cast_generic.icon
@@ -22,5 +22,4 @@ V_LINE_TO, 9, R_H_LINE_TO, 30, R_V_LINE_TO, 18, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_hangout.1x.icon b/ash/resources/vector_icons/system_menu_cast_hangout.1x.icon index f1ad1e1..df91815 100644 --- a/ash/resources/vector_icons/system_menu_cast_hangout.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_hangout.1x.icon
@@ -28,5 +28,4 @@ R_V_LINE_TO, -2.34f, R_H_LINE_TO, 2.47f, R_V_LINE_TO, 2.34f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_hangout.icon b/ash/resources/vector_icons/system_menu_cast_hangout.icon index 86d532e..3edba278 100644 --- a/ash/resources/vector_icons/system_menu_cast_hangout.icon +++ b/ash/resources/vector_icons/system_menu_cast_hangout.icon
@@ -28,5 +28,4 @@ R_V_LINE_TO, -5, R_H_LINE_TO, 5, R_V_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_meeting.1x.icon b/ash/resources/vector_icons/system_menu_cast_meeting.1x.icon index 41fdfe3..9ed8a77 100644 --- a/ash/resources/vector_icons/system_menu_cast_meeting.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_meeting.1x.icon
@@ -19,5 +19,4 @@ R_V_LINE_TO, 1.5f, LINE_TO, 14, 7, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_meeting.icon b/ash/resources/vector_icons/system_menu_cast_meeting.icon index 980875e..5b185bf 100644 --- a/ash/resources/vector_icons/system_menu_cast_meeting.icon +++ b/ash/resources/vector_icons/system_menu_cast_meeting.icon
@@ -19,5 +19,4 @@ R_V_LINE_TO, 3, R_LINE_TO, 5, -3, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_message.1x.icon b/ash/resources/vector_icons/system_menu_cast_message.1x.icon index f2fd0cf7..f13d2fd 100644 --- a/ash/resources/vector_icons/system_menu_cast_message.1x.icon +++ b/ash/resources/vector_icons/system_menu_cast_message.1x.icon
@@ -30,5 +30,4 @@ V_LINE_TO, 5, R_H_LINE_TO, 10, R_V_LINE_TO, 1.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_cast_message.icon b/ash/resources/vector_icons/system_menu_cast_message.icon index 3547d3a6..71c2779f 100644 --- a/ash/resources/vector_icons/system_menu_cast_message.icon +++ b/ash/resources/vector_icons/system_menu_cast_message.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -3, R_H_LINE_TO, 20, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_child_user.1x.icon b/ash/resources/vector_icons/system_menu_child_user.1x.icon index 45746de..54b7a08 100644 --- a/ash/resources/vector_icons/system_menu_child_user.1x.icon +++ b/ash/resources/vector_icons/system_menu_child_user.1x.icon
@@ -21,5 +21,4 @@ R_LINE_TO, 1.27f, -1.94f, LINE_TO, 16, 8, LINE_TO, 10.32f, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_child_user.icon b/ash/resources/vector_icons/system_menu_child_user.icon index e3dacc5c..5c566026 100644 --- a/ash/resources/vector_icons/system_menu_child_user.icon +++ b/ash/resources/vector_icons/system_menu_child_user.icon
@@ -21,5 +21,4 @@ R_LINE_TO, 2.55f, -3.89f, LINE_TO, 32, 16, LINE_TO, 20.64f, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_computer.1x.icon b/ash/resources/vector_icons/system_menu_computer.1x.icon index e20aa42e..2cdfb48 100644 --- a/ash/resources/vector_icons/system_menu_computer.1x.icon +++ b/ash/resources/vector_icons/system_menu_computer.1x.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 6, H_LINE_TO, 5, V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_computer.icon b/ash/resources/vector_icons/system_menu_computer.icon index dbaeeab1..607d8be 100644 --- a/ash/resources/vector_icons/system_menu_computer.icon +++ b/ash/resources/vector_icons/system_menu_computer.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 15, H_LINE_TO, 8, V_LINE_TO, 11, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_gamepad.1x.icon b/ash/resources/vector_icons/system_menu_gamepad.1x.icon index 117beaa9..d19e9f6d 100644 --- a/ash/resources/vector_icons/system_menu_gamepad.1x.icon +++ b/ash/resources/vector_icons/system_menu_gamepad.1x.icon
@@ -30,5 +30,4 @@ R_H_LINE_TO, 4, V_LINE_TO, 7, R_H_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_gamepad.icon b/ash/resources/vector_icons/system_menu_gamepad.icon index 76c89f2..4841b639 100644 --- a/ash/resources/vector_icons/system_menu_gamepad.icon +++ b/ash/resources/vector_icons/system_menu_gamepad.icon
@@ -30,5 +30,4 @@ H_LINE_TO, 36, V_LINE_TO, 15, R_H_LINE_TO, -9.06f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_guest.1x.icon b/ash/resources/vector_icons/system_menu_guest.1x.icon index 1756b74..a713ed7 100644 --- a/ash/resources/vector_icons/system_menu_guest.1x.icon +++ b/ash/resources/vector_icons/system_menu_guest.1x.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0.03f, -1.67f, 3.33f, -2.58f, 5, -2.58f, R_CUBIC_TO, 1.66f, 0, 4.97f, 0.91f, 5, 2.58f, R_CUBIC_TO, -1.07f, 1.63f, -2.92f, 2.7f, -5, 2.7f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_guest.icon b/ash/resources/vector_icons/system_menu_guest.icon index a4293bb..21c18cf 100644 --- a/ash/resources/vector_icons/system_menu_guest.icon +++ b/ash/resources/vector_icons/system_menu_guest.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 3.32f, 0, 9.95f, 1.9f, 10, 5.38f, CUBIC_TO, 27.85f, 29.77f, 24.17f, 32, 20, 32, R_CUBIC_TO, -4.17f, 0, -7.85f, -2.23f, -10, -5.62f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_hdmi.1x.icon b/ash/resources/vector_icons/system_menu_hdmi.1x.icon index a70e5ef6..3e56ac0e 100644 --- a/ash/resources/vector_icons/system_menu_hdmi.1x.icon +++ b/ash/resources/vector_icons/system_menu_hdmi.1x.icon
@@ -32,5 +32,4 @@ H_LINE_TO, 7, V_LINE_TO, 4, R_H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_hdmi.icon b/ash/resources/vector_icons/system_menu_hdmi.icon index c9e2183..69c33cdff 100644 --- a/ash/resources/vector_icons/system_menu_hdmi.icon +++ b/ash/resources/vector_icons/system_menu_hdmi.icon
@@ -32,5 +32,4 @@ V_LINE_TO, 12, H_LINE_TO, 13, V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_headset.1x.icon b/ash/resources/vector_icons/system_menu_headset.1x.icon index c01f734b..fd67785c 100644 --- a/ash/resources/vector_icons/system_menu_headset.1x.icon +++ b/ash/resources/vector_icons/system_menu_headset.1x.icon
@@ -20,5 +20,4 @@ V_LINE_TO, 9.58f, CUBIC_TO, 18, 5.39f, 14.14f, 2, 10, 2, CUBIC_TO, 5.86f, 2, 2, 5.39f, 2, 9.58f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_headset.icon b/ash/resources/vector_icons/system_menu_headset.icon index 67cc0dc..64eeccd 100644 --- a/ash/resources/vector_icons/system_menu_headset.icon +++ b/ash/resources/vector_icons/system_menu_headset.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, -11.79f, CUBIC_TO, 35, 10.79f, 28.28f, 4, 20, 4, CUBIC_TO, 11.72f, 4, 5, 10.79f, 5, 19.16f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_help.1x.icon b/ash/resources/vector_icons/system_menu_help.1x.icon index eeeedf8..c9a6a25 100644 --- a/ash/resources/vector_icons/system_menu_help.1x.icon +++ b/ash/resources/vector_icons/system_menu_help.1x.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 0, -1.77f, 1.43f, -3.2f, 3.2f, -3.2f, R_CUBIC_TO, 1.77f, 0, 3.2f, 1.43f, 3.2f, 3.2f, R_CUBIC_TO, 0, 0.7f, -0.29f, 1.34f, -0.74f, 1.8f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_help.icon b/ash/resources/vector_icons/system_menu_help.icon index 9205b83d..83d28d6 100644 --- a/ash/resources/vector_icons/system_menu_help.icon +++ b/ash/resources/vector_icons/system_menu_help.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 0, -3.54f, 2.86f, -6.4f, 6.4f, -6.4f, R_CUBIC_TO, 3.54f, 0, 6.4f, 2.86f, 6.4f, 6.4f, R_CUBIC_TO, 0, 1.41f, -0.58f, 2.69f, -1.49f, 3.6f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_info.1x.icon b/ash/resources/vector_icons/system_menu_info.1x.icon index 5fb614f..98303d3 100644 --- a/ash/resources/vector_icons/system_menu_info.1x.icon +++ b/ash/resources/vector_icons/system_menu_info.1x.icon
@@ -20,5 +20,4 @@ V_LINE_TO, 6, R_H_LINE_TO, 2, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_info.icon b/ash/resources/vector_icons/system_menu_info.icon index 39db157..fe44ba7 100644 --- a/ash/resources/vector_icons/system_menu_info.icon +++ b/ash/resources/vector_icons/system_menu_info.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, -3, R_H_LINE_TO, 3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_keyboard.1x.icon b/ash/resources/vector_icons/system_menu_keyboard.1x.icon index 234ce33c..a489093 100644 --- a/ash/resources/vector_icons/system_menu_keyboard.1x.icon +++ b/ash/resources/vector_icons/system_menu_keyboard.1x.icon
@@ -78,5 +78,4 @@ V_LINE_TO, 8, R_H_LINE_TO, 1, R_V_LINE_TO, 1, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_keyboard.icon b/ash/resources/vector_icons/system_menu_keyboard.icon index 34bc444..2be7249 100644 --- a/ash/resources/vector_icons/system_menu_keyboard.icon +++ b/ash/resources/vector_icons/system_menu_keyboard.icon
@@ -78,5 +78,4 @@ R_V_LINE_TO, -3, R_H_LINE_TO, 3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_keyboard_brightness.1x.icon b/ash/resources/vector_icons/system_menu_keyboard_brightness.1x.icon index 1b97e21..5c9028e 100644 --- a/ash/resources/vector_icons/system_menu_keyboard_brightness.1x.icon +++ b/ash/resources/vector_icons/system_menu_keyboard_brightness.1x.icon
@@ -56,5 +56,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2.45f, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_keyboard_brightness.icon b/ash/resources/vector_icons/system_menu_keyboard_brightness.icon index 2316beb..23ba163b 100644 --- a/ash/resources/vector_icons/system_menu_keyboard_brightness.icon +++ b/ash/resources/vector_icons/system_menu_keyboard_brightness.icon
@@ -56,5 +56,4 @@ V_LINE_TO, 27, R_H_LINE_TO, -4.64f, R_V_LINE_TO, -3.01f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_lock.1x.icon b/ash/resources/vector_icons/system_menu_lock.1x.icon index c24e335..9bb0992 100644 --- a/ash/resources/vector_icons/system_menu_lock.1x.icon +++ b/ash/resources/vector_icons/system_menu_lock.1x.icon
@@ -28,5 +28,4 @@ R_CUBIC_TO, 1.1f, 0, 2.5f, 0.49f, 2.5f, 2, V_LINE_TO, 8, R_H_LINE_TO, -5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_lock.icon b/ash/resources/vector_icons/system_menu_lock.icon index ab77272..a6e6d8fb 100644 --- a/ash/resources/vector_icons/system_menu_lock.icon +++ b/ash/resources/vector_icons/system_menu_lock.icon
@@ -30,5 +30,4 @@ R_CUBIC_TO, 3.31f, 0, 6, 2.45f, 6, 5.47f, V_LINE_TO, 15, H_LINE_TO, 14, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_mouse.1x.icon b/ash/resources/vector_icons/system_menu_mouse.1x.icon index 252dd06..675be538 100644 --- a/ash/resources/vector_icons/system_menu_mouse.1x.icon +++ b/ash/resources/vector_icons/system_menu_mouse.1x.icon
@@ -19,5 +19,4 @@ CUBIC_TO, 6.2f, 3.31f, 4, 5.43f, 4, 8, R_H_LINE_TO, 5.04f, V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_mouse.icon b/ash/resources/vector_icons/system_menu_mouse.icon index 1dfe048a..7e427f9 100644 --- a/ash/resources/vector_icons/system_menu_mouse.icon +++ b/ash/resources/vector_icons/system_menu_mouse.icon
@@ -19,5 +19,4 @@ R_CUBIC_TO, -6.21f, 0.74f, -11, 5.83f, -11, 12, R_H_LINE_TO, 11, V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_new_user.1x.icon b/ash/resources/vector_icons/system_menu_new_user.1x.icon index 6855519..8c7a0e13 100644 --- a/ash/resources/vector_icons/system_menu_new_user.1x.icon +++ b/ash/resources/vector_icons/system_menu_new_user.1x.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 0.62f, 0, 1.22f, -0.07f, 1.8f, -0.21f, R_CUBIC_TO, 0.17f, 0.57f, 0.26f, 1.18f, 0.26f, 1.81f, R_CUBIC_TO, 0, 3.53f, -2.87f, 6.4f, -6.4f, 6.4f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_new_user.icon b/ash/resources/vector_icons/system_menu_new_user.icon index d5ebc5b..68e24b77 100644 --- a/ash/resources/vector_icons/system_menu_new_user.icon +++ b/ash/resources/vector_icons/system_menu_new_user.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 1.25f, 0, 2.45f, -0.14f, 3.6f, -0.42f, R_CUBIC_TO, 0.34f, 1.14f, 0.53f, 2.35f, 0.53f, 3.62f, R_CUBIC_TO, 0, 7.06f, -5.74f, 12.8f, -12.8f, 12.8f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_night_light_off.1x.icon b/ash/resources/vector_icons/system_menu_night_light_off.1x.icon index e7f4aa3..3c71773 100644 --- a/ash/resources/vector_icons/system_menu_night_light_off.1x.icon +++ b/ash/resources/vector_icons/system_menu_night_light_off.1x.icon
@@ -30,5 +30,4 @@ R_LINE_TO, 14.31f, 14.31f, R_LINE_TO, -1.06f, 1.06f, LINE_TO, 2.5f, 3.06f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_night_light_off.icon b/ash/resources/vector_icons/system_menu_night_light_off.icon index 1e7bc9f..660bb50 100644 --- a/ash/resources/vector_icons/system_menu_night_light_off.icon +++ b/ash/resources/vector_icons/system_menu_night_light_off.icon
@@ -30,5 +30,4 @@ R_LINE_TO, 28.63f, 28.63f, R_LINE_TO, -2.12f, 2.12f, LINE_TO, 5, 6.12f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_night_light_on.1x.icon b/ash/resources/vector_icons/system_menu_night_light_on.1x.icon index 64623ec..34b4c54 100644 --- a/ash/resources/vector_icons/system_menu_night_light_on.1x.icon +++ b/ash/resources/vector_icons/system_menu_night_light_on.1x.icon
@@ -16,5 +16,4 @@ CUBIC_TO, 8.85f, 14.93f, 7.29f, 12.67f, 7.29f, 10, R_CUBIC_TO, 0, -2.67f, 1.56f, -4.93f, 3.71f, -5.71f, CUBIC_TO, 10.48f, 4.1f, 9.93f, 4, 9.35f, 4, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_night_light_on.icon b/ash/resources/vector_icons/system_menu_night_light_on.icon index 513dce8..f1cd0aa 100644 --- a/ash/resources/vector_icons/system_menu_night_light_on.icon +++ b/ash/resources/vector_icons/system_menu_night_light_on.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 1.4f, 0, 2.74f, -0.22f, 4, -0.63f, R_CUBIC_TO, -5.22f, -1.69f, -9, -6.59f, -9, -12.37f, R_CUBIC_TO, 0, -5.78f, 3.78f, -10.69f, 9, -12.37f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_phone.1x.icon b/ash/resources/vector_icons/system_menu_phone.1x.icon index 17bc0ee..c837268 100644 --- a/ash/resources/vector_icons/system_menu_phone.1x.icon +++ b/ash/resources/vector_icons/system_menu_phone.1x.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 10, H_LINE_TO, 7, V_LINE_TO, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_phone.icon b/ash/resources/vector_icons/system_menu_phone.icon index 22d78fbb..2c0ec69d 100644 --- a/ash/resources/vector_icons/system_menu_phone.icon +++ b/ash/resources/vector_icons/system_menu_phone.icon
@@ -18,5 +18,4 @@ V_LINE_TO, 10, R_H_LINE_TO, 14, R_V_LINE_TO, 20, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_power.1x.icon b/ash/resources/vector_icons/system_menu_power.1x.icon index 82429a6..806d0f6 100644 --- a/ash/resources/vector_icons/system_menu_power.1x.icon +++ b/ash/resources/vector_icons/system_menu_power.1x.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 2, 14.44f, 5.58f, 18, 10, 18, R_CUBIC_TO, 4.42f, 0, 8, -3.56f, 8, -7.96f, R_CUBIC_TO, 0, -2.42f, -1.09f, -4.58f, -2.82f, -6.04f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_power.icon b/ash/resources/vector_icons/system_menu_power.icon index 0680184a..5cdb93d 100644 --- a/ash/resources/vector_icons/system_menu_power.icon +++ b/ash/resources/vector_icons/system_menu_power.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0, 8.28f, 6.72f, 15, 15, 15, R_CUBIC_TO, 8.28f, 0, 15, -6.72f, 15, -15, R_CUBIC_TO, 0, -4.57f, -2.05f, -8.63f, -5.28f, -11.38f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_auto.1x.icon b/ash/resources/vector_icons/system_menu_rotation_lock_auto.1x.icon index 6d8f8d2..6cfe68ab 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_auto.1x.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_auto.1x.icon
@@ -38,5 +38,4 @@ R_CUBIC_TO, 0.57f, 0.6f, 1.51f, 0.59f, 2.09f, -0.01f, R_LINE_TO, 5.23f, -5.45f, R_CUBIC_TO, 0.58f, -0.6f, 0.58f, -1.58f, 0, -2.18f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_auto.icon b/ash/resources/vector_icons/system_menu_rotation_lock_auto.icon index cf0f07e..a3ad737 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_auto.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_auto.icon
@@ -38,5 +38,4 @@ R_CUBIC_TO, 1.15f, 1.17f, 3.02f, 1.16f, 4.17f, -0.01f, R_LINE_TO, 10.46f, -10.6f, R_CUBIC_TO, 1.15f, -1.17f, 1.15f, -3.08f, 0, -4.24f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_landscape.1x.icon b/ash/resources/vector_icons/system_menu_rotation_lock_landscape.1x.icon index a229a01..1183c3c 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_landscape.1x.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_landscape.1x.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 8, H_LINE_TO, 5, V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_landscape.icon b/ash/resources/vector_icons/system_menu_rotation_lock_landscape.icon index d22e2fd..35363c3a 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_landscape.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_landscape.icon
@@ -18,5 +18,4 @@ V_LINE_TO, 11, R_H_LINE_TO, 20, R_V_LINE_TO, 18, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_portrait.1x.icon b/ash/resources/vector_icons/system_menu_rotation_lock_portrait.1x.icon index 29d46ab..60b6fa2 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_portrait.1x.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_portrait.1x.icon
@@ -18,5 +18,4 @@ R_H_LINE_TO, 8, V_LINE_TO, 4, H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_rotation_lock_portrait.icon b/ash/resources/vector_icons/system_menu_rotation_lock_portrait.icon index b301e12..12b4b2a 100644 --- a/ash/resources/vector_icons/system_menu_rotation_lock_portrait.icon +++ b/ash/resources/vector_icons/system_menu_rotation_lock_portrait.icon
@@ -18,5 +18,4 @@ R_H_LINE_TO, 16, V_LINE_TO, 8, H_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_screen_share.1x.icon b/ash/resources/vector_icons/system_menu_screen_share.1x.icon index faba58f..55e47c6 100644 --- a/ash/resources/vector_icons/system_menu_screen_share.1x.icon +++ b/ash/resources/vector_icons/system_menu_screen_share.1x.icon
@@ -26,5 +26,4 @@ R_LINE_TO, 3, 3.5f, R_LINE_TO, -3, 3.5f, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_screen_share.icon b/ash/resources/vector_icons/system_menu_screen_share.icon index 42355ab..e6d8797c 100644 --- a/ash/resources/vector_icons/system_menu_screen_share.icon +++ b/ash/resources/vector_icons/system_menu_screen_share.icon
@@ -26,5 +26,4 @@ R_LINE_TO, 6, 6, R_LINE_TO, -6, 6, R_V_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_settings.1x.icon b/ash/resources/vector_icons/system_menu_settings.1x.icon index c5785188..6707c8a6 100644 --- a/ash/resources/vector_icons/system_menu_settings.1x.icon +++ b/ash/resources/vector_icons/system_menu_settings.1x.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, 0, -1.65f, 1.35f, -3, 3, -3, R_CUBIC_TO, 1.65f, 0, 3, 1.35f, 3, 3, R_CUBIC_TO, 0, 1.65f, -1.35f, 3, -3, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_settings.icon b/ash/resources/vector_icons/system_menu_settings.icon index a38b947f..77dca19 100644 --- a/ash/resources/vector_icons/system_menu_settings.icon +++ b/ash/resources/vector_icons/system_menu_settings.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, 0, -3.21f, 2.69f, -5.82f, 5.98f, -5.82f, R_CUBIC_TO, 3.3f, 0, 5.98f, 2.61f, 5.98f, 5.82f, R_CUBIC_TO, 0, 3.21f, -2.68f, 5.82f, -5.98f, 5.82f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_supervised_user.1x.icon b/ash/resources/vector_icons/system_menu_supervised_user.1x.icon index aee7f15..426d646 100644 --- a/ash/resources/vector_icons/system_menu_supervised_user.1x.icon +++ b/ash/resources/vector_icons/system_menu_supervised_user.1x.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 0, -0.73f, 0, -2, 2, -2.9f, R_CUBIC_TO, -0.83f, -0.15f, -1.87f, 0, -2.5f, 0, R_CUBIC_TO, -2.24f, 0, -6.5f, 0.76f, -6.5f, 2.76f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_supervised_user.icon b/ash/resources/vector_icons/system_menu_supervised_user.icon index f93efb2..2c27f93b 100644 --- a/ash/resources/vector_icons/system_menu_supervised_user.icon +++ b/ash/resources/vector_icons/system_menu_supervised_user.icon
@@ -28,5 +28,4 @@ R_V_LINE_TO, -3.8f, R_CUBIC_TO, 0, -1.44f, 0.56f, -3.95f, 4.03f, -5.87f, R_CUBIC_TO, -1.48f, -0.3f, -2.91f, -0.47f, -4.03f, -0.47f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_tablet.1x.icon b/ash/resources/vector_icons/system_menu_tablet.1x.icon index e078da3..4fdcf72 100644 --- a/ash/resources/vector_icons/system_menu_tablet.1x.icon +++ b/ash/resources/vector_icons/system_menu_tablet.1x.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 8, H_LINE_TO, 5, V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_tablet.icon b/ash/resources/vector_icons/system_menu_tablet.icon index 595873d..49cb10e 100644 --- a/ash/resources/vector_icons/system_menu_tablet.icon +++ b/ash/resources/vector_icons/system_menu_tablet.icon
@@ -18,5 +18,4 @@ V_LINE_TO, 11, R_H_LINE_TO, 20, R_V_LINE_TO, 18, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_timer.1x.icon b/ash/resources/vector_icons/system_menu_timer.1x.icon index bfc0b90..7f9d8c6 100644 --- a/ash/resources/vector_icons/system_menu_timer.1x.icon +++ b/ash/resources/vector_icons/system_menu_timer.1x.icon
@@ -28,5 +28,4 @@ V_LINE_TO, 8, H_LINE_TO, 9, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_timer.icon b/ash/resources/vector_icons/system_menu_timer.icon index b3e4bb97..22f61938 100644 --- a/ash/resources/vector_icons/system_menu_timer.icon +++ b/ash/resources/vector_icons/system_menu_timer.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -8, R_H_LINE_TO, -3, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_tracing.1x.icon b/ash/resources/vector_icons/system_menu_tracing.1x.icon index ca67b2c..8e6bcf3 100644 --- a/ash/resources/vector_icons/system_menu_tracing.1x.icon +++ b/ash/resources/vector_icons/system_menu_tracing.1x.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -4, R_H_LINE_TO, 2, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_tracing.icon b/ash/resources/vector_icons/system_menu_tracing.icon index ecdbaa5..14f7eb40 100644 --- a/ash/resources/vector_icons/system_menu_tracing.icon +++ b/ash/resources/vector_icons/system_menu_tracing.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -7, R_H_LINE_TO, 3, R_V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_update.1x.icon b/ash/resources/vector_icons/system_menu_update.1x.icon index 8a65ffb..b13dfe1b 100644 --- a/ash/resources/vector_icons/system_menu_update.1x.icon +++ b/ash/resources/vector_icons/system_menu_update.1x.icon
@@ -17,5 +17,4 @@ R_LINE_TO, -5, 6, R_H_LINE_TO, 3, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_update.icon b/ash/resources/vector_icons/system_menu_update.icon index 1da0254..28a0cadc 100644 --- a/ash/resources/vector_icons/system_menu_update.icon +++ b/ash/resources/vector_icons/system_menu_update.icon
@@ -17,5 +17,4 @@ LINE_TO, 10, 23, R_H_LINE_TO, 6, R_V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_usb.1x.icon b/ash/resources/vector_icons/system_menu_usb.1x.icon index d7ceaa62d..e9f5b7e 100644 --- a/ash/resources/vector_icons/system_menu_usb.1x.icon +++ b/ash/resources/vector_icons/system_menu_usb.1x.icon
@@ -35,5 +35,4 @@ R_V_LINE_TO, -3.02f, R_H_LINE_TO, -2.96f, R_V_LINE_TO, 3.02f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_usb.icon b/ash/resources/vector_icons/system_menu_usb.icon index 2ca56a8..0d2713d 100644 --- a/ash/resources/vector_icons/system_menu_usb.icon +++ b/ash/resources/vector_icons/system_menu_usb.icon
@@ -35,5 +35,4 @@ R_V_LINE_TO, -6.04f, R_H_LINE_TO, -5.91f, R_V_LINE_TO, 6.04f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_videocam.1x.icon b/ash/resources/vector_icons/system_menu_videocam.1x.icon index e9e933d..6035f7d7 100644 --- a/ash/resources/vector_icons/system_menu_videocam.1x.icon +++ b/ash/resources/vector_icons/system_menu_videocam.1x.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 9, LINE_TO, 14, 12, V_LINE_TO, 8.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_videocam.icon b/ash/resources/vector_icons/system_menu_videocam.icon index dc3d2091..4c484c9 100644 --- a/ash/resources/vector_icons/system_menu_videocam.icon +++ b/ash/resources/vector_icons/system_menu_videocam.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 18, R_LINE_TO, -6, -5, R_V_LINE_TO, -7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_high.1x.icon b/ash/resources/vector_icons/system_menu_volume_high.1x.icon index 1144ee66..80835fc2 100644 --- a/ash/resources/vector_icons/system_menu_volume_high.1x.icon +++ b/ash/resources/vector_icons/system_menu_volume_high.1x.icon
@@ -23,5 +23,4 @@ R_CUBIC_TO, 3.44f, -0.78f, 6, -3.84f, 6, -7.5f, R_CUBIC_TO, 0, -3.66f, -2.56f, -6.72f, -6, -7.5f, R_V_LINE_TO, 1.76f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_high.icon b/ash/resources/vector_icons/system_menu_volume_high.icon index c4d53f0a4..ba69d04 100644 --- a/ash/resources/vector_icons/system_menu_volume_high.icon +++ b/ash/resources/vector_icons/system_menu_volume_high.icon
@@ -23,5 +23,4 @@ R_CUBIC_TO, 6.87f, -1.56f, 12, -7.68f, 12, -15, CUBIC_TO_SHORTHAND, 29.87f, 6.56f, 23, 5, R_V_LINE_TO, 3.52f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_low.1x.icon b/ash/resources/vector_icons/system_menu_volume_low.1x.icon index f886c6d..db8b384 100644 --- a/ash/resources/vector_icons/system_menu_volume_low.1x.icon +++ b/ash/resources/vector_icons/system_menu_volume_low.1x.icon
@@ -9,5 +9,4 @@ V_LINE_TO, 3, LINE_TO, 5.47f, 7, H_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_low.icon b/ash/resources/vector_icons/system_menu_volume_low.icon index f37f4d5..a8ea90d 100644 --- a/ash/resources/vector_icons/system_menu_volume_low.icon +++ b/ash/resources/vector_icons/system_menu_volume_low.icon
@@ -9,5 +9,4 @@ R_LINE_TO, 8.5f, 9, V_LINE_TO, 6, R_LINE_TO, -8.5f, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_medium.1x.icon b/ash/resources/vector_icons/system_menu_volume_medium.1x.icon index fead053..c3ecec8 100644 --- a/ash/resources/vector_icons/system_menu_volume_medium.1x.icon +++ b/ash/resources/vector_icons/system_menu_volume_medium.1x.icon
@@ -15,5 +15,4 @@ R_V_LINE_TO, 7, R_CUBIC_TO, 1.78f, -0.63f, 2.5f, -2.5f, 2.5f, -3.5f, R_CUBIC_TO, 0, -1, -0.72f, -2.86f, -2.5f, -3.5f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_medium.icon b/ash/resources/vector_icons/system_menu_volume_medium.icon index 47f4f965..ee3bc081 100644 --- a/ash/resources/vector_icons/system_menu_volume_medium.icon +++ b/ash/resources/vector_icons/system_menu_volume_medium.icon
@@ -15,5 +15,4 @@ R_LINE_TO, -8.45f, 9, H_LINE_TO, 5, R_V_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_mute.1x.icon b/ash/resources/vector_icons/system_menu_volume_mute.1x.icon index a3019c62..61ef7f6 100644 --- a/ash/resources/vector_icons/system_menu_volume_mute.1x.icon +++ b/ash/resources/vector_icons/system_menu_volume_mute.1x.icon
@@ -38,5 +38,4 @@ LINE_TO, 8.14f, 4.75f, LINE_TO, 10, 6.6f, V_LINE_TO, 2.89f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_menu_volume_mute.icon b/ash/resources/vector_icons/system_menu_volume_mute.icon index 7467f11..d06982d 100644 --- a/ash/resources/vector_icons/system_menu_volume_mute.icon +++ b/ash/resources/vector_icons/system_menu_volume_mute.icon
@@ -38,5 +38,4 @@ R_LINE_TO, -3.48f, 3.48f, LINE_TO, 20, 13.63f, V_LINE_TO, 6.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_power_button_menu_power_off.1x.icon b/ash/resources/vector_icons/system_power_button_menu_power_off.1x.icon index 7ec17a8a..c3e5729 100644 --- a/ash/resources/vector_icons/system_power_button_menu_power_off.1x.icon +++ b/ash/resources/vector_icons/system_power_button_menu_power_off.1x.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 3, 16.97f, 7.03f, 21, 12, 21, CUBIC_TO, 16.97f, 21, 21, 16.97f, 21, 12, CUBIC_TO, 21, 9.26f, 19.77f, 6.82f, 17.83f, 5.17f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_power_button_menu_power_off.icon b/ash/resources/vector_icons/system_power_button_menu_power_off.icon index 16dcf407..290036b 100644 --- a/ash/resources/vector_icons/system_power_button_menu_power_off.icon +++ b/ash/resources/vector_icons/system_power_button_menu_power_off.icon
@@ -19,5 +19,4 @@ CUBIC_TO, 6, 33.94f, 14.06f, 42, 24, 42, CUBIC_TO, 33.94f, 42, 42, 33.94f, 42, 24, CUBIC_TO, 42, 18.52f, 39.54f, 13.64f, 35.66f, 10.34f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_power_button_menu_sign_out.1x.icon b/ash/resources/vector_icons/system_power_button_menu_sign_out.1x.icon index 12b7a60..1ce82f4d 100644 --- a/ash/resources/vector_icons/system_power_button_menu_sign_out.1x.icon +++ b/ash/resources/vector_icons/system_power_button_menu_sign_out.1x.icon
@@ -31,5 +31,4 @@ CUBIC_TO, 20.1f, 21, 21, 20.1f, 21, 19, LINE_TO, 21, 5, CUBIC_TO, 21, 3.9f, 20.1f, 3, 19, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_power_button_menu_sign_out.icon b/ash/resources/vector_icons/system_power_button_menu_sign_out.icon index e369261..40486df 100644 --- a/ash/resources/vector_icons/system_power_button_menu_sign_out.icon +++ b/ash/resources/vector_icons/system_power_button_menu_sign_out.icon
@@ -30,5 +30,4 @@ CUBIC_TO, 40.2f, 42, 42, 40.2f, 42, 38, LINE_TO, 42, 10, CUBIC_TO, 42, 7.8f, 40.2f, 6, 38, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_accessibility.1x.icon b/ash/resources/vector_icons/system_tray_accessibility.1x.icon index 0187049..be68c83 100644 --- a/ash/resources/vector_icons/system_tray_accessibility.1x.icon +++ b/ash/resources/vector_icons/system_tray_accessibility.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 9.85f, 3.59f, 9.25f, 3, 8.52f, 3, R_CUBIC_TO, -0.73f, 0, -1.33f, 0.59f, -1.33f, 1.31f, R_CUBIC_TO, 0, 0.72f, 0.6f, 1.31f, 1.33f, 1.31f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_accessibility.icon b/ash/resources/vector_icons/system_tray_accessibility.icon index 8c3f1ce..f24ceb9 100644 --- a/ash/resources/vector_icons/system_tray_accessibility.icon +++ b/ash/resources/vector_icons/system_tray_accessibility.icon
@@ -21,5 +21,4 @@ R_MOVE_TO, 0, -1.94f, R_ARC_TO, 2.5f, 2.5f, 0, 1, 0, 0, -5, R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_alert.1x.icon b/ash/resources/vector_icons/system_tray_battery_alert.1x.icon index cc7d6a1..91e7fb3f 100644 --- a/ash/resources/vector_icons/system_tray_battery_alert.1x.icon +++ b/ash/resources/vector_icons/system_tray_battery_alert.1x.icon
@@ -14,5 +14,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 7, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_alert.icon b/ash/resources/vector_icons/system_tray_battery_alert.icon index 3da507dc..8670cb6f 100644 --- a/ash/resources/vector_icons/system_tray_battery_alert.icon +++ b/ash/resources/vector_icons/system_tray_battery_alert.icon
@@ -14,5 +14,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, -2, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_bolt.1x.icon b/ash/resources/vector_icons/system_tray_battery_bolt.1x.icon index 2e66eb2..87bdf57 100644 --- a/ash/resources/vector_icons/system_tray_battery_bolt.1x.icon +++ b/ash/resources/vector_icons/system_tray_battery_bolt.1x.icon
@@ -9,5 +9,4 @@ R_V_LINE_TO, 3.5f, H_LINE_TO, 10, LINE_TO, 7.52f, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_bolt.icon b/ash/resources/vector_icons/system_tray_battery_bolt.icon index 413dd9a..6f64a3c 100644 --- a/ash/resources/vector_icons/system_tray_battery_bolt.icon +++ b/ash/resources/vector_icons/system_tray_battery_bolt.icon
@@ -9,5 +9,4 @@ R_V_LINE_TO, 7, H_LINE_TO, 20, R_LINE_TO, -4.97f, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_unreliable.1x.icon b/ash/resources/vector_icons/system_tray_battery_unreliable.1x.icon index ce744ea6..e489428 100644 --- a/ash/resources/vector_icons/system_tray_battery_unreliable.1x.icon +++ b/ash/resources/vector_icons/system_tray_battery_unreliable.1x.icon
@@ -12,5 +12,4 @@ R_V_LINE_TO, 1.19f, R_CUBIC_TO, 0, 0, -0.19f, 0.63f, -1.22f, 0.63f, R_CUBIC_TO, -1.03f, 0, -1.53f, -1.25f, -2.53f, -1.23f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_unreliable.icon b/ash/resources/vector_icons/system_tray_battery_unreliable.icon index 371f6b2..4c8920d 100644 --- a/ash/resources/vector_icons/system_tray_battery_unreliable.icon +++ b/ash/resources/vector_icons/system_tray_battery_unreliable.icon
@@ -12,5 +12,4 @@ R_V_LINE_TO, 1.98f, R_CUBIC_TO, 0, 0, -0.38f, 1.05f, -2.44f, 1.05f, R_CUBIC_TO, -2.06f, 0, -3.07f, -2.08f, -5.06f, -2.05f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_x.1x.icon b/ash/resources/vector_icons/system_tray_battery_x.1x.icon index 294277a..81e484d 100644 --- a/ash/resources/vector_icons/system_tray_battery_x.1x.icon +++ b/ash/resources/vector_icons/system_tray_battery_x.1x.icon
@@ -16,5 +16,4 @@ LINE_TO, 9.33f, 11, R_LINE_TO, 0.67f, -0.67f, LINE_TO, 8.67f, 9, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_battery_x.icon b/ash/resources/vector_icons/system_tray_battery_x.icon index 2bf2cfe..9d8fd327e 100644 --- a/ash/resources/vector_icons/system_tray_battery_x.icon +++ b/ash/resources/vector_icons/system_tray_battery_x.icon
@@ -16,5 +16,4 @@ LINE_TO, 18.67f, 22, LINE_TO, 20, 20.67f, LINE_TO, 17.33f, 18, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_caps_lock.1x.icon b/ash/resources/vector_icons/system_tray_caps_lock.1x.icon index 07342fa..95a9126 100644 --- a/ash/resources/vector_icons/system_tray_caps_lock.1x.icon +++ b/ash/resources/vector_icons/system_tray_caps_lock.1x.icon
@@ -16,5 +16,4 @@ R_V_LINE_TO, -2, H_LINE_TO, 4, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_caps_lock.icon b/ash/resources/vector_icons/system_tray_caps_lock.icon index d8cd7bc..7a5c551 100644 --- a/ash/resources/vector_icons/system_tray_caps_lock.icon +++ b/ash/resources/vector_icons/system_tray_caps_lock.icon
@@ -16,5 +16,4 @@ R_V_LINE_TO, -3, H_LINE_TO, 8, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_cast.1x.icon b/ash/resources/vector_icons/system_tray_cast.1x.icon index 3d540eb..09d17d1 100644 --- a/ash/resources/vector_icons/system_tray_cast.1x.icon +++ b/ash/resources/vector_icons/system_tray_cast.1x.icon
@@ -41,5 +41,4 @@ R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1, V_LINE_TO, 5, R_CUBIC_TO, 0, -0.55f, -0.45f, -1, -1, -1, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_cast.icon b/ash/resources/vector_icons/system_tray_cast.icon index 7de458f..4ffc1401 100644 --- a/ash/resources/vector_icons/system_tray_cast.icon +++ b/ash/resources/vector_icons/system_tray_cast.icon
@@ -51,5 +51,4 @@ R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, V_LINE_TO, 9, R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_night_light.1x.icon b/ash/resources/vector_icons/system_tray_night_light.1x.icon index 17b0c5c..e05838fa 100644 --- a/ash/resources/vector_icons/system_tray_night_light.1x.icon +++ b/ash/resources/vector_icons/system_tray_night_light.1x.icon
@@ -17,5 +17,4 @@ CUBIC_TO, 6.54f, 11.93f, 4.76f, 9.67f, 4.76f, 7, CUBIC_TO, 4.76f, 4.33f, 6.54f, 2.07f, 9, 1.29f, LINE_TO, 9, 1.29f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_night_light.icon b/ash/resources/vector_icons/system_tray_night_light.icon index 8d49fe7..1ccd9c5 100644 --- a/ash/resources/vector_icons/system_tray_night_light.icon +++ b/ash/resources/vector_icons/system_tray_night_light.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 1.15f, 0, 2.26f, -0.19f, 3.29f, -0.53f, R_CUBIC_TO, -4.3f, -1.43f, -7.41f, -5.58f, -7.41f, -10.47f, R_CUBIC_TO, 0, -4.89f, 3.11f, -9.04f, 7.41f, -10.47f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_recording.1x.icon b/ash/resources/vector_icons/system_tray_recording.1x.icon index 67c6d7a5..1d33b65 100644 --- a/ash/resources/vector_icons/system_tray_recording.1x.icon +++ b/ash/resources/vector_icons/system_tray_recording.1x.icon
@@ -5,5 +5,4 @@ CANVAS_DIMENSIONS, 16, CIRCLE, 8, 8, 6, CIRCLE, 8, 8, 4.5f, -CIRCLE, 8, 8, 3, -END +CIRCLE, 8, 8, 3
diff --git a/ash/resources/vector_icons/system_tray_recording.icon b/ash/resources/vector_icons/system_tray_recording.icon index 4cc5b47c..bdc4091 100644 --- a/ash/resources/vector_icons/system_tray_recording.icon +++ b/ash/resources/vector_icons/system_tray_recording.icon
@@ -5,5 +5,4 @@ CANVAS_DIMENSIONS, 32, CIRCLE, 16, 16, 12, CIRCLE, 16, 16, 9, -CIRCLE, 16, 16, 7, -END +CIRCLE, 16, 16, 7
diff --git a/ash/resources/vector_icons/system_tray_rotation_lock_auto.1x.icon b/ash/resources/vector_icons/system_tray_rotation_lock_auto.1x.icon index 827ae49..a21753db 100644 --- a/ash/resources/vector_icons/system_tray_rotation_lock_auto.1x.icon +++ b/ash/resources/vector_icons/system_tray_rotation_lock_auto.1x.icon
@@ -37,5 +37,4 @@ R_CUBIC_TO, 0.47f, 0.47f, 1.25f, 0.47f, 1.72f, 0, R_LINE_TO, 4.31f, -4.27f, R_CUBIC_TO, 0.47f, -0.47f, 0.47f, -1.24f, 0, -1.71f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_rotation_lock_auto.icon b/ash/resources/vector_icons/system_tray_rotation_lock_auto.icon index c1b196fb..52d9765 100644 --- a/ash/resources/vector_icons/system_tray_rotation_lock_auto.icon +++ b/ash/resources/vector_icons/system_tray_rotation_lock_auto.icon
@@ -37,5 +37,4 @@ R_CUBIC_TO, 0.95f, 0.94f, 2.49f, 0.93f, 3.44f, -0.01f, R_LINE_TO, 8.62f, -8.53f, R_CUBIC_TO, 0.95f, -0.94f, 0.95f, -2.48f, 0, -3.42f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_rotation_lock_locked.1x.icon b/ash/resources/vector_icons/system_tray_rotation_lock_locked.1x.icon index f015dfb..45286a6 100644 --- a/ash/resources/vector_icons/system_tray_rotation_lock_locked.1x.icon +++ b/ash/resources/vector_icons/system_tray_rotation_lock_locked.1x.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, -0.31f, 0, -0.57f, 0.25f, -0.57f, 0.56f, R_V_LINE_TO, 2.22f, R_CUBIC_TO, 0, 0.31f, 0.26f, 0.56f, 0.57f, 0.56f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_rotation_lock_locked.icon b/ash/resources/vector_icons/system_tray_rotation_lock_locked.icon index a2d2402b..be80263a 100644 --- a/ash/resources/vector_icons/system_tray_rotation_lock_locked.icon +++ b/ash/resources/vector_icons/system_tray_rotation_lock_locked.icon
@@ -48,5 +48,4 @@ R_CUBIC_TO, -0.63f, 0, -1.14f, 0.5f, -1.14f, 1.11f, R_V_LINE_TO, 4.44f, CUBIC_TO, 19, 13.5f, 19.52f, 14, 20.14f, 14, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_screen_share.1x.icon b/ash/resources/vector_icons/system_tray_screen_share.1x.icon index 316ad37..661d84c 100644 --- a/ash/resources/vector_icons/system_tray_screen_share.1x.icon +++ b/ash/resources/vector_icons/system_tray_screen_share.1x.icon
@@ -26,5 +26,4 @@ LINE_TO, 11, 8, R_LINE_TO, -2.64f, 2, V_LINE_TO, 8.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_screen_share.icon b/ash/resources/vector_icons/system_tray_screen_share.icon index 517fac6..32b8cfc 100644 --- a/ash/resources/vector_icons/system_tray_screen_share.icon +++ b/ash/resources/vector_icons/system_tray_screen_share.icon
@@ -26,5 +26,4 @@ R_LINE_TO, 5.5f, 4.5f, LINE_TO, 17, 20, R_V_LINE_TO, -3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_tracing.1x.icon b/ash/resources/vector_icons/system_tray_tracing.1x.icon index 9edaf34..a761968 100644 --- a/ash/resources/vector_icons/system_tray_tracing.1x.icon +++ b/ash/resources/vector_icons/system_tray_tracing.1x.icon
@@ -30,5 +30,4 @@ V_LINE_TO, 8, R_H_LINE_TO, 2, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_tracing.icon b/ash/resources/vector_icons/system_tray_tracing.icon index 2a47ba2..6d4b8d8 100644 --- a/ash/resources/vector_icons/system_tray_tracing.icon +++ b/ash/resources/vector_icons/system_tray_tracing.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -7, R_H_LINE_TO, 3, R_V_LINE_TO, 7, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_update.1x.icon b/ash/resources/vector_icons/system_tray_update.1x.icon index dc3a3a3..92de678 100644 --- a/ash/resources/vector_icons/system_tray_update.1x.icon +++ b/ash/resources/vector_icons/system_tray_update.1x.icon
@@ -17,5 +17,4 @@ LINE_TO, 3.5f, 9, R_H_LINE_TO, 2.65f, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_update.icon b/ash/resources/vector_icons/system_tray_update.icon index 007cfc09..bb2c67f 100644 --- a/ash/resources/vector_icons/system_tray_update.icon +++ b/ash/resources/vector_icons/system_tray_update.icon
@@ -17,5 +17,4 @@ LINE_TO, 7, 18, R_H_LINE_TO, 5, R_V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_volume_mute.1x.icon b/ash/resources/vector_icons/system_tray_volume_mute.1x.icon index 1d7202e..c2810f15 100644 --- a/ash/resources/vector_icons/system_tray_volume_mute.1x.icon +++ b/ash/resources/vector_icons/system_tray_volume_mute.1x.icon
@@ -38,5 +38,4 @@ LINE_TO, 6.61f, 4.06f, LINE_TO, 8, 5.45f, V_LINE_TO, 2.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/system_tray_volume_mute.icon b/ash/resources/vector_icons/system_tray_volume_mute.icon index e2bbd094..a2479b9 100644 --- a/ash/resources/vector_icons/system_tray_volume_mute.icon +++ b/ash/resources/vector_icons/system_tray_volume_mute.icon
@@ -38,5 +38,4 @@ LINE_TO, 13.21f, 8.12f, LINE_TO, 16, 10.91f, V_LINE_TO, 5.33f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/touch_calibration_complete_check.1x.icon b/ash/resources/vector_icons/touch_calibration_complete_check.1x.icon index fb32c214..0b8d779 100644 --- a/ash/resources/vector_icons/touch_calibration_complete_check.1x.icon +++ b/ash/resources/vector_icons/touch_calibration_complete_check.1x.icon
@@ -18,5 +18,4 @@ LINE_TO, 50.67f, 21.33f, LINE_TO, 26.67f, 45.33f, LINE_TO, 26.67f, 45.33f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/touch_calibration_complete_check.icon b/ash/resources/vector_icons/touch_calibration_complete_check.icon index 7c6f4f5c..14b14f0 100644 --- a/ash/resources/vector_icons/touch_calibration_complete_check.icon +++ b/ash/resources/vector_icons/touch_calibration_complete_check.icon
@@ -18,5 +18,4 @@ LINE_TO, 101.33f, 42.67f, LINE_TO, 53.33f, 90.67f, LINE_TO, 53.33f, 90.67f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/touch_calibration_hand.icon b/ash/resources/vector_icons/touch_calibration_hand.icon index cca81278..63501ec9 100644 --- a/ash/resources/vector_icons/touch_calibration_hand.icon +++ b/ash/resources/vector_icons/touch_calibration_hand.icon
@@ -28,5 +28,4 @@ LINE_TO, 22.98f, 20.89f, LINE_TO, 14.58f, 23.23f, LINE_TO, 23.02f, 20.89f, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon b/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon index 6d9de85..e3fd929 100644 --- a/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon +++ b/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon
@@ -17,5 +17,4 @@ LINE_TO, 9, 2.53f, LINE_TO, 12.54f, 6, LINE_TO, 9, 6, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon b/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon index 2793144..df9d179 100644 --- a/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon +++ b/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon
@@ -17,5 +17,4 @@ LINE_TO, 17.33f, 4.67f, LINE_TO, 24.67f, 12, LINE_TO, 17.33f, 12, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/window_control_back.1x.icon b/ash/resources/vector_icons/window_control_back.1x.icon index 54a037c..d7865b2 100644 --- a/ash/resources/vector_icons/window_control_back.1x.icon +++ b/ash/resources/vector_icons/window_control_back.1x.icon
@@ -15,5 +15,4 @@ LINE_TO, 6.6f, 1, LINE_TO, 8, 2.25f, LINE_TO, 4.92f, 5, -CLOSE, -END +CLOSE
diff --git a/ash/resources/vector_icons/window_control_back.icon b/ash/resources/vector_icons/window_control_back.icon index 679d4d1..1820b1a8 100644 --- a/ash/resources/vector_icons/window_control_back.icon +++ b/ash/resources/vector_icons/window_control_back.icon
@@ -16,5 +16,4 @@ LINE_TO, 12.86f, 0, LINE_TO, 15, 2.05f, LINE_TO, 6.83f, 10, -CLOSE, -END +CLOSE
diff --git a/ash/shelf/app_list_shelf_item_delegate.cc b/ash/shelf/app_list_shelf_item_delegate.cc index db19d98a..5f34826 100644 --- a/ash/shelf/app_list_shelf_item_delegate.cc +++ b/ash/shelf/app_list_shelf_item_delegate.cc
@@ -22,8 +22,8 @@ int64_t display_id, ShelfLaunchSource source, ItemSelectedCallback callback) { - Shell::Get()->app_list_controller()->ToggleAppList(display_id, - app_list::kShelfButton); + Shell::Get()->app_list_controller()->ToggleAppList( + display_id, app_list::kShelfButton, event->time_stamp()); std::move(callback).Run(SHELF_ACTION_APP_LIST_SHOWN, base::nullopt); }
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index eda5b98..3864947 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -1131,7 +1131,7 @@ display::Screen::GetScreen() ->GetDisplayNearestWindow(shelf_widget_->GetNativeWindow()) .id(), - app_list::kSwipeFromShelf); + app_list::kSwipeFromShelf, gesture_in_screen.time_stamp()); Shell::Get()->app_list_controller()->UpdateYPositionAndOpacity( shelf_bounds.y(), GetAppListBackgroundOpacityOnShelfOpacity()); launcher_above_shelf_bottom_amount_ =
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 85b971ec..006da6f 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -350,6 +350,24 @@ return bounds; } +gfx::Rect SplitViewController::GetSnappedWindowBoundsInScreenUnadjusted( + aura::Window* window, + SnapPosition snap_position) { + const gfx::Rect work_area_bounds_in_screen = + GetDisplayWorkAreaBoundsInScreen(window); + if (snap_position == NONE) + return work_area_bounds_in_screen; + + gfx::Rect left_or_top_rect, right_or_bottom_rect; + GetSnappedWindowBoundsInScreenInternal(window, &left_or_top_rect, + &right_or_bottom_rect); + + if (IsCurrentScreenOrientationPrimary()) + return (snap_position == LEFT) ? left_or_top_rect : right_or_bottom_rect; + else + return (snap_position == LEFT) ? right_or_bottom_rect : left_or_top_rect; +} + void SplitViewController::StartResize(const gfx::Point& location_in_screen) { DCHECK(IsSplitViewModeActive()); is_resizing_ = true;
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index 1a9ac07c..2f4be52 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -104,7 +104,10 @@ aura::Window* GetDefaultSnappedWindow(); // Gets the window bounds according to the snap state |snap_state| and the - // separator position |separator_position_|. + // divider position |divider_position_|. The returned snapped window bounds + // are adjusted to its minimum size if the desired bounds are smaller than + // its minumum bounds. Note: the snapped window bounds can't be pushed + // outside of the workspace area. gfx::Rect GetSnappedWindowBoundsInParent(aura::Window* window, SnapPosition snap_position); gfx::Rect GetSnappedWindowBoundsInScreen(aura::Window* window, @@ -112,6 +115,11 @@ gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window) const; gfx::Rect GetDisplayWorkAreaBoundsInScreen(aura::Window* window) const; + // Gets the desired snapped window bounds accoridng to the snap state + // |snap_state| and the divider pistion |divider_position_|. + gfx::Rect GetSnappedWindowBoundsInScreenUnadjusted(aura::Window* window, + SnapPosition snap_postion); + void StartResize(const gfx::Point& location_in_screen); void Resize(const gfx::Point& location_in_screen); void EndResize(const gfx::Point& location_in_screen);
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc index 18d13a38..0af7260 100644 --- a/ash/wm/workspace/backdrop_controller.cc +++ b/ash/wm/workspace/backdrop_controller.cc
@@ -127,8 +127,7 @@ if (window->GetRootWindow() != backdrop_window_->GetRootWindow()) return; - if (!backdrop_->IsVisible()) - Show(); + Show(); // Since the backdrop needs to be immediately behind the window and the // stacking functions only guarantee a "it's above or below", we need @@ -157,11 +156,29 @@ RemoveForceHidden(); } +void BackdropController::OnSplitViewModeStarting() { + Shell::Get()->split_view_controller()->AddObserver(this); +} + +void BackdropController::OnSplitViewModeEnded() { + Shell::Get()->split_view_controller()->RemoveObserver(this); +} + void BackdropController::OnAccessibilityStatusChanged( AccessibilityNotificationVisibility notify) { UpdateBackdrop(); } +void BackdropController::OnSplitViewStateChanged( + SplitViewController::State previous_state, + SplitViewController::State state) { + UpdateBackdrop(); +} + +void BackdropController::OnSplitViewDividerPositionChanged() { + UpdateBackdrop(); +} + void BackdropController::EnsureBackdropWidget() { if (backdrop_) return; @@ -236,8 +253,12 @@ } void BackdropController::Show() { + // Makes sure that the backdrop has the correct bounds if it should not be + // fullscreen size. + backdrop_->SetFullscreen(BackdropShouldFullscreen()); + if (!BackdropShouldFullscreen()) + backdrop_->SetBounds(GetBackdropBounds()); backdrop_->Show(); - backdrop_->SetFullscreen(true); } void BackdropController::Hide() { @@ -268,4 +289,36 @@ UpdateBackdrop(); } +bool BackdropController::BackdropShouldFullscreen() { + aura::Window* window = GetTopmostWindowWithBackdrop(); + SplitViewController* split_view_controller = + Shell::Get()->split_view_controller(); + SplitViewController::State state = split_view_controller->state(); + if ((state == SplitViewController::LEFT_SNAPPED && + window == split_view_controller->left_window()) || + (state == SplitViewController::RIGHT_SNAPPED && + window == split_view_controller->right_window())) { + return false; + } + + return true; +} + +gfx::Rect BackdropController::GetBackdropBounds() { + DCHECK(!BackdropShouldFullscreen()); + + SplitViewController* split_view_controller = + Shell::Get()->split_view_controller(); + SplitViewController::State state = split_view_controller->state(); + DCHECK(state == SplitViewController::LEFT_SNAPPED || + state == SplitViewController::RIGHT_SNAPPED); + aura::Window* snapped_window = + split_view_controller->GetDefaultSnappedWindow(); + SplitViewController::SnapPosition snap_position = + (state == SplitViewController::LEFT_SNAPPED) ? SplitViewController::LEFT + : SplitViewController::RIGHT; + return split_view_controller->GetSnappedWindowBoundsInScreenUnadjusted( + snapped_window, snap_position); +} + } // namespace ash
diff --git a/ash/wm/workspace/backdrop_controller.h b/ash/wm/workspace/backdrop_controller.h index bfd72f0..9e5b460 100644 --- a/ash/wm/workspace/backdrop_controller.h +++ b/ash/wm/workspace/backdrop_controller.h
@@ -9,6 +9,7 @@ #include "ash/accessibility/accessibility_observer.h" #include "ash/shell_observer.h" +#include "ash/wm/splitview/split_view_controller.h" #include "base/macros.h" namespace aura { @@ -41,7 +42,9 @@ // 1) Has a aura::client::kHasBackdrop property = true. // 2) BackdropDelegate::HasBackdrop(aura::Window* window) returns true. // 3) Active ARC window when the spoken feedback is enabled. -class BackdropController : public ShellObserver, public AccessibilityObserver { +class BackdropController : public ShellObserver, + public AccessibilityObserver, + public SplitViewController::Observer { public: explicit BackdropController(aura::Window* container); ~BackdropController() override; @@ -64,11 +67,18 @@ void OnOverviewModeEnded() override; void OnAppListVisibilityChanged(bool shown, aura::Window* root_window) override; + void OnSplitViewModeStarting() override; + void OnSplitViewModeEnded() override; // AccessibilityObserver: void OnAccessibilityStatusChanged( AccessibilityNotificationVisibility notify) override; + // SplitViewController::Observer: + void OnSplitViewStateChanged(SplitViewController::State previous_state, + SplitViewController::State state) override; + void OnSplitViewDividerPositionChanged() override; + private: friend class WorkspaceControllerTestApi; @@ -93,6 +103,18 @@ // Decrement |force_hidden_counter_| and then update backdrop state. void RemoveForceHidden(); + // Returns true if the backdrop window should be fullscreen. It should not be + // fullscreen only if 1) split view is active and 2) there is only one snapped + // window and 3) the snapped window is the topmost window which should have + // the backdrop. + bool BackdropShouldFullscreen(); + + // Gets the bounds for the backdrop window if it should not be fullscreen. + // It's the case for splitview mode, if there is only one snapped window, the + // backdrop should not cover the non-snapped side of the screen, thus the + // backdrop bounds should be the bounds of the snapped window. + gfx::Rect GetBackdropBounds(); + // The backdrop which covers the rest of the screen. views::Widget* backdrop_ = nullptr;
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 6d74359..804db01f 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1755,15 +1755,14 @@ default_container()->children()[0]->bounds()); // Snap the window to left. Test that the backdrop window is still visible - // and is the second child in the container. Its bounds should still be the - // same as the container bounds. + // and is the second child in the container. Its bounds should be the same + // as the snapped window's bounds. split_view_controller->SnapWindow(window1.get(), SplitViewController::LEFT); EXPECT_EQ(2U, default_container()->children().size()); for (auto* child : default_container()->children()) EXPECT_TRUE(child->IsVisible()); EXPECT_EQ(window1.get(), default_container()->children()[1]); - EXPECT_EQ(default_container()->bounds(), - default_container()->children()[0]->bounds()); + EXPECT_EQ(window1->bounds(), default_container()->children()[0]->bounds()); // Now snap another window to right. Test that the backdrop window is still // visible but is now the third window in the container. Its bounds should
diff --git a/base/android/java/templates/BuildConfig.template b/base/android/java/templates/BuildConfig.template index 8d6f440..2b4d1a6f 100644 --- a/base/android/java/templates/BuildConfig.template +++ b/base/android/java/templates/BuildConfig.template
@@ -18,18 +18,11 @@ */ public class BuildConfig { - /** Whether multidex is enabled for this target. - * - * This has to be a function instead of a static final boolean s.t. the initial false value - * doesn't get optimized into {@link ChromiumMultiDexInstaller} at base_java compile time. - */ - public static boolean isMultidexEnabled() { #if defined(ENABLE_MULTIDEX) - return true; + public static MAYBE_FINAL boolean IS_MULTIDEX_ENABLED = true; #else - return false; + public static MAYBE_FINAL boolean IS_MULTIDEX_ENABLED = false; #endif - } #if defined(_FIREBASE_APP_ID) public static MAYBE_FINAL String FIREBASE_APP_ID = QUOTE(_FIREBASE_APP_ID);
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 028cf9f..252cd04c 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -225,8 +225,6 @@ void MessageLoop::SetNestableTasksAllowed(bool allowed) { if (allowed) { - CHECK(RunLoop::IsNestingAllowedOnCurrentThread()); - // Kick the native pump just in case we enter a OS-driven nested message // loop that does not go through RunLoop::Run(). pump_->ScheduleWork(); @@ -243,13 +241,11 @@ // implementation detail. http://crbug.com/703346 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { DCHECK_EQ(this, current()); - CHECK(allow_task_observers_); task_observers_.AddObserver(task_observer); } void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { DCHECK_EQ(this, current()); - CHECK(allow_task_observers_); task_observers_.RemoveObserver(task_observer); }
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index 27ee7fe..2f4f24f 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -276,10 +276,6 @@ // Runs the specified PendingTask. void RunTask(PendingTask* pending_task); - // Disallow task observers. After this is called, calling - // Add/RemoveTaskObserver() on this MessageLoop will crash. - void DisallowTaskObservers() { allow_task_observers_ = false; } - //---------------------------------------------------------------------------- protected: std::unique_ptr<MessagePump> pump_; @@ -399,9 +395,6 @@ // MessageLoop is bound to its thread and constant forever after. PlatformThreadId thread_id_ = kInvalidThreadId; - // Whether task observers are allowed. - bool allow_task_observers_ = true; - // Holds data stored through the SequenceLocalStorageSlot API. internal::SequenceLocalStorageMap sequence_local_storage_map_;
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index 52adb693..71ff0484 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -147,9 +147,6 @@ // usage in bytes, as per definition of WorkingSetBytes. Note that this // function is somewhat expensive on Windows (a few ms per process). bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const; - // Computes pss (proportional set size) of a process. Note that this - // function is somewhat expensive on Windows (a few ms per process). - bool GetProportionalSetSizeBytes(uint64_t* pss_bytes) const; #if defined(OS_LINUX) || defined(OS_ANDROID) // Resident Set Size is a Linux/Android specific memory concept. Do not
diff --git a/base/process/process_metrics_win.cc b/base/process/process_metrics_win.cc index e3b053bd..6d1c7d5 100644 --- a/base/process/process_metrics_win.cc +++ b/base/process/process_metrics_win.cc
@@ -219,27 +219,6 @@ return true; } -// This function calculates the proportional set size for a process. -bool ProcessMetrics::GetProportionalSetSizeBytes(uint64_t* pss_bytes) const { - double ws_pss = 0.0; - - WorkingSetInformationBuffer buffer; - if (!buffer.QueryPageEntries(process_.Get())) - return false; - - size_t num_page_entries = buffer.GetPageEntryCount(); - for (size_t i = 0; i < num_page_entries; i++) { - if (buffer->WorkingSetInfo[i].Shared && - buffer->WorkingSetInfo[i].ShareCount > 0) - ws_pss += 1.0 / buffer->WorkingSetInfo[i].ShareCount; - else - ws_pss += 1.0; - } - - *pss_bytes = static_cast<uint64_t>(ws_pss * GetPageSize()); - return true; -} - static uint64_t FileTimeToUTC(const FILETIME& ftime) { LARGE_INTEGER li; li.LowPart = ftime.dwLowDateTime;
diff --git a/base/run_loop.cc b/base/run_loop.cc index 467e2d83..30d8c4ea 100644 --- a/base/run_loop.cc +++ b/base/run_loop.cc
@@ -103,9 +103,6 @@ DCHECK(delegate_) << "A RunLoop::Delegate must be bound to this thread prior " "to using RunLoop."; DCHECK(origin_task_runner_); - - DCHECK(IsNestingAllowedOnCurrentThread() || - type_ != Type::kNestableTasksAllowed); } RunLoop::~RunLoop() { @@ -219,7 +216,6 @@ void RunLoop::AddNestingObserverOnCurrentThread(NestingObserver* observer) { Delegate* delegate = tls_delegate.Get().Get(); DCHECK(delegate); - CHECK(delegate->allow_nesting_); delegate->nesting_observers_.AddObserver(observer); } @@ -227,21 +223,10 @@ void RunLoop::RemoveNestingObserverOnCurrentThread(NestingObserver* observer) { Delegate* delegate = tls_delegate.Get().Get(); DCHECK(delegate); - CHECK(delegate->allow_nesting_); delegate->nesting_observers_.RemoveObserver(observer); } // static -bool RunLoop::IsNestingAllowedOnCurrentThread() { - return tls_delegate.Get().Get()->allow_nesting_; -} - -// static -void RunLoop::DisallowNestingOnCurrentThread() { - tls_delegate.Get().Get()->allow_nesting_ = false; -} - -// static void RunLoop::QuitCurrentDeprecated() { DCHECK(IsRunningOnCurrentThread()); tls_delegate.Get().Get()->active_run_loops_.top()->Quit(); @@ -301,7 +286,6 @@ const bool is_nested = active_run_loops_.size() > 1; if (is_nested) { - CHECK(delegate_->allow_nesting_); for (auto& observer : delegate_->nesting_observers_) observer.OnBeginNestedRunLoop(); if (type_ == Type::kNestableTasksAllowed)
diff --git a/base/run_loop.h b/base/run_loop.h index b7c594e1..d3858fce 100644 --- a/base/run_loop.h +++ b/base/run_loop.h
@@ -50,9 +50,7 @@ // recursive task processing is disabled. // // In general, nestable RunLoops are to be avoided. They are dangerous and - // difficult to get right, so please use with extreme caution. To further - // protect this: kNestableTasksAllowed RunLoops are only allowed on threads - // where IsNestingAllowedOnCurrentThread(). + // difficult to get right, so please use with extreme caution. // // A specific example where this makes a difference is: // - The thread is running a RunLoop. @@ -145,13 +143,6 @@ static void AddNestingObserverOnCurrentThread(NestingObserver* observer); static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer); - // Returns true if nesting is allowed on this thread. - static bool IsNestingAllowedOnCurrentThread(); - - // Disallow nesting. After this is called, running a nested RunLoop or calling - // Add/RemoveNestingObserverOnCurrentThread() on this thread will crash. - static void DisallowNestingOnCurrentThread(); - // A RunLoop::Delegate is a generic interface that allows RunLoop to be // separate from the underlying implementation of the message loop for this // thread. It holds private state used by RunLoops on its associated thread. @@ -207,7 +198,6 @@ // have more than a few entries. using RunLoopStack = base::stack<RunLoop*, std::vector<RunLoop*>>; - bool allow_nesting_ = true; RunLoopStack active_run_loops_; ObserverList<RunLoop::NestingObserver> nesting_observers_;
diff --git a/base/run_loop_unittest.cc b/base/run_loop_unittest.cc index 96060f4a..ee12ea5 100644 --- a/base/run_loop_unittest.cc +++ b/base/run_loop_unittest.cc
@@ -596,8 +596,6 @@ } // namespace TEST_P(RunLoopTest, NestingObservers) { - EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread()); - testing::StrictMock<MockNestingObserver> nesting_observer; testing::StrictMock<MockTask> mock_task_a; testing::StrictMock<MockTask> mock_task_b; @@ -606,10 +604,6 @@ const RepeatingClosure run_nested_loop = Bind([]() { RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed); - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce([]() { - EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread()); - })); ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, nested_run_loop.QuitClosure()); nested_run_loop.Run(); @@ -617,7 +611,9 @@ // Generate a stack of nested RunLoops. OnBeginNestedRunLoop() is expected // when beginning each nesting depth and OnExitNestedRunLoop() is expected - // when exiting each nesting depth. + // when exiting each nesting depth. Each one of these tasks is ahead of the + // QuitClosures as those are only posted at the end of the queue when + // |run_nested_loop| is executed. ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_nested_loop); ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -640,21 +636,6 @@ RunLoop::RemoveNestingObserverOnCurrentThread(&nesting_observer); } -// Disabled on Android per http://crbug.com/643760. -#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID) -TEST_P(RunLoopTest, DisallowNestingDeathTest) { - EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread()); - RunLoop::DisallowNestingOnCurrentThread(); - EXPECT_FALSE(RunLoop::IsNestingAllowedOnCurrentThread()); - - ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce([]() { - RunLoop nested_run_loop; - nested_run_loop.RunUntilIdle(); - })); - EXPECT_DEATH({ run_loop_.RunUntilIdle(); }, ""); -} -#endif // defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID) - TEST_P(RunLoopTest, DisallowRunningForTesting) { RunLoop::ScopedDisallowRunningForTesting disallow_running; EXPECT_DCHECK_DEATH({ run_loop_.Run(); });
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index b64b9840..5537bbd4 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -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("//build/compiled_action.gni") import("//build/config/ui.gni") import("//build/config/nacl/config.gni") @@ -184,6 +185,17 @@ ] } + if (is_linux) { + public_deps += [ ":fontconfig_util_linux" ] + data_deps = [ + "//third_party/test_fonts", + ] + if (current_toolchain == host_toolchain) { + data_deps += [ ":do_generate_fontconfig_caches" ] + data += [ "$root_out_dir/fontconfig_caches/" ] + } + } + if (is_ios) { set_sources_assignment_filter([]) sources += [ "test_file_util_mac.cc" ] @@ -317,6 +329,43 @@ } if (is_linux) { + source_set("fontconfig_util_linux") { + sources = [ + "fontconfig_util_linux.cc", + "fontconfig_util_linux.h", + ] + deps = [ + "//base", + "//third_party/fontconfig", + ] + } + + if (current_toolchain == host_toolchain) { + executable("generate_fontconfig_caches") { + testonly = true + sources = [ + "generate_fontconfig_caches.cc", + ] + deps = [ + ":fontconfig_util_linux", + "//base", + "//build/config:exe_and_shlib_deps", + ] + } + + compiled_action("do_generate_fontconfig_caches") { + testonly = true + tool = ":generate_fontconfig_caches" + data_deps = [ + "//third_party/test_fonts", + ] + args = [] + outputs = [ + "$root_out_dir/fontconfig_caches/STAMP", + ] + } + } + shared_library("malloc_wrapper") { testonly = true sources = [
diff --git a/base/test/fontconfig_util_linux.cc b/base/test/fontconfig_util_linux.cc new file mode 100644 index 0000000..cc5d496a --- /dev/null +++ b/base/test/fontconfig_util_linux.cc
@@ -0,0 +1,458 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/fontconfig_util_linux.h" + +#include <fontconfig/fontconfig.h> + +#include "base/base_paths.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" + +namespace base { + +namespace { + +const char kFontsConfTemplate[] = R"(<?xml version="1.0"?> +<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> +<fontconfig> + + <!-- Cache location. --> + <cachedir>$1</cachedir> + + <!-- GCS-synced fonts. --> + <dir>$2</dir> + + <!-- System fonts. TODO(thomasanderson): Remove these. --> + <dir>/usr/share/fonts/opentype/ipafont-gothic</dir> + <dir>/usr/share/fonts/opentype/ipafont-mincho</dir> + <dir>/usr/share/fonts/truetype/msttcorefonts</dir> + + <!-- Default properties. --> + <match target="font"> + <edit name="embeddedbitmap" mode="append_last"> + <bool>false</bool> + </edit> + </match> + + <!-- TODO(thomasanderson): Remove once Tinos is added to GCS fonts. --> + <match target="pattern"> + <test name="family" compare="eq"> + <string>Tinos</string> + </test> + <test name="prgname" compare="eq"> + <string>chromevox_tests</string> + </test> + <edit name="hintstyle" mode="assign"> + <const>hintslight</const> + </edit> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>Times</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans</string> + </test> + <edit name="family" mode="assign"> + <string>DejaVu Sans</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans serif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <!-- Some layout tests specify Helvetica as a family and we need to make sure + that we don't fallback to Times New Roman for them --> + <match target="pattern"> + <test qual="any" name="family"> + <string>Helvetica</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans-serif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>serif</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>mono</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>monospace</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>Courier</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>cursive</string> + </test> + <edit name="family" mode="assign"> + <string>Comic Sans MS</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>fantasy</string> + </test> + <edit name="family" mode="assign"> + <string>Impact</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>Monaco</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <!-- TODO(thomasanderson): Move these configs to be test-specific. --> + <match target="pattern"> + <test name="family" compare="eq"> + <string>NonAntiAliasedSans</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="antialias" mode="assign"> + <bool>false</bool> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>SlightHintedGeorgia</string> + </test> + <edit name="family" mode="assign"> + <string>Georgia</string> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintslight</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>NonHintedSans</string> + </test> + <edit name="family" mode="assign"> + <string>Verdana</string> + </edit> + <!-- These deliberately contradict each other. The 'hinting' preference + should take priority --> + <edit name="hintstyle" mode="assign"> + <const>hintfull</const> + </edit> + <edit name="hinting" mode="assign"> + <bool>false</bool> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>AutohintedSerif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="autohint" mode="assign"> + <bool>true</bool> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintmedium</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>HintedSerif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="autohint" mode="assign"> + <bool>false</bool> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintmedium</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>FullAndAutoHintedSerif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="autohint" mode="assign"> + <bool>true</bool> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintfull</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>SubpixelEnabledArial</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="rgba" mode="assign"> + <const>rgb</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>SubpixelDisabledArial</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="rgba" mode="assign"> + <const>none</const> + </edit> + </match> + + <match target="pattern"> + <!-- FontConfig doesn't currently provide a well-defined way to turn on + subpixel positioning. This is just an arbitrary pattern to use after + turning subpixel positioning on globally to ensure that we don't have + issues with our style getting cached for other tests. --> + <test name="family" compare="eq"> + <string>SubpixelPositioning</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <!-- See comments above --> + <test name="family" compare="eq"> + <string>SubpixelPositioningAhem</string> + </test> + <edit name="family" mode="assign"> + <string>ahem</string> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>SlightHintedTimesNewRoman</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintslight</const> + </edit> + </match> + + <!-- When we encounter a character that the current font doesn't + support, gfx::GetFallbackFontForChar() returns the first font + that does have a glyph for the character. The list of fonts is + sorted by a pattern that includes the current locale, but doesn't + include a font family (which means that the fallback font depends + on the locale but not on the current font). + + DejaVu Sans is commonly the only font that supports some + characters, such as "⇧", and even when other candidates are + available, DejaVu Sans is commonly first among them, because of + the way Fontconfig is ordinarily configured. For example, the + configuration in the Fonconfig source lists DejaVu Sans under the + sans-serif generic family, and appends sans-serif to patterns + that don't already include a generic family (such as the pattern + in gfx::GetFallbackFontForChar()). + + To get the same fallback font in the layout tests, we could + duplicate this configuration here, or more directly, simply + append DejaVu Sans to all patterns. --> + <match target="pattern"> + <edit name="family" mode="append_last"> + <string>DejaVu Sans</string> + </edit> + </match> + +</fontconfig> +)"; + +} // namespace + +void SetUpFontconfig() { + FilePath dir_module; + PathService::Get(DIR_MODULE, &dir_module); + FilePath font_cache = dir_module.Append("fontconfig_caches"); + FilePath test_fonts = dir_module.Append("test_fonts"); + std::string fonts_conf = ReplaceStringPlaceholders( + kFontsConfTemplate, {font_cache.value(), test_fonts.value()}, nullptr); + + FcConfig* config = FcConfigCreate(); + CHECK(config); +#if FC_VERSION >= 21205 + CHECK(FcConfigParseAndLoadFromMemory( + config, reinterpret_cast<const FcChar8*>(fonts_conf.c_str()), FcTrue)); +#else + FilePath temp; + CHECK(CreateTemporaryFile(&temp)); + CHECK(WriteFile(temp, fonts_conf.c_str(), fonts_conf.size())); + CHECK(FcConfigParseAndLoad( + config, reinterpret_cast<const FcChar8*>(temp.value().c_str()), FcTrue)); + CHECK(DeleteFile(temp, false)); +#endif + CHECK(FcConfigBuildFonts(config)); + CHECK(FcConfigSetCurrent(config)); + + // Decrement the reference count for |config|. It's now owned by fontconfig. + FcConfigDestroy(config); +} + +void TearDownFontconfig() { + FcFini(); +} + +bool LoadFontIntoFontconfig(const FilePath& path) { + if (!PathExists(path)) { + LOG(ERROR) << "You are missing " << path.value() << ". Try re-running " + << "build/install-build-deps.sh. " + << "Please make sure that " + << "third_party/test_fonts/ has downloaded " + << "and extracted the test_fonts." + << "Also see " + << "https://chromium.googlesource.com/chromium/src/+/master/" + << "docs/layout_tests_linux.md"; + return false; + } + + if (!FcConfigAppFontAddFile( + NULL, reinterpret_cast<const FcChar8*>(path.value().c_str()))) { + LOG(ERROR) << "Failed to load font " << path.value(); + return false; + } + + return true; +} + +bool LoadConfigFileIntoFontconfig(const FilePath& path) { + // Unlike other FcConfig functions, FcConfigParseAndLoad() doesn't default to + // the current config when passed NULL. So that's cool. + if (!FcConfigParseAndLoad( + FcConfigGetCurrent(), + reinterpret_cast<const FcChar8*>(path.value().c_str()), FcTrue)) { + LOG(ERROR) << "Fontconfig failed to load " << path.value(); + return false; + } + return true; +} + +bool LoadConfigDataIntoFontconfig(const FilePath& temp_dir, + const std::string& data) { + FilePath path; + if (!CreateTemporaryFileInDir(temp_dir, &path)) { + PLOG(ERROR) << "Unable to create temporary file in " << temp_dir.value(); + return false; + } + if (WriteFile(path, data.data(), data.size()) != + static_cast<int>(data.size())) { + PLOG(ERROR) << "Unable to write config data to " << path.value(); + return false; + } + return LoadConfigFileIntoFontconfig(path); +} + +std::string CreateFontconfigEditStanza(const std::string& name, + const std::string& type, + const std::string& value) { + return StringPrintf( + " <edit name=\"%s\" mode=\"assign\">\n" + " <%s>%s</%s>\n" + " </edit>\n", + name.c_str(), type.c_str(), value.c_str(), type.c_str()); +} + +std::string CreateFontconfigTestStanza(const std::string& name, + const std::string& op, + const std::string& type, + const std::string& value) { + return StringPrintf( + " <test name=\"%s\" compare=\"%s\" qual=\"any\">\n" + " <%s>%s</%s>\n" + " </test>\n", + name.c_str(), op.c_str(), type.c_str(), value.c_str(), type.c_str()); +} + +std::string CreateFontconfigAliasStanza(const std::string& original_family, + const std::string& preferred_family) { + return StringPrintf( + " <alias>\n" + " <family>%s</family>\n" + " <prefer><family>%s</family></prefer>\n" + " </alias>\n", + original_family.c_str(), preferred_family.c_str()); +} + +} // namespace base
diff --git a/base/test/fontconfig_util_linux.h b/base/test/fontconfig_util_linux.h new file mode 100644 index 0000000..ac7037a --- /dev/null +++ b/base/test/fontconfig_util_linux.h
@@ -0,0 +1,51 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TEST_FONTCONFIG_UTIL_LINUX_H_ +#define BASE_TEST_FONTCONFIG_UTIL_LINUX_H_ + +#include <stddef.h> + +#include <string> + +namespace base { +class FilePath; + +// Initializes Fontconfig with a custom configuration suitable for tests. +void SetUpFontconfig(); + +// Deinitializes Fontconfig. +void TearDownFontconfig(); + +// Loads the font file at |path| into the current config, returning true on +// success. +bool LoadFontIntoFontconfig(const FilePath& path); + +// Instructs Fontconfig to load |path|, an XML configuration file, into the +// current config, returning true on success. +bool LoadConfigFileIntoFontconfig(const FilePath& path); + +// Writes |data| to a file in |temp_dir| and passes it to +// LoadConfigFileIntoFontconfig(). +bool LoadConfigDataIntoFontconfig(const FilePath& temp_dir, + const std::string& data); + +// Returns a Fontconfig <edit> stanza. +std::string CreateFontconfigEditStanza(const std::string& name, + const std::string& type, + const std::string& value); + +// Returns a Fontconfig <test> stanza. +std::string CreateFontconfigTestStanza(const std::string& name, + const std::string& op, + const std::string& type, + const std::string& value); + +// Returns a Fontconfig <alias> stanza. +std::string CreateFontconfigAliasStanza(const std::string& original_family, + const std::string& preferred_family); + +} // namespace base + +#endif // BASE_TEST_FONTCONFIG_UTIL_LINUX_H_
diff --git a/base/test/generate_fontconfig_caches.cc b/base/test/generate_fontconfig_caches.cc new file mode 100644 index 0000000..681ed24 --- /dev/null +++ b/base/test/generate_fontconfig_caches.cc
@@ -0,0 +1,24 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/test/fontconfig_util_linux.h" + +int main(void) { + base::SetUpFontconfig(); + base::TearDownFontconfig(); + + base::FilePath dir_module; + CHECK(PathService::Get(base::DIR_MODULE, &dir_module)); + base::FilePath fontconfig_caches = dir_module.Append("fontconfig_caches"); + CHECK(base::DirectoryExists(fontconfig_caches)); + base::FilePath stamp = fontconfig_caches.Append("STAMP"); + CHECK_EQ(0, base::WriteFile(stamp, "", 0)); + + return 0; +}
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 4cb2208..3d53097 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -62,6 +62,10 @@ #include "base/test/test_support_ios.h" #endif +#if defined(OS_LINUX) +#include "base/test/fontconfig_util_linux.h" +#endif + namespace base { namespace { @@ -456,6 +460,12 @@ #endif #endif +#if defined(OS_LINUX) + // TODO(thomasanderson): Call TearDownFontconfig() in Shutdown(). It would + // currently crash because of leaked FcFontSet's in font_fallback_linux.cc. + SetUpFontconfig(); +#endif + CatchMaybeTests(); ResetCommandLine(); AddTestLauncherResultPrinter();
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index b3517ba..da74494f 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -39,6 +39,7 @@ from py_utils import tempfile_ext import tombstones + with host_paths.SysPath( os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party'), 0): import jinja2 # pylint: disable=import-error @@ -75,8 +76,6 @@ _EXTRA_TEST_LIST = ( 'org.chromium.base.test.BaseChromiumAndroidJUnitRunner.TestList') -UI_CAPTURE_DIRS = ['chromium_tests_root', 'UiCapture'] - FEATURE_ANNOTATION = 'Feature' RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest' @@ -126,7 +125,6 @@ super(LocalDeviceInstrumentationTestRun, self).__init__( env, test_instance) self._flag_changers = {} - self._ui_capture_dir = dict() self._replace_package_contextmanager = None #override @@ -253,21 +251,8 @@ valgrind_tools.SetChromeTimeoutScale( dev, self._test_instance.timeout_scale) - @trace_event.traced - def setup_ui_capture_dir(dev): - # Make sure the UI capture directory exists and is empty by deleting - # and recreating it. - # TODO (aberent) once DeviceTempDir exists use it here. - self._ui_capture_dir[dev] = posixpath.join( - dev.GetExternalStoragePath(), - *UI_CAPTURE_DIRS) - - if dev.PathExists(self._ui_capture_dir[dev]): - dev.RunShellCommand(['rm', '-rf', self._ui_capture_dir[dev]]) - dev.RunShellCommand(['mkdir', self._ui_capture_dir[dev]]) - steps += [set_debug_app, edit_shared_prefs, push_test_data, - create_flag_changer, setup_ui_capture_dir] + create_flag_changer] def bind_crash_handler(step, dev): return lambda: crash_handler.RetryOnSystemCrash(step, dev) @@ -372,7 +357,11 @@ device.adb, suffix='.png', dir=device.GetExternalStoragePath()) extras[EXTRA_SCREENSHOT_FILE] = screenshot_device_file.name - extras[EXTRA_UI_CAPTURE_DIR] = self._ui_capture_dir[device] + # Set up the screenshot directory. This needs to be done for each test so + # that we only get screenshots created by that test. + ui_capture_dir = device_temp_file.NamedDeviceTemporaryDirectory( + device.adb) + extras[EXTRA_UI_CAPTURE_DIR] = ui_capture_dir.name if self._env.trace_output: trace_device_file = device_temp_file.DeviceTempFile( @@ -450,114 +439,116 @@ time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), device.serial) - with self._env.output_manager.ArchivedTempfile( - stream_name, 'logcat') as logcat_file: - try: - with logcat_monitor.LogcatMonitor( - device.adb, - filter_specs=local_device_environment.LOGCAT_FILTERS, - output_file=logcat_file.name, - transform_func=self._test_instance.MaybeDeobfuscateLines) as logmon: - with _LogTestEndpoints(device, test_name): - with contextlib_ext.Optional( - trace_event.trace(test_name), - self._env.trace_output): - output = device.StartInstrumentation( - target, raw=True, extras=extras, timeout=timeout, retries=0) - finally: - logmon.Close() - - if logcat_file.Link(): - logging.info('Logcat saved to %s', logcat_file.Link()) - - duration_ms = time_ms() - start_ms - - with contextlib_ext.Optional( - trace_event.trace('ProcessResults'), - self._env.trace_output): - output = self._test_instance.MaybeDeobfuscateLines(output) - # TODO(jbudorick): Make instrumentation tests output a JSON so this - # doesn't have to parse the output. - result_code, result_bundle, statuses = ( - self._test_instance.ParseAmInstrumentRawOutput(output)) - results = self._test_instance.GenerateTestResults( - result_code, result_bundle, statuses, start_ms, duration_ms, - device.product_cpu_abi, self._test_instance.symbolizer) - - if self._env.trace_output: - self._SaveTraceData(trace_device_file, device, test['class']) - - def restore_flags(): - if flags_to_add: - self._flag_changers[str(device)].Restore() - - def restore_timeout_scale(): - if test_timeout_scale: - valgrind_tools.SetChromeTimeoutScale( - device, self._test_instance.timeout_scale) - - def handle_coverage_data(): - if self._test_instance.coverage_directory: - device.PullFile(coverage_directory, - self._test_instance.coverage_directory) - device.RunShellCommand( - 'rm -f %s' % posixpath.join(coverage_directory, '*'), - check_return=True, shell=True) - - def handle_render_test_data(): - if _IsRenderTest(test): - # Render tests do not cause test failure by default. So we have to check - # to see if any failure images were generated even if the test does not - # fail. - try: - self._ProcessRenderTestResults( - device, render_tests_device_output_dir, results) - finally: - device.RemovePath(render_tests_device_output_dir, - recursive=True, force=True) - - def pull_ui_screen_captures(): - screenshots = [] - for filename in device.ListDirectory(self._ui_capture_dir[device]): - if filename.endswith('.json'): - screenshots.append(pull_ui_screenshot(filename)) - if screenshots: - json_archive_name = 'ui_capture_%s_%s.json' % ( - test_name.replace('#', '.'), - time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime())) - with self._env.output_manager.ArchivedTempfile( - json_archive_name, 'ui_capture', output_manager.Datatype.JSON - ) as json_archive: - json.dump(screenshots, json_archive) - for result in results: - result.SetLink('ui screenshot', json_archive.Link()) - - def pull_ui_screenshot(filename): - source_dir = self._ui_capture_dir[device] - json_path = posixpath.join(source_dir, filename) - json_data = json.loads(device.ReadFile(json_path)) - image_file_path = posixpath.join(source_dir, json_data['location']) + with ui_capture_dir: with self._env.output_manager.ArchivedTempfile( - json_data['location'], 'ui_capture', output_manager.Datatype.IMAGE - ) as image_archive: - device.PullFile(image_file_path, image_archive.name) - json_data['image_link'] = image_archive.Link() - return json_data + stream_name, 'logcat') as logcat_file: + try: + with logcat_monitor.LogcatMonitor( + device.adb, + filter_specs=local_device_environment.LOGCAT_FILTERS, + output_file=logcat_file.name, + transform_func=self._test_instance.MaybeDeobfuscateLines + ) as logmon: + with _LogTestEndpoints(device, test_name): + with contextlib_ext.Optional( + trace_event.trace(test_name), + self._env.trace_output): + output = device.StartInstrumentation( + target, raw=True, extras=extras, timeout=timeout, retries=0) + finally: + logmon.Close() - # While constructing the TestResult objects, we can parallelize several - # steps that involve ADB. These steps should NOT depend on any info in - # the results! Things such as whether the test CRASHED have not yet been - # determined. - post_test_steps = [restore_flags, restore_timeout_scale, - handle_coverage_data, handle_render_test_data, - pull_ui_screen_captures] - if self._env.concurrent_adb: - post_test_step_thread_group = reraiser_thread.ReraiserThreadGroup( - reraiser_thread.ReraiserThread(f) for f in post_test_steps) - post_test_step_thread_group.StartAll(will_block=True) - else: - for step in post_test_steps: - step() + if logcat_file.Link(): + logging.info('Logcat saved to %s', logcat_file.Link()) + + duration_ms = time_ms() - start_ms + + with contextlib_ext.Optional( + trace_event.trace('ProcessResults'), + self._env.trace_output): + output = self._test_instance.MaybeDeobfuscateLines(output) + # TODO(jbudorick): Make instrumentation tests output a JSON so this + # doesn't have to parse the output. + result_code, result_bundle, statuses = ( + self._test_instance.ParseAmInstrumentRawOutput(output)) + results = self._test_instance.GenerateTestResults( + result_code, result_bundle, statuses, start_ms, duration_ms, + device.product_cpu_abi, self._test_instance.symbolizer) + + if self._env.trace_output: + self._SaveTraceData(trace_device_file, device, test['class']) + + def restore_flags(): + if flags_to_add: + self._flag_changers[str(device)].Restore() + + def restore_timeout_scale(): + if test_timeout_scale: + valgrind_tools.SetChromeTimeoutScale( + device, self._test_instance.timeout_scale) + + def handle_coverage_data(): + if self._test_instance.coverage_directory: + device.PullFile(coverage_directory, + self._test_instance.coverage_directory) + device.RunShellCommand( + 'rm -f %s' % posixpath.join(coverage_directory, '*'), + check_return=True, shell=True) + + def handle_render_test_data(): + if _IsRenderTest(test): + # Render tests do not cause test failure by default. So we have to + # check to see if any failure images were generated even if the test + # does not fail. + try: + self._ProcessRenderTestResults( + device, render_tests_device_output_dir, results) + finally: + device.RemovePath(render_tests_device_output_dir, + recursive=True, force=True) + + def pull_ui_screen_captures(): + screenshots = [] + for filename in device.ListDirectory(ui_capture_dir.name): + if filename.endswith('.json'): + screenshots.append(pull_ui_screenshot(filename)) + if screenshots: + json_archive_name = 'ui_capture_%s_%s.json' % ( + test_name.replace('#', '.'), + time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime())) + with self._env.output_manager.ArchivedTempfile( + json_archive_name, 'ui_capture', output_manager.Datatype.JSON + ) as json_archive: + json.dump(screenshots, json_archive) + for result in results: + result.SetLink('ui screenshot', json_archive.Link()) + + def pull_ui_screenshot(filename): + source_dir = ui_capture_dir.name + json_path = posixpath.join(source_dir, filename) + json_data = json.loads(device.ReadFile(json_path)) + image_file_path = posixpath.join(source_dir, json_data['location']) + with self._env.output_manager.ArchivedTempfile( + json_data['location'], 'ui_capture', output_manager.Datatype.IMAGE + ) as image_archive: + device.PullFile(image_file_path, image_archive.name) + json_data['image_link'] = image_archive.Link() + return json_data + + # While constructing the TestResult objects, we can parallelize several + # steps that involve ADB. These steps should NOT depend on any info in + # the results! Things such as whether the test CRASHED have not yet been + # determined. + post_test_steps = [restore_flags, restore_timeout_scale, + handle_coverage_data, handle_render_test_data, + pull_ui_screen_captures] + if self._env.concurrent_adb: + post_test_step_thread_group = reraiser_thread.ReraiserThreadGroup( + reraiser_thread.ReraiserThread(f) for f in post_test_steps) + post_test_step_thread_group.StartAll(will_block=True) + else: + for step in post_test_steps: + step() for result in results: if logcat_file:
diff --git a/build/android/pylib/results/presentation/test_results_presentation.py b/build/android/pylib/results/presentation/test_results_presentation.py index 21137fe..e218dac 100755 --- a/build/android/pylib/results/presentation/test_results_presentation.py +++ b/build/android/pylib/results/presentation/test_results_presentation.py
@@ -6,7 +6,9 @@ import argparse import collections +import contextlib import json +import logging import tempfile import os import sys @@ -361,6 +363,56 @@ authenticated_link=True) +def ui_screenshot_set(json_path): + with open(json_path) as json_file: + json_object = json.loads(json_file.read()) + if not 'per_iteration_data' in json_object: + # This will be reported as an error by result_details, no need to duplicate. + return None + ui_screenshots = [] + for testsuite_run in json_object['per_iteration_data']: + for _, test_runs in testsuite_run.iteritems(): + for test_run in test_runs: + if 'ui screenshot' in test_run['links']: + screenshot_link = test_run['links']['ui screenshot'] + if screenshot_link.startswith('file:'): + with contextlib.closing(urllib.urlopen(screenshot_link)) as f: + test_screenshots = json.load(f) + else: + # Assume anything that isn't a file link is a google storage link + screenshot_string = google_storage_helper.read_from_link( + screenshot_link) + if not screenshot_string: + logging.error('Bad screenshot link %s', screenshot_link) + continue + test_screenshots = json.loads( + screenshot_string) + ui_screenshots.extend(test_screenshots) + + if ui_screenshots: + return json.dumps(ui_screenshots) + return None + + +def upload_screenshot_set(json_path, test_name, bucket, builder_name, + build_number): + screenshot_set = ui_screenshot_set(json_path) + if not screenshot_set: + return None + dest = google_storage_helper.unique_name( + 'screenshots_%s_%s_%s' % (test_name, builder_name, build_number), + suffix='.json') + with tempfile.NamedTemporaryFile(suffix='.json') as temp_file: + temp_file.write(screenshot_set) + temp_file.flush() + return google_storage_helper.upload( + name=dest, + filepath=temp_file.name, + bucket='%s/json' % bucket, + content_type='application/json', + authenticated_link=True) + + def main(): parser = argparse.ArgumentParser() parser.add_argument('--json-file', help='Path of json file.') @@ -455,16 +507,28 @@ 'Result details link do not match. The link returned by get_url_link' ' should be the same as that returned by upload.') + ui_screenshot_link = upload_screenshot_set(json_file, args.test_name, + args.bucket, builder_name, build_number) + + if args.output_json: with open(json_file) as original_json_file: json_object = json.load(original_json_file) json_object['links'] = { 'result_details (logcats, flakiness links)': result_details_link } + + if ui_screenshot_link: + json_object['links']['ui screenshots'] = ui_screenshot_link + with open(args.output_json, 'w') as f: json.dump(json_object, f) else: - print result_details_link + print 'Result Details: %s' % result_details_link + + if ui_screenshot_link: + print 'UI Screenshots %s' % ui_screenshot_link + if __name__ == '__main__': sys.exit(main())
diff --git a/build/android/pylib/utils/google_storage_helper.py b/build/android/pylib/utils/google_storage_helper.py index 55e4882..3101d71 100644 --- a/build/android/pylib/utils/google_storage_helper.py +++ b/build/android/pylib/utils/google_storage_helper.py
@@ -13,6 +13,7 @@ import os import sys import time +import urlparse from pylib.constants import host_paths from pylib.utils import decorators @@ -62,6 +63,15 @@ return get_url_link(name, bucket, authenticated_link) +@decorators.NoRaiseException(default_return_value='') +def read_from_link(link): + # Note that urlparse returns the path with an initial '/', so we only need to + # add one more after the 'gs;' + gs_path = 'gs:/%s' % urlparse.urlparse(link).path + cmd = [_GSUTIL_PATH, '-q', 'cat', gs_path] + return cmd_helper.GetCmdOutput(cmd) + + @decorators.NoRaiseException(default_return_value=False) def exists(name, bucket): bucket = _format_bucket_name(bucket)
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 97c31b8..1a8bf0f 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -937,6 +937,16 @@ results_detail_file.flush() logging.critical('TEST RESULTS: %s', results_detail_file.Link()) + ui_screenshots = test_results_presentation.ui_screenshot_set( + json_file.name) + if ui_screenshots: + with out_manager.ArchivedTempfile( + 'ui_screenshots.json', + 'ui_capture', + output_manager.Datatype.JSON) as ui_screenshot_file: + ui_screenshot_file.write(ui_screenshots) + logging.critical('UI Screenshots: %s', ui_screenshot_file.Link()) + if args.command == 'perf' and (args.steps or args.single_step): return 0
diff --git a/build/compiled_action.gni b/build/compiled_action.gni index c7fb8c65..50f9be6a 100644 --- a/build/compiled_action.gni +++ b/build/compiled_action.gni
@@ -83,6 +83,7 @@ action(target_name) { forward_variables_from(invoker, [ + "data_deps", "deps", "inputs", "outputs",
diff --git a/chrome/android/java/res/layout/signin_view.xml b/chrome/android/java/res/layout/signin_view.xml new file mode 100644 index 0000000..2aa3da8d --- /dev/null +++ b/chrome/android/java/res/layout/signin_view.xml
@@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<org.chromium.chrome.browser.signin.SigninView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:chrome="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <org.chromium.chrome.browser.signin.SigninScrollView + android:id="@+id/signin_scroll_view" + android:layout_width="match_parent" + android:layout_height="0dp" + android:fadingEdgeLength="48dp" + android:layout_weight="1" + android:requiresFadingEdge="vertical" + android:scrollbars="none"> + <!-- TODO(https://crbug.com/819142): Add the rest of the layout. --> + </org.chromium.chrome.browser.signin.SigninScrollView> + <LinearLayout + android:id="@+id/button_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="16dp"> + <!-- TODO(https://crbug.com/819142): Use textAppearance instead of text* attributes. --> + <Button + android:id="@+id/negative_button" + style="@style/ButtonCompatBorderless" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:paddingEnd="@dimen/fre_button_padding" + android:paddingStart="@dimen/fre_button_padding" + android:textAllCaps="true" + android:textColor="@color/light_active_color" + android:textSize="14sp" + tools:text="@string/no_thanks"/> + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="invisible"/> + <!-- TODO(https://crbug.com/819142): Specify WhiteBody as textAppearance. --> + <org.chromium.ui.widget.ButtonCompat + android:id="@+id/positive_button" + style="@style/WhiteBody" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:paddingEnd="@dimen/fre_button_padding" + android:paddingStart="@dimen/fre_button_padding" + android:textAllCaps="true" + chrome:buttonColor="@color/light_active_color" + chrome:buttonRaised="false" + tools:text="@string/signin_accept_button"/> + <!-- TODO(https://crbug.com/819142): Use textAppearance instead of text* attributes. --> + <Button + android:id="@+id/more_button" + style="@style/ButtonCompatBorderless" + android:layout_width="wrap_content" + android:layout_height="36dp" + android:drawableEnd="@drawable/down_arrow" + android:drawablePadding="8dp" + android:textAllCaps="true" + android:textColor="@color/light_active_color" + android:textSize="@dimen/text_size_medium" + android:visibility="gone" + tools:text="@string/more"/> + <View + android:id="@+id/positive_button_end_padding" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" + android:visibility="gone"/> + </LinearLayout> +</org.chromium.chrome.browser.signin.SigninView>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 290304a..d377cbf5 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -489,7 +489,7 @@ <dimen name="list_item_start_icon_width">36dp</dimen> <dimen name="list_item_start_icon_corner_radius">18dp</dimen> <dimen name="list_item_end_icon_width">56dp</dimen> - <dimen name="list_menu_width">140dp</dimen> + <dimen name="list_menu_width">180dp</dimen> <!-- SelectableListLayout dimensions --> <dimen name="selectable_list_layout_row_padding">16dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java index 22ed2c67..69895c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -60,7 +60,7 @@ UmaUtils.recordMainEntryPointTime(); super.attachBaseContext(context); checkAppBeingReplaced(); - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } ContextUtils.initApplicationContext(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/Origin.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/Origin.java index c871b4e9..bde31687 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/Origin.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/Origin.java
@@ -6,34 +6,62 @@ import android.net.Uri; -import org.chromium.net.GURLUtils; - /** - * A class to canonically represent a web origin in Java. It requires the native library to be - * loaded as it uses {@link GURLUtils#getOrigin}. + * A class to canonically represent a web origin in Java. It intends to mirror the behaviour of + * GURLUtils.getOrigin, but needs to work without native being loaded. */ public class Origin { - private final String mOrigin; + private static final int HTTP_DEFAULT_PORT = 80; + private static final int HTTPS_DEFAULT_PORT = 443; + + private final Uri mOrigin; /** * Constructs a canonical Origin from a String. */ public Origin(String uri) { - mOrigin = GURLUtils.getOrigin(uri); + this(Uri.parse(uri)); } /** * Constructs a canonical Origin from an Uri. */ public Origin(Uri uri) { - this(uri.toString()); + if (uri.getScheme() == null || uri.getAuthority() == null) { + mOrigin = Uri.EMPTY; + return; + } + + // Make explicit ports implicit and remove any user:password. + int port = uri.getPort(); + if (uri.getScheme().equals("http") && port == HTTP_DEFAULT_PORT) port = -1; + if (uri.getScheme().equals("https") && port == HTTPS_DEFAULT_PORT) port = -1; + + String authority = uri.getHost(); + if (port != -1) authority += ":" + port; + + Uri origin; + try { + origin = uri.normalizeScheme() + .buildUpon() + .opaquePart("") + .fragment("") + .path("/") + .encodedAuthority(authority) + .clearQuery() + .build(); + } catch (UnsupportedOperationException e) { + origin = Uri.EMPTY; + } + + mOrigin = origin; } /** - * Returns a Uri representing this Origin. + * Returns a Uri representing the Origin. */ public Uri uri() { - return Uri.parse(mOrigin); + return mOrigin; } @Override @@ -41,9 +69,12 @@ return mOrigin.hashCode(); } + /** + * Returns a String representing the Origin. + */ @Override public String toString() { - return mOrigin; + return mOrigin.toString(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java index 94a589a..e2c3edc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java
@@ -9,13 +9,14 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; +import java.util.ArrayList; + /** * Layout that displays all normal tabs in one stack and all incognito tabs in a second. */ @@ -36,22 +37,15 @@ */ public StackLayout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost) { super(context, updateHost, renderHost); - - for (int i = 0; i < NUM_STACKS; i++) { - mStacks.add(new Stack(context, this)); - } } @Override public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) { super.setTabModelSelector(modelSelector, manager); - mStacks.get(NORMAL_STACK_INDEX).setTabList(modelSelector.getModel(false)); - mStacks.get(INCOGNITO_STACK_INDEX).setTabList(modelSelector.getModel(true)); - } - - @Override - protected TabList getTabList(int index) { - return mTabModelSelector.getModel(index == INCOGNITO_STACK_INDEX); + ArrayList<TabList> tabLists = new ArrayList<TabList>(); + tabLists.add(modelSelector.getModel(false)); + tabLists.add(modelSelector.getModel(true)); + setTabLists(tabLists); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java index 1166d9d..19f08a17 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java
@@ -49,6 +49,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.List; /** * Base class for layouts that show one or more stacks of tabs. @@ -96,7 +97,7 @@ */ private static final float SWITCH_STACK_FLING_DT = 1.0f / 30.0f; - /** The array of potentially visible stacks. */ + /** The list of potentially visible stacks. */ protected final ArrayList<Stack> mStacks; /** Rectangles that defines the area where each stack need to be laid out. */ @@ -129,6 +130,10 @@ private float mLastOnDownY; private long mLastOnDownTimeStamp; + private float mWidth; + private float mHeight; + private int mOrientation; + // Pre-allocated temporary arrays that store id of visible tabs. // They can be used to call populatePriorityVisibilityList. // We use StackTab[] instead of ArrayList<StackTab> because the sorting function does @@ -223,6 +228,7 @@ } else { final int newStackIndex = getTabStackIndex() + stackIndexDeltaAt; if (newStackIndex < 0 || newStackIndex >= mStacks.size()) return; + if (!mStacks.get(newStackIndex).isDisplayable()) return; flingStacks(newStackIndex); } requestStackUpdate(); @@ -310,6 +316,28 @@ mSceneLayer = new TabListSceneLayer(); } + /** + * Updates this layout to show one tab stack for each of the passed-in TabLists. Takes a + * reference to the lists param and expects it not to change. + * @param lists The list of TabLists to use. + */ + protected void setTabLists(List<TabList> lists) { + if (mStacks.size() > lists.size()) { + mStacks.subList(lists.size(), lists.size()).clear(); + } + while (mStacks.size() < lists.size()) { + Stack stack = new Stack(getContext(), this); + stack.notifySizeChanged(mWidth, mHeight, mOrientation); + mStacks.add(stack); + } + + for (int i = 0; i < lists.size(); i++) { + mStacks.get(i).setTabList(lists.get(i)); + } + + // mStackRects will get updated in updateLayout() + } + @Override public boolean forceShowBrowserControlsAndroidView() { return true; @@ -352,8 +380,6 @@ resetScrollData(); } - protected abstract TabList getTabList(int index); - /** * Get the tab stack at the specified index. * @@ -728,6 +754,9 @@ @Override public void notifySizeChanged(float width, float height, int orientation) { + mWidth = width; + mHeight = height; + mOrientation = orientation; mCachedLandscapeViewport = null; mCachedPortraitViewport = null; for (Stack stack : mStacks) { @@ -1089,7 +1118,8 @@ final float stackFocus = MathUtils.clamp(1 - scrollDistance, 0, 1); mStacks.get(i).setStackFocusInfo(stackFocus, - mSortingComparator == mOrderComparator ? getTabList(i).index() : -1); + mSortingComparator == mOrderComparator ? mStacks.get(i).getTabList().index() + : -1); } // Compute position and visibility
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java index 7a79709..76b5beb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -19,7 +19,7 @@ import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; -import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; +import org.chromium.chrome.browser.compositor.layouts.phone.StackLayoutBase; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabList; @@ -231,7 +231,7 @@ private Animator mViewAnimations; // The parent Layout - private final StackLayout mLayout; + private final StackLayoutBase mLayout; // Border values private float mBorderTransparentTop; @@ -257,7 +257,7 @@ /** * @param layout The parent layout. */ - public Stack(Context context, StackLayout layout) { + public Stack(Context context, StackLayoutBase layout) { mLayout = layout; contextChanged(context); } @@ -270,6 +270,13 @@ } /** + * @return The TabList associated with this stack. + */ + public TabList getTabList() { + return mTabList; + } + + /** * @return The {@link StackTab}s currently being rendered by the tab stack. * @VisibleForTesting */ @@ -2273,7 +2280,7 @@ */ public float getMaxTabHeight() { if (FeatureUtilities.isChromeHomeEnabled() && mCurrentMode == Orientation.PORTRAIT) { - return mLayout.getHeightMinusBrowserControls() - StackLayout.MODERN_TOP_MARGIN_DP; + return mLayout.getHeightMinusBrowserControls() - StackLayoutBase.MODERN_TOP_MARGIN_DP; } return mLayout.getHeightMinusBrowserControls(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index e85c510..9a0953a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -1586,6 +1586,7 @@ // Set up the next batch of Ranker logging. mTapSuppressionRankerLogger.setupLoggingForPage(getBaseWebContents()); mSearchPanel.getPanelMetrics().setRankerLogger(mTapSuppressionRankerLogger); + ContextualSearchUma.logRankerFeaturesAvailable(false); mInternalStateController.notifyFinishedWorkOn(InternalState.TAP_GESTURE_COMMIT); } @@ -1674,6 +1675,7 @@ public void showContextualSearchTapUi() { mInternalStateController.notifyStartingWorkOn(InternalState.SHOW_FULL_TAP_UI); showContextualSearch(StateChangeReason.TEXT_SELECT_TAP); + ContextualSearchUma.logRankerFeaturesAvailable(true); mInternalStateController.notifyFinishedWorkOn(InternalState.SHOW_FULL_TAP_UI); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java index 5d7e8d06..5153513 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java
@@ -1344,6 +1344,17 @@ } /** + * Logs that features or outcomes are available to record to Ranker. + * This data can be used to correlate with #logRecordedToRanker to validate that everything that + * should be recorded is actually being recorded. + * @param areOutcomes Whether the features available are outcomes. + */ + static void logRankerFeaturesAvailable(boolean areOutcomes) { + RecordHistogram.recordBooleanHistogram( + "Search.ContextualSearch.Ranker.eaturesAvailable", areOutcomes); + } + + /** * Gets the state-change code for the given parameters by doing a lookup in the given map. * @param state The panel state. * @param reason The reason the state changed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 4b3b83fca..17db3c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -523,7 +523,7 @@ * @param callback A callback that will be called once operation is completed. */ public void deletePagesByClientIdAndOrigin( - List<ClientId> clientIds, String origin, Callback<Integer> callback) { + List<ClientId> clientIds, OfflinePageOrigin origin, Callback<Integer> callback) { String[] namespaces = new String[clientIds.size()]; String[] ids = new String[clientIds.size()]; @@ -533,7 +533,7 @@ } nativeDeletePagesByClientIdAndOrigin( - mNativeOfflinePageBridge, namespaces, ids, origin, callback); + mNativeOfflinePageBridge, namespaces, ids, origin.encodeAsJsonString(), callback); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOrigin.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOrigin.java index 0eaf009..c6f7d1ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOrigin.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageOrigin.java
@@ -141,6 +141,25 @@ return mAppName; } + @Override + public String toString() { + return encodeAsJsonString(); + } + + @Override + public boolean equals(Object other) { + if (other != null && other instanceof OfflinePageOrigin) { + OfflinePageOrigin o = (OfflinePageOrigin) other; + return mAppName.equals(o.mAppName) && Arrays.equals(mSignatures, o.mSignatures); + } + return false; + } + + @Override + public int hashCode() { + return Arrays.deepHashCode(new Object[] {mAppName, mSignatures}); + } + /** * @param context The context to look up signatures. * @param appName The name of the application to look up.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java index c08ebc3..5b6a273 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
@@ -759,6 +759,9 @@ if (mSearchQuery == null) { // If not searching, the category needs to be removed again. getPreferenceScreen().removePreference(passwordParent); + } else { + getView().announceForAccessibility( + getResources().getText(R.string.accessible_find_in_page_no_results)); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java index 0b10502..666e177 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java
@@ -70,7 +70,7 @@ final Intent intent; if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) { - intent = SigninActivity.createIntent(context, accessPoint, false); + intent = SigninActivity.createIntent(context, accessPoint); } else { intent = createIntentForDefaultSigninFlow(context, accessPoint, false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java index 6649ce8..44cf0b5a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninActivity.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.signin; +import android.app.Fragment; +import android.app.FragmentManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -24,14 +26,11 @@ /** * Creates an {@link Intent} which can be used to start the signin flow. * @param accessPoint {@link AccessPoint} for starting signin flow. Used in metrics. - * @param isFromPersonalizedPromo Whether the signin activity is started from a personalized - * promo. */ - public static Intent createIntent(Context context, - @AccountSigninActivity.AccessPoint int accessPoint, boolean isFromPersonalizedPromo) { + public static Intent createIntent( + Context context, @AccountSigninActivity.AccessPoint int accessPoint) { Intent intent = new Intent(context, SigninActivity.class); - // TODO(https://crbug.com/814728): Call SigninFragment.createArguments. - Bundle fragmentArguments = new Bundle(); + Bundle fragmentArguments = SigninFragment.createArguments(accessPoint); intent.putExtras(fragmentArguments); return intent; } @@ -52,6 +51,12 @@ super.onCreate(savedInstanceState); setContentView(R.layout.signin_activity); - // TODO(https://crbug.com/814728): Add SigninFragment. + FragmentManager fragmentManager = getFragmentManager(); + Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container); + if (fragment == null) { + fragment = new SigninFragment(); + fragment.setArguments(getIntent().getExtras()); + fragmentManager.beginTransaction().add(R.id.fragment_container, fragment).commit(); + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java new file mode 100644 index 0000000..a5356b1 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -0,0 +1,180 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.signin; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; +import org.chromium.chrome.browser.preferences.PreferencesLauncher; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** This fragment implements sign-in screen for {@link SigninActivity}. */ +public class SigninFragment extends SigninFragmentBase { + private static final String TAG = "SigninFragment"; + + private static final String ARGUMENT_PERSONALIZED_PROMO_ACTION = + "SigninFragment.PersonalizedPromoAction"; + + @IntDef({PROMO_ACTION_NONE, PROMO_ACTION_WITH_DEFAULT, PROMO_ACTION_NOT_DEFAULT, + PROMO_ACTION_NEW_ACCOUNT}) + @Retention(RetentionPolicy.SOURCE) + public @interface PromoAction {} + + public static final int PROMO_ACTION_NONE = 0; + public static final int PROMO_ACTION_WITH_DEFAULT = 1; + public static final int PROMO_ACTION_NOT_DEFAULT = 2; + public static final int PROMO_ACTION_NEW_ACCOUNT = 3; + + private @PromoAction int mPromoAction; + + /** + * Creates an argument bundle to start signin. + * @param accessPoint The access point for starting signin flow. + */ + public static Bundle createArguments(@SigninAccessPoint int accessPoint) { + return SigninFragmentBase.createArguments(accessPoint); + } + + /** + * Creates an argument bundle to start signin from personalized signin promo. + * @param accessPoint The access point for starting signin flow. + * @param promoAction Promo action that was used to start signin. Used for UMA. + */ + public static Bundle createArgumentsFromPersonalizedPromo( + @SigninAccessPoint int accessPoint, @PromoAction int promoAction) { + Bundle result = SigninFragmentBase.createArguments(accessPoint); + result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, promoAction); + return result; + } + + // Every fragment must have a public default constructor. + public SigninFragment() {} + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPromoAction = + getSigninArguments().getInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PROMO_ACTION_NONE); + + SigninManager.logSigninStartAccessPoint(getSigninAccessPoint()); + recordSigninStartedHistogramAccountInfo(); + recordSigninStartedUserAction(); + } + + @Override + protected Bundle getSigninArguments() { + return getArguments(); + } + + @Override + protected void onSigninRefused() { + getActivity().finish(); + } + + @Override + protected void onSigninAccepted( + String accountName, boolean isDefaultAccount, boolean settingsClicked) { + if (PrefServiceBridge.getInstance().getSyncLastAccountName() != null) { + AccountSigninActivity.recordSwitchAccountSourceHistogram( + AccountSigninActivity.SwitchAccountSource.SIGNOUT_SIGNIN); + } + + SigninManager.get().signIn(accountName, getActivity(), new SigninManager.SignInCallback() { + @Override + public void onSignInComplete() { + if (settingsClicked) { + Intent intent = PreferencesLauncher.createIntentForSettingsPage( + getActivity(), AccountManagementFragment.class.getName()); + startActivity(intent); + } + + recordSigninCompletedHistogramAccountInfo(); + getActivity().finish(); + } + + @Override + public void onSignInAborted() {} + }); + } + + private void recordSigninCompletedHistogramAccountInfo() { + final String histogram; + switch (mPromoAction) { + case PROMO_ACTION_NONE: + return; + case PROMO_ACTION_WITH_DEFAULT: + histogram = "Signin.SigninCompletedAccessPoint.WithDefault"; + break; + case PROMO_ACTION_NOT_DEFAULT: + histogram = "Signin.SigninCompletedAccessPoint.NotDefault"; + break; + case PROMO_ACTION_NEW_ACCOUNT: + histogram = "Signin.SigninCompletedAccessPoint.NewAccount"; + break; + default: + assert false : "Unexpected signin flow type!"; + return; + } + + RecordHistogram.recordEnumeratedHistogram( + histogram, getSigninAccessPoint(), SigninAccessPoint.MAX); + } + + private void recordSigninStartedHistogramAccountInfo() { + final String histogram; + switch (mPromoAction) { + case PROMO_ACTION_NONE: + return; + case PROMO_ACTION_WITH_DEFAULT: + histogram = "Signin.SigninStartedAccessPoint.WithDefault"; + break; + case PROMO_ACTION_NOT_DEFAULT: + histogram = "Signin.SigninStartedAccessPoint.NotDefault"; + break; + case PROMO_ACTION_NEW_ACCOUNT: + histogram = "Signin.SigninStartedAccessPoint.NewAccount"; + break; + default: + assert false : "Unexpected signin flow type!"; + return; + } + + RecordHistogram.recordEnumeratedHistogram( + histogram, getSigninAccessPoint(), SigninAccessPoint.MAX); + } + + private void recordSigninStartedUserAction() { + switch (getSigninAccessPoint()) { + case SigninAccessPoint.AUTOFILL_DROPDOWN: + RecordUserAction.record("Signin_Signin_FromAutofillDropdown"); + break; + case SigninAccessPoint.BOOKMARK_MANAGER: + RecordUserAction.record("Signin_Signin_FromBookmarkManager"); + break; + case SigninAccessPoint.RECENT_TABS: + RecordUserAction.record("Signin_Signin_FromRecentTabs"); + break; + case SigninAccessPoint.SETTINGS: + RecordUserAction.record("Signin_Signin_FromSettings"); + break; + case SigninAccessPoint.SIGNIN_PROMO: + RecordUserAction.record("Signin_Signin_FromSigninPromo"); + break; + case SigninAccessPoint.NTP_CONTENT_SUGGESTIONS: + RecordUserAction.record("Signin_Signin_FromNTPContentSuggestions"); + break; + default: + assert false : "Invalid access point."; + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java new file mode 100644 index 0000000..bd7e125 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
@@ -0,0 +1,124 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.signin; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.R; + +/** + * This fragment implements sign-in screen with account picker and descriptions of signin-related + * features. Configuration for this fragment is provided by overriding {@link #getSigninArguments} + * derived classes. + */ +public abstract class SigninFragmentBase extends Fragment { + private static final String TAG = "SigninFragmentBase"; + + private static final String ARGUMENT_ACCESS_POINT = "SigninFragmentBase.AccessPoint"; + + private @SigninAccessPoint int mSigninAccessPoint; + + private SigninView mView; + private @StringRes int mCancelButtonTextId = R.string.cancel; + + /** + * Creates an argument bundle to start AccountSigninView from the account selection page. + * @param accessPoint The access point for starting signin flow. + */ + protected static Bundle createArguments(@SigninAccessPoint int accessPoint) { + Bundle result = new Bundle(); + result.putInt(ARGUMENT_ACCESS_POINT, accessPoint); + return result; + } + + /** + * This method should return arguments Bundle that contains arguments created by + * {@link #createArguments} and related methods. + */ + protected abstract Bundle getSigninArguments(); + + /** The sign-in was refused. */ + protected abstract void onSigninRefused(); + + /** + * The sign-in was accepted. + * @param accountName The name of the account + * @param isDefaultAccount Whether selected account is a default one (first of all accounts) + * @param settingsClicked Whether the user requested to see their sync settings + */ + protected abstract void onSigninAccepted( + String accountName, boolean isDefaultAccount, boolean settingsClicked); + + /** Returns the access point that initiated the sign-in flow. */ + protected @SigninAccessPoint int getSigninAccessPoint() { + return mSigninAccessPoint; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle arguments = getSigninArguments(); + initAccessPoint(arguments.getInt(ARGUMENT_ACCESS_POINT, -1)); + } + + private void initAccessPoint(@SigninAccessPoint int accessPoint) { + assert accessPoint == SigninAccessPoint.AUTOFILL_DROPDOWN + || accessPoint == SigninAccessPoint.BOOKMARK_MANAGER + || accessPoint == SigninAccessPoint.NTP_CONTENT_SUGGESTIONS + || accessPoint == SigninAccessPoint.RECENT_TABS + || accessPoint == SigninAccessPoint.SETTINGS + || accessPoint == SigninAccessPoint.SIGNIN_PROMO + || accessPoint + == SigninAccessPoint.START_PAGE : "invalid access point: " + accessPoint; + + mSigninAccessPoint = accessPoint; + if (accessPoint == SigninAccessPoint.START_PAGE + || accessPoint == SigninAccessPoint.SIGNIN_PROMO) { + mCancelButtonTextId = R.string.no_thanks; + } + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mView = (SigninView) inflater.inflate(R.layout.signin_view, container, false); + mView.getAcceptButton().setVisibility(View.GONE); + mView.getMoreButton().setVisibility(View.VISIBLE); + mView.getMoreButton().setOnClickListener(view -> { + mView.getScrollView().smoothScrollBy(0, mView.getScrollView().getHeight()); + // TODO(https://crbug.com/821127): Revise this user action. + RecordUserAction.record("Signin_MoreButton_Shown"); + }); + mView.getScrollView().setScrolledToBottomObserver(this::showAcceptButton); + + mView.getRefuseButton().setOnClickListener(view -> { + setButtonsEnabled(false); + onSigninRefused(); + }); + + // TODO(https://crbug.com/814728): Set texts for UI elements + + return mView; + } + + private void showAcceptButton() { + mView.getAcceptButton().setVisibility(View.VISIBLE); + mView.getMoreButton().setVisibility(View.GONE); + mView.getScrollView().setScrolledToBottomObserver(null); + } + + private void setButtonsEnabled(boolean enabled) { + mView.getAcceptButton().setEnabled(enabled); + mView.getRefuseButton().setEnabled(enabled); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninScrollView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninScrollView.java new file mode 100644 index 0000000..8dd4108 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninScrollView.java
@@ -0,0 +1,70 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.signin; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.ViewTreeObserver; +import android.widget.ScrollView; + +/** + * ScrollView without the top edge that also sends notification when it is scrolled to the bottom. + */ +public class SigninScrollView extends ScrollView { + private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener = + this::checkScrolledToBottom; + private final ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener = + this::checkScrolledToBottom; + private @Nullable Runnable mObserver; + + public SigninScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected float getTopFadingEdgeStrength() { + // Disable fading out effect at the top of this ScrollView. + return 0; + } + + @Override + protected void onDetachedFromWindow() { + removeObserver(); + super.onDetachedFromWindow(); + } + + private void checkScrolledToBottom() { + if (mObserver == null) return; + if (getChildCount() == 0) { + // The ScrollView is definitely scrolled to bottom if there are no children. + mObserver.run(); + return; + } + if ((getHeight() + getScrollY()) < getChildAt(getChildCount() - 1).getBottom()) return; + mObserver.run(); + } + + /** + * Sets observer. Regardless of the passed value, notifications for the previous observer will + * be canceled. + * @param observer The Runnable to receive notification when SigninScrollView is scrolled to + * bottom, or null to clear the observer. + */ + public void setScrolledToBottomObserver(@Nullable Runnable observer) { + removeObserver(); + if (observer == null) return; + mObserver = observer; + getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); + getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener); + } + + private void removeObserver() { + if (mObserver == null) return; + mObserver = null; + getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener); + getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninView.java new file mode 100644 index 0000000..39a2560 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninView.java
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.signin; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; + +import org.chromium.chrome.R; +import org.chromium.ui.widget.ButtonCompat; + +/** View that wraps signin screen and caches references to UI elements. */ +public class SigninView extends LinearLayout { + private SigninScrollView mScrollView; + private ButtonCompat mAcceptButton; + private Button mRefuseButton; + private Button mMoreButton; + private View mAcceptButtonEndPadding; + + public SigninView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + mScrollView = (SigninScrollView) findViewById(R.id.signin_scroll_view); + mAcceptButton = (ButtonCompat) findViewById(R.id.positive_button); + mRefuseButton = (Button) findViewById(R.id.negative_button); + mMoreButton = (Button) findViewById(R.id.more_button); + mAcceptButtonEndPadding = findViewById(R.id.positive_button_end_padding); + } + + public SigninScrollView getScrollView() { + return mScrollView; + } + + public ButtonCompat getAcceptButton() { + return mAcceptButton; + } + + public Button getRefuseButton() { + return mRefuseButton; + } + + public Button getMoreButton() { + return mMoreButton; + } + + public View getAcceptButtonEndPadding() { + return mAcceptButtonEndPadding; + } +}
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 5173a30..dbd3fa0 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
@@ -751,10 +751,10 @@ } if (mNativeTabAndroid == 0) { - // if mNativeTabAndroid is invalid then we are going to crash anyways on the + // if mNativeTabAndroid is null then we are going to crash anyways on the // native side. Lets crash on the java side so that we can have a better stack - // trace. https://crbug.com/662877 - throw new RuntimeException("Please post this crash on crbug.com/662877"); + // trace. + throw new RuntimeException("Tab.loadUrl called when no native side exists"); } // We load the URL from the tab rather than directly from the ContentView so the tab has
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index bdfb4f2..e26c75e 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2296,7 +2296,13 @@ Waiting for Google Play Services to finish updating </message> - <!-- New Signin Promos Strings --> + <!-- Strings for Streamlined Signin and Unified Consent. --> + <!-- TODO(https://crbug.com/814728): Make translatable when strings are approved. --> + <message name="IDS_SIGNIN_ACCEPT_BUTTON" desc="Text for the confirmation button in the sign-in screen. By clicking this button users signs in and turns on Sync and personalization. [CHAR-LIMIT=20]" translateable="false"> + Yes, I'm in + </message> + + <!-- Personalized Signin Promos Strings --> <message name="IDS_SIGNIN_PROMO_DESCRIPTION_BOOKMARKS" desc="Description string for 'Continue as' signin promo shown in Bookmarks screen."> To get your bookmarks on all your devices, sign in to Chrome. </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 65cfd69..95eba2cba 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1113,11 +1113,15 @@ "java/src/org/chromium/chrome/browser/signin/ProfileDataCache.java", "java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java", "java/src/org/chromium/chrome/browser/signin/SigninActivity.java", + "java/src/org/chromium/chrome/browser/signin/SigninFragment.java", + "java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java", "java/src/org/chromium/chrome/browser/signin/SigninHelper.java", "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java", "java/src/org/chromium/chrome/browser/signin/SigninManager.java", "java/src/org/chromium/chrome/browser/signin/SigninPromoController.java", "java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java", + "java/src/org/chromium/chrome/browser/signin/SigninScrollView.java", + "java/src/org/chromium/chrome/browser/signin/SigninView.java", "java/src/org/chromium/chrome/browser/signin/SyncPromoView.java", "java/src/org/chromium/chrome/browser/snackbar/BottomContainer.java", "java/src/org/chromium/chrome/browser/snackbar/DataReductionPromoSnackbarController.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginTest.java index 6fdaf073..f36ce37 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginTest.java
@@ -29,11 +29,48 @@ mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess(); } - /** - * The actual conversion from a free form URL to an Origin is done in native and that is - * thoroughly tested there. Here we only check that the transformation is performed, not that - * it is complete and correct. - */ + @Test + @SmallTest + public void testTransformation() { + Assert.assertEquals(Uri.parse("http://example.com:123/").getPort(), 123); + + // Unlike origin.cc, the returned Uri has a port of -1 if it is the default port for the + // scheme. + check("http://192.168.9.1/", "http", "192.168.9.1", -1); + + // Test cases for origin.cc that do *not* work with Origin.java: + + // check("http://[2001:db8::1]/", "http", "[2001:db8::1]", 80); + // This is because Uri cannot deal with IPv6 URLS, eg: + // Uri.parse("http://[2001:db8::1]/").getHost() returns "[2001" + + // check("http://☃.net/", "http", "xn--n3h.net", 80); + // check("blob:http://☃.net/", "http", "xn--n3h.net", 80); + // We don't perform punycode substitution so the string is unchanged. + + check("http://example.com/", "http", "example.com", -1); + check("http://example.com:123/", "http", "example.com", 123); + check("https://example.com/", "https", "example.com", -1); + check("https://example.com:123/", "https", "example.com", 123); + check("http://user:pass@example.com/", "http", "example.com", -1); + check("http://example.com:123/?query", "http", "example.com", 123); + check("https://example.com/#1234", "https", "example.com", -1); + check("https://u:p@example.com:123/?query#1234", "https", "example.com", 123); + } + + private static void check(String url, String scheme, String host, int port) { + Origin origin = new Origin(url); + Assert.assertEquals(scheme, origin.uri().getScheme()); + Assert.assertEquals(host, origin.uri().getHost()); + Assert.assertEquals(port, origin.uri().getPort()); + + if (port == -1) { + Assert.assertEquals(origin.toString(), scheme + "://" + host + "/"); + } else { + Assert.assertEquals(origin.toString(), scheme + "://" + host + ":" + port + "/"); + } + } + @Test @SmallTest public void testConstruction() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java index 4382b7c..878de8b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java
@@ -10,6 +10,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.annotation.SuppressLint; import android.app.Instrumentation; import android.content.res.Configuration; import android.graphics.Point; @@ -93,6 +94,7 @@ * } * </pre> */ +@SuppressLint("SetWorldReadable") public class ScreenShooter extends TestWatcher { private static final String SCREENSHOT_DIR = "org.chromium.base.test.util.Screenshooter.ScreenshotDir"; @@ -204,6 +206,9 @@ File shotFile = File.createTempFile(shotName, IMAGE_SUFFIX, new File(mBaseDir)); assertTrue("Screenshot " + shotName, mDevice.takeScreenshot(shotFile)); writeImageDescription(shotFile, filters, tags, metadata); + // Set as world readable so that the test runner can read it from /data/local/tmp + // without having to run as root + shotFile.setReadable(true, false); } catch (IOException e) { fail("Cannot create shot files " + e.toString()); } @@ -231,8 +236,12 @@ String jsonFileName = shotFileName.substring(0, shotFileName.length() - IMAGE_SUFFIX.length()) + JSON_SUFFIX; - try (FileWriter fileWriter = new FileWriter(new File(mBaseDir, jsonFileName));) { + File descriptionFile = new File(mBaseDir, jsonFileName); + try (FileWriter fileWriter = new FileWriter(descriptionFile)) { fileWriter.write(imageDescription.toString()); } + // Set as world readable so that the test runner can read it from /data/local/tmp without + // having to run as root + descriptionFile.setReadable(true, false); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageOriginUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageOriginUnitTest.java index a80234c..ad4b5ee 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageOriginUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageOriginUnitTest.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.offlinepages; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,4 +26,25 @@ assertEquals("[\"abc.xyz\",[\"deadbeef\",\"00c0ffee\"]]", origin.encodeAsJsonString()); } + + @Test + public void testEquals() { + String appName = "abc.xyz"; + String[] signature1 = new String[] {"deadbeef", "00c0ffee"}; + String[] signature2 = new String[] {"deadbeef", "fooba499"}; + OfflinePageOrigin origin1 = new OfflinePageOrigin(appName, signature1); + OfflinePageOrigin origin2 = new OfflinePageOrigin(appName, signature2); + OfflinePageOrigin origin3 = new OfflinePageOrigin("", signature1); + OfflinePageOrigin origin4 = new OfflinePageOrigin(appName, signature1); + + assertFalse("Equivalent to null", origin1.equals(null)); + assertTrue("Not equivalent to self", origin1.equals(origin1)); + assertFalse("Equivalent when signatures not equal", origin1.equals(origin2)); + assertFalse("Equivalent when name not equal", origin1.equals(origin3)); + assertTrue("Equally created items not equal", origin1.equals(origin4)); + + assertEquals("HashCode not equal to self", origin1.hashCode(), origin1.hashCode()); + assertEquals( + "HashCode not equal when items are equal", origin1.hashCode(), origin4.hashCode()); + } }
diff --git a/chrome/app/vector_icons/account_box.icon b/chrome/app/vector_icons/account_box.icon index 089dccf..e6806d8 100644 --- a/chrome/app/vector_icons/account_box.icon +++ b/chrome/app/vector_icons/account_box.icon
@@ -24,5 +24,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 12, R_V_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/account_child.icon b/chrome/app/vector_icons/account_child.icon index 0b8e989f..db3f809 100644 --- a/chrome/app/vector_icons/account_child.icon +++ b/chrome/app/vector_icons/account_child.icon
@@ -21,4 +21,3 @@ V_LINE_TO, 25.23f, CUBIC_TO, 37, 21.12f, 30.16f, 18, 24, 18, CLOSE, -END,
diff --git a/chrome/app/vector_icons/account_child_circle.icon b/chrome/app/vector_icons/account_child_circle.icon index f4ff64e..4ce7f60 100644 --- a/chrome/app/vector_icons/account_child_circle.icon +++ b/chrome/app/vector_icons/account_child_circle.icon
@@ -32,5 +32,4 @@ CUBIC_TO, 7, 11.2f, 9.63f, 10, 12, 10, R_CUBIC_TO, 2.37f, 0, 5, 1.2f, 5, 2.78f, R_V_LINE_TO, 4.44f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/account_circle.icon b/chrome/app/vector_icons/account_circle.icon index 2774de46..07bf0c78 100644 --- a/chrome/app/vector_icons/account_circle.icon +++ b/chrome/app/vector_icons/account_circle.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0.03f, -1.99f, 4, -3.08f, 6, -3.08f, R_CUBIC_TO, 1.99f, 0, 5.97f, 1.09f, 6, 3.08f, R_CUBIC_TO, -1.29f, 1.94f, -3.5f, 3.22f, -6, 3.22f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/add.icon b/chrome/app/vector_icons/add.icon index f2c69854..73829f6 100644 --- a/chrome/app/vector_icons/add.icon +++ b/chrome/app/vector_icons/add.icon
@@ -8,5 +8,4 @@ MOVE_TO, 3, 8, R_H_LINE_TO, 10, MOVE_TO, 8, 3, -R_V_LINE_TO, 10, -END +R_V_LINE_TO, 10
diff --git a/chrome/app/vector_icons/ads.icon b/chrome/app/vector_icons/ads.icon index 36effc4..8f03cd6 100644 --- a/chrome/app/vector_icons/ads.icon +++ b/chrome/app/vector_icons/ads.icon
@@ -18,5 +18,4 @@ V_LINE_TO, 6, R_H_LINE_TO, 8, R_V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/apps.icon b/chrome/app/vector_icons/apps.icon index f70955f..b7cdbe6c 100644 --- a/chrome/app/vector_icons/apps.icon +++ b/chrome/app/vector_icons/apps.icon
@@ -55,5 +55,4 @@ R_V_LINE_TO, -8, R_H_LINE_TO, -8, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/back_arrow_touch.icon b/chrome/app/vector_icons/back_arrow_touch.icon index 974a7c83..59a516d 100644 --- a/chrome/app/vector_icons/back_arrow_touch.icon +++ b/chrome/app/vector_icons/back_arrow_touch.icon
@@ -22,5 +22,4 @@ R_LINE_TO, 0.09f, -0.09f, R_ARC_TO, 1, 1, 0, 0, 0, 1.32f, -1.32f, R_V_LINE_TO, 0, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/blocked_badge.icon b/chrome/app/vector_icons/blocked_badge.icon index 687be0dec..a621f1d 100644 --- a/chrome/app/vector_icons/blocked_badge.icon +++ b/chrome/app/vector_icons/blocked_badge.icon
@@ -41,5 +41,4 @@ LINE_TO, 28, 23.2f, CUBIC_TO, 28.34f, 22.87f, 28.34f, 22.33f, 28, 22, CUBIC_TO, 27.67f, 21.66f, 27.13f, 21.66f, 26.8f, 22, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/blocked_redirect.icon b/chrome/app/vector_icons/blocked_redirect.icon index 6b0e37f..f9e1633 100644 --- a/chrome/app/vector_icons/blocked_redirect.icon +++ b/chrome/app/vector_icons/blocked_redirect.icon
@@ -28,5 +28,4 @@ LINE_TO, 2, 9, LINE_TO, 5, 9, LINE_TO, 5, 11, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/bookmarkbar_touch_overflow.icon b/chrome/app/vector_icons/bookmarkbar_touch_overflow.icon index 254ad43..f493ed8 100644 --- a/chrome/app/vector_icons/bookmarkbar_touch_overflow.icon +++ b/chrome/app/vector_icons/bookmarkbar_touch_overflow.icon
@@ -9,5 +9,4 @@ LINE_TO, 9.52f, 6, LINE_TO, 16, 12, LINE_TO, 9.52f, 18, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools.1x.icon b/chrome/app/vector_icons/browser_tools.1x.icon index ff2750374..7115751 100644 --- a/chrome/app/vector_icons/browser_tools.1x.icon +++ b/chrome/app/vector_icons/browser_tools.1x.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 9.33f, 12, 10, 12.67f, 10, 13.5f, CUBIC_TO, 10, 14.33f, 9.33f, 15, 8.5f, 15, CUBIC_TO, 7.67f, 15, 7, 14.33f, 7, 13.5f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools.icon b/chrome/app/vector_icons/browser_tools.icon index fcda251..6fd494e 100644 --- a/chrome/app/vector_icons/browser_tools.icon +++ b/chrome/app/vector_icons/browser_tools.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 19, 24.34f, 17.66f, 23, 16, 23, CUBIC_TO, 14.34f, 23, 13, 24.34f, 13, 26, CUBIC_TO, 13, 27.66f, 14.34f, 29, 16, 29, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_animated.1x.icon b/chrome/app/vector_icons/browser_tools_animated.1x.icon index 01566f2..5897c1c 100644 --- a/chrome/app/vector_icons/browser_tools_animated.1x.icon +++ b/chrome/app/vector_icons/browser_tools_animated.1x.icon
@@ -103,5 +103,4 @@ CUBIC_TO, 7.67f, 15, 7, 14.33f, 7, 13.5f, TRANSITION_END, 283, 400, gfx::Tween::FAST_OUT_SLOW_IN, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_animated.icon b/chrome/app/vector_icons/browser_tools_animated.icon index ba7adb98..89af1169 100644 --- a/chrome/app/vector_icons/browser_tools_animated.icon +++ b/chrome/app/vector_icons/browser_tools_animated.icon
@@ -95,4 +95,3 @@ TRANSITION_END, 283, 400, gfx::Tween::FAST_OUT_SLOW_IN, CLOSE, -END,
diff --git a/chrome/app/vector_icons/browser_tools_error.icon b/chrome/app/vector_icons/browser_tools_error.icon index 8c04ff10..c1c66a5 100644 --- a/chrome/app/vector_icons/browser_tools_error.icon +++ b/chrome/app/vector_icons/browser_tools_error.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, -2, R_H_LINE_TO, 2, R_V_LINE_TO, 2, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_error_touch.icon b/chrome/app/vector_icons/browser_tools_error_touch.icon index 2ae9ce0c..2283d82a 100644 --- a/chrome/app/vector_icons/browser_tools_error_touch.icon +++ b/chrome/app/vector_icons/browser_tools_error_touch.icon
@@ -25,5 +25,4 @@ R_H_LINE_TO, 24, R_V_LINE_TO, 24, H_LINE_TO, 0, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_touch.icon b/chrome/app/vector_icons/browser_tools_touch.icon index 8e92a38..4d28e31 100644 --- a/chrome/app/vector_icons/browser_tools_touch.icon +++ b/chrome/app/vector_icons/browser_tools_touch.icon
@@ -14,5 +14,4 @@ R_MOVE_TO, 0, 6, R_ARC_TO, 2, 2, 0, 1, 0, 0, 4, R_ARC_TO, 2, 2, 0, 0, 0, 0, -4, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_update.icon b/chrome/app/vector_icons/browser_tools_update.icon index 9747c147..c93b4d8d 100644 --- a/chrome/app/vector_icons/browser_tools_update.icon +++ b/chrome/app/vector_icons/browser_tools_update.icon
@@ -15,5 +15,4 @@ LINE_TO, 4, 9, R_H_LINE_TO, 2, R_V_LINE_TO, 3, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/browser_tools_update_touch.icon b/chrome/app/vector_icons/browser_tools_update_touch.icon index b3a8b9c..65640d0 100644 --- a/chrome/app/vector_icons/browser_tools_update_touch.icon +++ b/chrome/app/vector_icons/browser_tools_update_touch.icon
@@ -22,5 +22,4 @@ R_H_LINE_TO, 24, R_V_LINE_TO, 24, H_LINE_TO, 0, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/caret_down.1x.icon b/chrome/app/vector_icons/caret_down.1x.icon index f0d172f..1359d50 100644 --- a/chrome/app/vector_icons/caret_down.1x.icon +++ b/chrome/app/vector_icons/caret_down.1x.icon
@@ -9,4 +9,3 @@ MOVE_TO, 4, 6, R_LINE_TO, 4, 4, R_LINE_TO, 4, -4, -END,
diff --git a/chrome/app/vector_icons/caret_down.icon b/chrome/app/vector_icons/caret_down.icon index 7a5452d..b4a1696f 100644 --- a/chrome/app/vector_icons/caret_down.icon +++ b/chrome/app/vector_icons/caret_down.icon
@@ -10,4 +10,3 @@ R_LINE_TO, 7.5f, -8, // Hard clip at path points +- half the stroke. CLIP, 7, 11, 18, 11, -END,
diff --git a/chrome/app/vector_icons/caret_up.1x.icon b/chrome/app/vector_icons/caret_up.1x.icon index 863b01c3..5bd4153 100644 --- a/chrome/app/vector_icons/caret_up.1x.icon +++ b/chrome/app/vector_icons/caret_up.1x.icon
@@ -9,4 +9,3 @@ MOVE_TO, 4, 10, R_LINE_TO, 4, -4, R_LINE_TO, 4, 4, -END,
diff --git a/chrome/app/vector_icons/caret_up.icon b/chrome/app/vector_icons/caret_up.icon index 67f18cba..09b08e0 100644 --- a/chrome/app/vector_icons/caret_up.icon +++ b/chrome/app/vector_icons/caret_up.icon
@@ -10,4 +10,3 @@ MOVE_TO, 8.5f, 19.5f, R_LINE_TO, 7.5f, -8, R_LINE_TO, 7.5f, 8, -END,
diff --git a/chrome/app/vector_icons/certificate.icon b/chrome/app/vector_icons/certificate.icon index d2ffd58f..fa2cc23a 100644 --- a/chrome/app/vector_icons/certificate.icon +++ b/chrome/app/vector_icons/certificate.icon
@@ -45,5 +45,4 @@ R_H_LINE_TO, 24, R_V_LINE_TO, -3, H_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/chromium/product.icon b/chrome/app/vector_icons/chromium/product.icon index b7cc06d..63ece93 100644 --- a/chrome/app/vector_icons/chromium/product.icon +++ b/chrome/app/vector_icons/chromium/product.icon
@@ -27,5 +27,4 @@ R_H_LINE_TO, -6.6f, R_CUBIC_TO, 1, 0.8f, 1.7f, 2.1f, 1.7f, 3.5f, CLOSE, -CIRCLE, 12, 12, 3.5, -END +CIRCLE, 12, 12, 3.5
diff --git a/chrome/app/vector_icons/close_all.icon b/chrome/app/vector_icons/close_all.icon index abe83644..fdf8061 100644 --- a/chrome/app/vector_icons/close_all.icon +++ b/chrome/app/vector_icons/close_all.icon
@@ -35,5 +35,4 @@ LINE_TO, 15.41f, 10, R_LINE_TO, 2.83f, 2.83f, R_LINE_TO, -1.41f, 1.41f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/code.icon b/chrome/app/vector_icons/code.icon index 8492f13..d634082 100644 --- a/chrome/app/vector_icons/code.icon +++ b/chrome/app/vector_icons/code.icon
@@ -17,5 +17,4 @@ R_LINE_TO, 12, 12, R_LINE_TO, -12, 12, R_LINE_TO, -2.8f, -2.8f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/content_paste.icon b/chrome/app/vector_icons/content_paste.icon index 194ed6d..4997de7 100644 --- a/chrome/app/vector_icons/content_paste.icon +++ b/chrome/app/vector_icons/content_paste.icon
@@ -33,5 +33,4 @@ V_LINE_TO, 4, R_H_LINE_TO, 2, R_V_LINE_TO, 16, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/cookie.icon b/chrome/app/vector_icons/cookie.icon index a4e6887a..ab47da7a 100644 --- a/chrome/app/vector_icons/cookie.icon +++ b/chrome/app/vector_icons/cookie.icon
@@ -55,5 +55,4 @@ CUBIC_TO, 34.66f, 26, 36, 27.34f, 36, 29, CUBIC_TO, 36, 30.66f, 34.66f, 32, 33, 32, LINE_TO, 33, 32, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/crashed_tab.icon b/chrome/app/vector_icons/crashed_tab.icon index fa3e662..50576843 100644 --- a/chrome/app/vector_icons/crashed_tab.icon +++ b/chrome/app/vector_icons/crashed_tab.icon
@@ -48,5 +48,4 @@ R_MOVE_TO, 0, -4, R_LINE_TO, 0, 0, R_MOVE_TO, -2, 2, -R_LINE_TO, 0, 0, -END +R_LINE_TO, 0, 0
diff --git a/chrome/app/vector_icons/credit_card.1x.icon b/chrome/app/vector_icons/credit_card.1x.icon index 2608251..b3e5a647 100644 --- a/chrome/app/vector_icons/credit_card.1x.icon +++ b/chrome/app/vector_icons/credit_card.1x.icon
@@ -24,5 +24,4 @@ H_LINE_TO, 3.01f, CUBIC_TO, 1.9f, 14, 1, 13.1f, 1, 12.01f, V_LINE_TO, 4.99f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/credit_card.icon b/chrome/app/vector_icons/credit_card.icon index c48afc5..b0b43cb7 100644 --- a/chrome/app/vector_icons/credit_card.icon +++ b/chrome/app/vector_icons/credit_card.icon
@@ -24,5 +24,4 @@ V_LINE_TO, 8, R_H_LINE_TO, 22, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/default_favicon.icon b/chrome/app/vector_icons/default_favicon.icon index c66dc6b..3639719dd7 100644 --- a/chrome/app/vector_icons/default_favicon.icon +++ b/chrome/app/vector_icons/default_favicon.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, 8, R_H_LINE_TO, 8, R_V_LINE_TO, 16, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/default_touch_favicon.icon b/chrome/app/vector_icons/default_touch_favicon.icon index ecc13ead..84bbf3e 100644 --- a/chrome/app/vector_icons/default_touch_favicon.icon +++ b/chrome/app/vector_icons/default_touch_favicon.icon
@@ -17,5 +17,4 @@ MOVE_TO, 10, 9, LINE_TO, 7, 6, LINE_TO, 7, 9, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/default_touch_favicon_mask.icon b/chrome/app/vector_icons/default_touch_favicon_mask.icon index ba64377..3158281b 100644 --- a/chrome/app/vector_icons/default_touch_favicon_mask.icon +++ b/chrome/app/vector_icons/default_touch_favicon_mask.icon
@@ -4,5 +4,4 @@ CANVAS_DIMENSIONS, 16, CIRCLE, 8, 8, 6, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/eol.icon b/chrome/app/vector_icons/eol.icon index 1fa2a35..1d929fc 100644 --- a/chrome/app/vector_icons/eol.icon +++ b/chrome/app/vector_icons/eol.icon
@@ -55,5 +55,4 @@ LINE_TO, 34.26f, 38.6f, LINE_TO, 45.21f, 49.76f, LINE_TO, 45.21f, 50.42f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/extension.icon b/chrome/app/vector_icons/extension.icon index 75fe2c8..b8174deb 100644 --- a/chrome/app/vector_icons/extension.icon +++ b/chrome/app/vector_icons/extension.icon
@@ -31,5 +31,4 @@ R_H_LINE_TO, 3, R_CUBIC_TO, 2.76f, 0, 5, -2.24f, 5, -5, R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/extension_crashed.icon b/chrome/app/vector_icons/extension_crashed.icon index 6a88cb6..2229d7397 100644 --- a/chrome/app/vector_icons/extension_crashed.icon +++ b/chrome/app/vector_icons/extension_crashed.icon
@@ -32,5 +32,4 @@ LINE_TO, 16, 31.5f, LINE_TO, 37, 17.5f, LINE_TO, 37, 23, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/file_download.icon b/chrome/app/vector_icons/file_download.icon index e7067c0..b2f7de0 100644 --- a/chrome/app/vector_icons/file_download.icon +++ b/chrome/app/vector_icons/file_download.icon
@@ -16,5 +16,4 @@ R_H_LINE_TO, 28, R_V_LINE_TO, -4, H_LINE_TO, 10, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/file_download_shelf.icon b/chrome/app/vector_icons/file_download_shelf.icon index a77e54099..f35a93d 100644 --- a/chrome/app/vector_icons/file_download_shelf.icon +++ b/chrome/app/vector_icons/file_download_shelf.icon
@@ -21,5 +21,4 @@ R_H_LINE_TO, 32, R_V_LINE_TO, 4, R_H_LINE_TO, -32, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/folder.icon b/chrome/app/vector_icons/folder.icon index 412e6e4..28f38f3 100644 --- a/chrome/app/vector_icons/folder.icon +++ b/chrome/app/vector_icons/folder.icon
@@ -14,5 +14,4 @@ R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, R_H_LINE_TO, -8, R_LINE_TO, -2, -2, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/folder_supervised.1x.icon b/chrome/app/vector_icons/folder_supervised.1x.icon index eee32eb..2245267 100644 --- a/chrome/app/vector_icons/folder_supervised.1x.icon +++ b/chrome/app/vector_icons/folder_supervised.1x.icon
@@ -43,5 +43,4 @@ CUBIC_TO, 8.75f, 5.56f, 8.19f, 5, 7.5f, 5, CUBIC_TO, 6.81f, 5, 6.25f, 5.56f, 6.25f, 6.25f, CUBIC_TO, 6.25f, 6.94f, 6.81f, 7.5f, 7.5f, 7.5f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/folder_supervised.icon b/chrome/app/vector_icons/folder_supervised.icon index 17da033..da6f86f1d 100644 --- a/chrome/app/vector_icons/folder_supervised.icon +++ b/chrome/app/vector_icons/folder_supervised.icon
@@ -43,5 +43,4 @@ CUBIC_TO, 17.5f, 18.67f, 16.83f, 18, 16, 18, CUBIC_TO, 15.17f, 18, 14.5f, 18.67f, 14.5f, 19.5f, CUBIC_TO, 14.5f, 20.33f, 15.17f, 21, 16, 21, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/forward_arrow_touch.icon b/chrome/app/vector_icons/forward_arrow_touch.icon index b7bb8ce..06bb39f 100644 --- a/chrome/app/vector_icons/forward_arrow_touch.icon +++ b/chrome/app/vector_icons/forward_arrow_touch.icon
@@ -22,5 +22,4 @@ R_LINE_TO, -0.09f, -0.09f, R_ARC_TO, 1, 1, 0, 0, 1, -1.32f, -1.32f, R_V_LINE_TO, 0, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/globe.icon b/chrome/app/vector_icons/globe.icon index 858c2f3..08b0b926 100644 --- a/chrome/app/vector_icons/globe.icon +++ b/chrome/app/vector_icons/globe.icon
@@ -45,5 +45,4 @@ CUBIC_TO, 38.14f, 28.44f, 38.29f, 28.42f, 38.44f, 28.4f, CUBIC_TO, 37.45f, 31.83f, 35.33f, 34.76f, 32.51f, 36.76f, LINE_TO, 32.51f, 36.76f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/google_chrome/product.icon b/chrome/app/vector_icons/google_chrome/product.icon index ec96ab98..8f98f16 100644 --- a/chrome/app/vector_icons/google_chrome/product.icon +++ b/chrome/app/vector_icons/google_chrome/product.icon
@@ -39,5 +39,4 @@ NEW_PATH, // Blue PATH_COLOR_ARGB, 0xFF, 0x42, 0x85, 0xF4, -CIRCLE, 12, 12, 3.5, -END +CIRCLE, 12, 12, 3.5
diff --git a/chrome/app/vector_icons/google_g_logo.icon b/chrome/app/vector_icons/google_g_logo.icon index d8ee51b..ba12830 100644 --- a/chrome/app/vector_icons/google_g_logo.icon +++ b/chrome/app/vector_icons/google_g_logo.icon
@@ -45,5 +45,4 @@ CUBIC_TO, 9.96f, 0, 4.46f, 3.6f, 1.78f, 8.8f, R_LINE_TO, 5.43f, 4.16f, R_CUBIC_TO, 1.27f, -3.78f, 4.85f, -6.6f, 9.1f, -6.6f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/google_pay_logo_with_vertical_separator.icon b/chrome/app/vector_icons/google_pay_logo_with_vertical_separator.icon index b9968af..f3f5e160 100644 --- a/chrome/app/vector_icons/google_pay_logo_with_vertical_separator.icon +++ b/chrome/app/vector_icons/google_pay_logo_with_vertical_separator.icon
@@ -110,6 +110,5 @@ R_H_LINE_TO, 1, R_V_LINE_TO, 14, R_H_LINE_TO, -1, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/horizontal_menu.1x.icon b/chrome/app/vector_icons/horizontal_menu.1x.icon index 90c90c64..5b82051 100644 --- a/chrome/app/vector_icons/horizontal_menu.1x.icon +++ b/chrome/app/vector_icons/horizontal_menu.1x.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 11.5f, 8.83f, 12.17f, 9.5f, 13, 9.5f, CUBIC_TO, 13.83f, 9.5f, 14.5f, 8.83f, 14.5f, 8, CUBIC_TO, 14.5f, 7.17f, 13.83f, 6.5f, 13, 6.5f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/horizontal_menu.icon b/chrome/app/vector_icons/horizontal_menu.icon index 95eedd9..33b5698 100644 --- a/chrome/app/vector_icons/horizontal_menu.icon +++ b/chrome/app/vector_icons/horizontal_menu.icon
@@ -20,5 +20,4 @@ CUBIC_TO, 22.34f, 19, 21, 17.66f, 21, 16, CUBIC_TO, 21, 14.34f, 22.34f, 13, 24, 13, CUBIC_TO, 25.66f, 13, 27, 14.34f, 27, 16, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/image.icon b/chrome/app/vector_icons/image.icon index 89eee8a..bcd00bb 100644 --- a/chrome/app/vector_icons/image.icon +++ b/chrome/app/vector_icons/image.icon
@@ -18,5 +18,4 @@ R_LINE_TO, 9, 12, H_LINE_TO, 10, R_LINE_TO, 7, -9, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/inactive_toast_arrow.icon b/chrome/app/vector_icons/inactive_toast_arrow.icon index 195ea064..a1ffcf1 100644 --- a/chrome/app/vector_icons/inactive_toast_arrow.icon +++ b/chrome/app/vector_icons/inactive_toast_arrow.icon
@@ -16,5 +16,4 @@ LINE_TO, 12.0f, 12.0f, LINE_TO, 25.0f, -1.29452005e-13f, LINE_TO, -1.0f, -1.26121336e-13f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/inactive_toast_close.icon b/chrome/app/vector_icons/inactive_toast_close.icon index 57ff3c6..f9aadfb 100644 --- a/chrome/app/vector_icons/inactive_toast_close.icon +++ b/chrome/app/vector_icons/inactive_toast_close.icon
@@ -16,5 +16,4 @@ R_LINE_TO, 3.89f, 3.89f, R_LINE_TO, 0.71f, -0.71f, R_LINE_TO, -3.89f, -3.89f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/inactive_toast_logo.icon b/chrome/app/vector_icons/inactive_toast_logo.icon index 8af149c..3ed5614 100644 --- a/chrome/app/vector_icons/inactive_toast_logo.icon +++ b/chrome/app/vector_icons/inactive_toast_logo.icon
@@ -27,5 +27,4 @@ R_H_LINE_TO, -6.6f, R_CUBIC_TO, 1, 0.8f, 1.7f, 2.1f, 1.7f, 3.5f, CLOSE, -CIRCLE, 12, 12, 3.5, -END +CIRCLE, 12, 12, 3.5
diff --git a/chrome/app/vector_icons/incognito.1x.icon b/chrome/app/vector_icons/incognito.1x.icon index 4f9d36d..420a90e 100644 --- a/chrome/app/vector_icons/incognito.1x.icon +++ b/chrome/app/vector_icons/incognito.1x.icon
@@ -48,5 +48,4 @@ R_H_LINE_TO, 18, R_LINE_TO, -3.8f, -2, H_LINE_TO, 6.93f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/incognito.icon b/chrome/app/vector_icons/incognito.icon index 0798668..5ebf9d94 100644 --- a/chrome/app/vector_icons/incognito.icon +++ b/chrome/app/vector_icons/incognito.icon
@@ -49,5 +49,4 @@ LINE_TO, 18.46f, 9.23f, LINE_TO, 16.26f, 16, R_H_LINE_TO, 15.64f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/key.icon b/chrome/app/vector_icons/key.icon index c529eb8..f8a919c 100644 --- a/chrome/app/vector_icons/key.icon +++ b/chrome/app/vector_icons/key.icon
@@ -21,5 +21,4 @@ R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3, R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/laptop.icon b/chrome/app/vector_icons/laptop.icon index 4ca2f98..8b2e9e41 100644 --- a/chrome/app/vector_icons/laptop.icon +++ b/chrome/app/vector_icons/laptop.icon
@@ -21,5 +21,4 @@ R_V_LINE_TO, 20, H_LINE_TO, 8, V_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/launch.icon b/chrome/app/vector_icons/launch.icon index 22223d6..b03c0aa 100644 --- a/chrome/app/vector_icons/launch.icon +++ b/chrome/app/vector_icons/launch.icon
@@ -26,5 +26,4 @@ V_LINE_TO, 8, H_LINE_TO, 15, V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/mixed_content.icon b/chrome/app/vector_icons/mixed_content.icon index a3303bbe..1c62044a 100644 --- a/chrome/app/vector_icons/mixed_content.icon +++ b/chrome/app/vector_icons/mixed_content.icon
@@ -16,5 +16,4 @@ LINE_TO, 39, 22.11f, CUBIC_TO, 39, 29.93f, 33.34f, 38.22f, 26, 40, LINE_TO, 26, 8, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/my_location.icon b/chrome/app/vector_icons/my_location.icon index fcbf685..c3d8647 100644 --- a/chrome/app/vector_icons/my_location.icon +++ b/chrome/app/vector_icons/my_location.icon
@@ -31,5 +31,4 @@ R_CUBIC_TO, 0, -7.73f, 6.27f, -14, 14, -14, R_CUBIC_TO, 7.73f, 0, 14, 6.27f, 14, 14, R_CUBIC_TO, 0, 7.73f, -6.27f, 14, -14, 14, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/navigate_home.1x.icon b/chrome/app/vector_icons/navigate_home.1x.icon index 1312e01..d140ec70 100644 --- a/chrome/app/vector_icons/navigate_home.1x.icon +++ b/chrome/app/vector_icons/navigate_home.1x.icon
@@ -28,5 +28,4 @@ CUBIC_TO, 2.5f, 16, 2, 15.5f, 2, 14.5f, LINE_TO, 2, 8.3f, LINE_TO, 2, 8.3f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/navigate_home.icon b/chrome/app/vector_icons/navigate_home.icon index 2a6f8d1..42aa6e0f 100644 --- a/chrome/app/vector_icons/navigate_home.icon +++ b/chrome/app/vector_icons/navigate_home.icon
@@ -33,5 +33,4 @@ CUBIC_TO, 6.9f, 29, 6, 28.1f, 6, 27, LINE_TO, 6, 17.39f, LINE_TO, 6, 17.39f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/navigate_home_touch.icon b/chrome/app/vector_icons/navigate_home_touch.icon index d266a1e..a2c6762a 100644 --- a/chrome/app/vector_icons/navigate_home_touch.icon +++ b/chrome/app/vector_icons/navigate_home_touch.icon
@@ -28,5 +28,4 @@ R_LINE_TO, 5, 5.15f, V_LINE_TO, 19, H_LINE_TO, 7, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/navigate_stop.1x.icon b/chrome/app/vector_icons/navigate_stop.1x.icon index bb69c8099..7e86af5 100644 --- a/chrome/app/vector_icons/navigate_stop.1x.icon +++ b/chrome/app/vector_icons/navigate_stop.1x.icon
@@ -19,5 +19,4 @@ LINE_TO, 13.75f, 12.57f, CUBIC_TO, 14.08f, 12.9f, 14.08f, 13.43f, 13.75f, 13.75f, CUBIC_TO, 13.43f, 14.08f, 12.9f, 14.08f, 12.57f, 13.75f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/navigate_stop.icon b/chrome/app/vector_icons/navigate_stop.icon index 5885cfcc..a8bcead 100644 --- a/chrome/app/vector_icons/navigate_stop.icon +++ b/chrome/app/vector_icons/navigate_stop.icon
@@ -19,5 +19,4 @@ LINE_TO, 27.51f, 25.14f, CUBIC_TO, 28.16f, 25.79f, 28.16f, 26.85f, 27.51f, 27.51f, CUBIC_TO, 26.85f, 28.16f, 25.79f, 28.16f, 25.14f, 27.51f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/navigate_stop_touch.icon b/chrome/app/vector_icons/navigate_stop_touch.icon index 1ef5b4f..60cfd8ad 100644 --- a/chrome/app/vector_icons/navigate_stop_touch.icon +++ b/chrome/app/vector_icons/navigate_stop_touch.icon
@@ -28,5 +28,4 @@ LINE_TO, 6.5f, 5, LINE_TO, 12, 10.51f, LINE_TO, 17.51f, 5, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/new_tab_button_incognito.icon b/chrome/app/vector_icons/new_tab_button_incognito.icon index d73efbd..b487335f 100644 --- a/chrome/app/vector_icons/new_tab_button_incognito.icon +++ b/chrome/app/vector_icons/new_tab_button_incognito.icon
@@ -41,5 +41,4 @@ R_CUBIC_TO, 0, -0.56f, -0.45f, -1, -1, -1, R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1, R_CUBIC_TO, 0, 0.56f, 0.45f, 1, 1, 1, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/new_tab_button_plus.icon b/chrome/app/vector_icons/new_tab_button_plus.icon index e23da8e0..69484e674 100644 --- a/chrome/app/vector_icons/new_tab_button_plus.icon +++ b/chrome/app/vector_icons/new_tab_button_plus.icon
@@ -15,5 +15,4 @@ R_H_LINE_TO, 5, V_LINE_TO, 0, R_H_LINE_TO, 2, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/new_tab_mac_touchbar.icon b/chrome/app/vector_icons/new_tab_mac_touchbar.icon index 807837f..43265a7 100644 --- a/chrome/app/vector_icons/new_tab_mac_touchbar.icon +++ b/chrome/app/vector_icons/new_tab_mac_touchbar.icon
@@ -22,5 +22,4 @@ R_V_LINE_TO, 12, R_H_LINE_TO, 12, R_V_LINE_TO, 6, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/open_in_phone.icon b/chrome/app/vector_icons/open_in_phone.icon index 3ec5522b..a990614 100644 --- a/chrome/app/vector_icons/open_in_phone.icon +++ b/chrome/app/vector_icons/open_in_phone.icon
@@ -28,5 +28,4 @@ R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, V_LINE_TO, 3, R_CUBIC_TO, 0, -1.1f, -0.9f, -1.99f, -2, -1.99f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/overflow_chevron.1x.icon b/chrome/app/vector_icons/overflow_chevron.1x.icon index 073f07c..a0b8ef1 100644 --- a/chrome/app/vector_icons/overflow_chevron.1x.icon +++ b/chrome/app/vector_icons/overflow_chevron.1x.icon
@@ -24,5 +24,4 @@ LINE_TO, 7.76f, 4.55f, CUBIC_TO, 8.08f, 4.25f, 8.08f, 3.75f, 7.76f, 3.45f, LINE_TO, 5.41f, 1.23f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/overflow_chevron.icon b/chrome/app/vector_icons/overflow_chevron.icon index 874c5b6..542ec32 100644 --- a/chrome/app/vector_icons/overflow_chevron.icon +++ b/chrome/app/vector_icons/overflow_chevron.icon
@@ -24,5 +24,4 @@ LINE_TO, 13.64f, 8.52f, CUBIC_TO, 14.12f, 7.95f, 14.12f, 7.05f, 13.64f, 6.48f, LINE_TO, 10.12f, 2.42f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/page_info_content_paste.icon b/chrome/app/vector_icons/page_info_content_paste.icon index e884297..091253ce 100644 --- a/chrome/app/vector_icons/page_info_content_paste.icon +++ b/chrome/app/vector_icons/page_info_content_paste.icon
@@ -28,5 +28,4 @@ H_LINE_TO, 7, R_ARC_TO, 1, 1, 0, 0, 1, -1, -1, R_V_LINE_TO, -1.5f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/paintbrush.icon b/chrome/app/vector_icons/paintbrush.icon index 9b7b2a6..dd55dee1 100644 --- a/chrome/app/vector_icons/paintbrush.icon +++ b/chrome/app/vector_icons/paintbrush.icon
@@ -35,5 +35,4 @@ LINE_TO, 5.6f, 27.6f, LINE_TO, 13.8f, 35.83f, LINE_TO, 13.8f, 35.83f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/photo.icon b/chrome/app/vector_icons/photo.icon index 4b1e7a6..5bfe351 100644 --- a/chrome/app/vector_icons/photo.icon +++ b/chrome/app/vector_icons/photo.icon
@@ -18,5 +18,4 @@ LINE_TO, 10.67f, 9, R_LINE_TO, 3, 4, H_LINE_TO, 4.33f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/photo_camera.icon b/chrome/app/vector_icons/photo_camera.icon index 3667b98..fd72bbd 100644 --- a/chrome/app/vector_icons/photo_camera.icon +++ b/chrome/app/vector_icons/photo_camera.icon
@@ -17,5 +17,4 @@ LINE_TO, 30, 4, H_LINE_TO, 18, CLOSE, -CIRCLE, 24, 24, 10, -END +CIRCLE, 24, 24, 10
diff --git a/chrome/app/vector_icons/profile_switcher_outline.icon b/chrome/app/vector_icons/profile_switcher_outline.icon index 11b0d52b..e9c12ce 100644 --- a/chrome/app/vector_icons/profile_switcher_outline.icon +++ b/chrome/app/vector_icons/profile_switcher_outline.icon
@@ -45,5 +45,4 @@ R_CUBIC_TO, 0.05f, -3.97f, 8.01f, -6.16f, 12, -6.16f, R_CUBIC_TO, 3.99f, 0, 11.94f, 2.19f, 12, 6.16f, R_CUBIC_TO, -2.59f, 3.88f, -6.99f, 6.44f, -12, 6.44f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/reload_touch.icon b/chrome/app/vector_icons/reload_touch.icon index 0e3d14b..aac2d29 100644 --- a/chrome/app/vector_icons/reload_touch.icon +++ b/chrome/app/vector_icons/reload_touch.icon
@@ -21,5 +21,4 @@ CUBIC_TO, 7.6f, 20, 4, 16.42f, 4, 12, R_CUBIC_TO, 0, -4.42f, 3.6f, -8, 8.04f, -8, R_CUBIC_TO, 2.2f, 0, 4.2f, 0.88f, 5.65f, 2.32f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/remove.icon b/chrome/app/vector_icons/remove.icon index 31af5d4..e2ca0dda 100644 --- a/chrome/app/vector_icons/remove.icon +++ b/chrome/app/vector_icons/remove.icon
@@ -6,5 +6,4 @@ STROKE, 2.f, CAP_SQUARE, MOVE_TO, 3, 8, -R_H_LINE_TO, 10, -END +R_H_LINE_TO, 10
diff --git a/chrome/app/vector_icons/remove_box.icon b/chrome/app/vector_icons/remove_box.icon index 6374ad7..c17ba2f2 100644 --- a/chrome/app/vector_icons/remove_box.icon +++ b/chrome/app/vector_icons/remove_box.icon
@@ -18,5 +18,4 @@ R_V_LINE_TO, -2, R_H_LINE_TO, 10, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sad_tab.icon b/chrome/app/vector_icons/sad_tab.icon index 6876aca..dfcaf99c 100644 --- a/chrome/app/vector_icons/sad_tab.icon +++ b/chrome/app/vector_icons/sad_tab.icon
@@ -44,5 +44,4 @@ LINE_TO, 28, 23, LINE_TO, 28, 18, LINE_TO, 28, 18, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/security.icon b/chrome/app/vector_icons/security.icon index c949e291..561c15e 100644 --- a/chrome/app/vector_icons/security.icon +++ b/chrome/app/vector_icons/security.icon
@@ -19,5 +19,4 @@ V_LINE_TO, 12.6f, R_LINE_TO, 14, -6.22f, R_V_LINE_TO, 17.6f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sensors.icon b/chrome/app/vector_icons/sensors.icon index 75c785a3..4d6bb3a 100644 --- a/chrome/app/vector_icons/sensors.icon +++ b/chrome/app/vector_icons/sensors.icon
@@ -40,5 +40,4 @@ R_CUBIC_TO, 2.2f, -1.3f, 3.8f, -3.8f, 3.8f, -6.6f, R_CUBIC_TO, 0, -2.8f, -1.5f, -5.2f, -3.7f, -6.6f, LINE_TO, 12, 3.7f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/settings.icon b/chrome/app/vector_icons/settings.icon index 8150a91..6286b5e 100644 --- a/chrome/app/vector_icons/settings.icon +++ b/chrome/app/vector_icons/settings.icon
@@ -47,5 +47,4 @@ R_CUBIC_TO, 0, -3.87f, 3.13f, -7, 7, -7, R_CUBIC_TO, 3.87f, 0, 7, 3.13f, 7, 7, R_CUBIC_TO, 0, 3.87f, -3.13f, 7, -7, 7, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/signin_button_drop_down_arrow.icon b/chrome/app/vector_icons/signin_button_drop_down_arrow.icon index 04734a7d..baeef57 100644 --- a/chrome/app/vector_icons/signin_button_drop_down_arrow.icon +++ b/chrome/app/vector_icons/signin_button_drop_down_arrow.icon
@@ -6,5 +6,4 @@ MOVE_TO, 5, 8, R_H_LINE_TO, 14, R_LINE_TO, -7, 11, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/smartphone.icon b/chrome/app/vector_icons/smartphone.icon index 278ef4d..27851c96 100644 --- a/chrome/app/vector_icons/smartphone.icon +++ b/chrome/app/vector_icons/smartphone.icon
@@ -17,5 +17,4 @@ V_LINE_TO, 10, R_H_LINE_TO, 20, R_V_LINE_TO, 28, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/supervisor_account.icon b/chrome/app/vector_icons/supervisor_account.icon index 4b317121..fc4d1d17 100644 --- a/chrome/app/vector_icons/supervisor_account.icon +++ b/chrome/app/vector_icons/supervisor_account.icon
@@ -18,4 +18,3 @@ R_V_LINE_TO, -4.5f, R_CUBIC_TO, 0, -1.7f, .67f, -4.67f, 4.74f, -6.94f, CUBIC_TO, 21, 26.19f, 19.31f, 26, 18, 26, -END,
diff --git a/chrome/app/vector_icons/supervisor_account_circle.icon b/chrome/app/vector_icons/supervisor_account_circle.icon index e0478bf..03b962fc 100644 --- a/chrome/app/vector_icons/supervisor_account_circle.icon +++ b/chrome/app/vector_icons/supervisor_account_circle.icon
@@ -34,5 +34,4 @@ R_CUBIC_TO, 0, -1.42f, 2.94f, -2.13f, 4.4f, -2.13f, R_CUBIC_TO, 1.07f, 0, 2.92f, 0.39f, 3.84f, 1.15f, R_CUBIC_TO, -1.17f, 2.97f, -4.06f, 5.09f, -7.45f, 5.09f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sync.icon b/chrome/app/vector_icons/sync.icon index c2727bb..34964fc 100644 --- a/chrome/app/vector_icons/sync.icon +++ b/chrome/app/vector_icons/sync.icon
@@ -24,5 +24,4 @@ R_LINE_TO, 2.5f, -2.36f, LINE_TO, 8, 9.77f, R_V_LINE_TO, 1.77f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sync_circle.icon b/chrome/app/vector_icons/sync_circle.icon index 6276c0b..1d9002c9 100644 --- a/chrome/app/vector_icons/sync_circle.icon +++ b/chrome/app/vector_icons/sync_circle.icon
@@ -25,5 +25,4 @@ R_LINE_TO, 0.73f, 0.73f, R_CUBIC_TO, 0.39f, -0.61f, 0.62f, -1.34f, 0.62f, -2.13f, R_CUBIC_TO, 0, -2.21f, -1.79f, -4, -4, -4, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sync_error_circle.icon b/chrome/app/vector_icons/sync_error_circle.icon index 62a4afa4..19160e76 100644 --- a/chrome/app/vector_icons/sync_error_circle.icon +++ b/chrome/app/vector_icons/sync_error_circle.icon
@@ -37,5 +37,4 @@ R_V_LINE_TO, -3, R_H_LINE_TO, -1, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sync_problem.icon b/chrome/app/vector_icons/sync_problem.icon index 590cea7b..e512d9f 100644 --- a/chrome/app/vector_icons/sync_problem.icon +++ b/chrome/app/vector_icons/sync_problem.icon
@@ -35,5 +35,4 @@ V_LINE_TO, 14, R_H_LINE_TO, -4, R_V_LINE_TO, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/sync_switch_account.icon b/chrome/app/vector_icons/sync_switch_account.icon index 71e863a..88eaf6d 100644 --- a/chrome/app/vector_icons/sync_switch_account.icon +++ b/chrome/app/vector_icons/sync_switch_account.icon
@@ -20,5 +20,4 @@ R_H_LINE_TO, 4.55f, R_V_LINE_TO, 1.94f, LINE_TO, 14, 5.58f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab.icon b/chrome/app/vector_icons/tab.icon index aaaf6cc2..debaf86 100644 --- a/chrome/app/vector_icons/tab.icon +++ b/chrome/app/vector_icons/tab.icon
@@ -19,5 +19,4 @@ R_V_LINE_TO, 8, R_H_LINE_TO, 16, R_V_LINE_TO, 20, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_audio.1x.icon b/chrome/app/vector_icons/tab_audio.1x.icon index 19d3e2c..f2689701 100644 --- a/chrome/app/vector_icons/tab_audio.1x.icon +++ b/chrome/app/vector_icons/tab_audio.1x.icon
@@ -16,5 +16,4 @@ MOVE_TO, 10.5f, 6, R_V_LINE_TO, 3, MOVE_TO, 12.5f, 5, -R_V_LINE_TO, 5, -END +R_V_LINE_TO, 5
diff --git a/chrome/app/vector_icons/tab_audio.icon b/chrome/app/vector_icons/tab_audio.icon index 5aa896d..1ed5205e 100644 --- a/chrome/app/vector_icons/tab_audio.icon +++ b/chrome/app/vector_icons/tab_audio.icon
@@ -19,5 +19,4 @@ R_V_LINE_TO, 10, R_H_LINE_TO, 2, R_V_LINE_TO, -10, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_audio_muting.1x.icon b/chrome/app/vector_icons/tab_audio_muting.1x.icon index 719f492..b81d3044 100644 --- a/chrome/app/vector_icons/tab_audio_muting.1x.icon +++ b/chrome/app/vector_icons/tab_audio_muting.1x.icon
@@ -22,5 +22,4 @@ MOVE_TO, 10.5f, 6, R_V_LINE_TO, 1.5f, MOVE_TO, 12.5f, 5, -R_V_LINE_TO, 4.5f, -END +R_V_LINE_TO, 4.5f
diff --git a/chrome/app/vector_icons/tab_audio_muting.icon b/chrome/app/vector_icons/tab_audio_muting.icon index 69a6cbc..166a98b 100644 --- a/chrome/app/vector_icons/tab_audio_muting.icon +++ b/chrome/app/vector_icons/tab_audio_muting.icon
@@ -28,5 +28,4 @@ R_LINE_TO, 2, 2, R_V_LINE_TO, -9, R_H_LINE_TO, -2, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_audio_muting_rounded.icon b/chrome/app/vector_icons/tab_audio_muting_rounded.icon index 5894536..24ee2e3 100644 --- a/chrome/app/vector_icons/tab_audio_muting_rounded.icon +++ b/chrome/app/vector_icons/tab_audio_muting_rounded.icon
@@ -38,5 +38,4 @@ LINE_TO, 4.84f, 2.72f, LINE_TO, 6, 3.88f, LINE_TO, 6, 1.56f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_audio_rounded.icon b/chrome/app/vector_icons/tab_audio_rounded.icon index 5dc3f0e1..6462ea0 100644 --- a/chrome/app/vector_icons/tab_audio_rounded.icon +++ b/chrome/app/vector_icons/tab_audio_rounded.icon
@@ -23,5 +23,4 @@ LINE_TO, 7.11f, 11, CUBIC_TO, 9.34f, 10.48f, 11, 8.44f, 11, 6, CUBIC_TO, 11, 3.56f, 9.34f, 1.52f, 7.11f, 1, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_bluetooth_connected.icon b/chrome/app/vector_icons/tab_bluetooth_connected.icon index 9ed1125..3d75601 100644 --- a/chrome/app/vector_icons/tab_bluetooth_connected.icon +++ b/chrome/app/vector_icons/tab_bluetooth_connected.icon
@@ -30,5 +30,4 @@ R_V_LINE_TO, -6, R_LINE_TO, 2.83f, 3.01f, H_LINE_TO, 21, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/app/vector_icons/tab_close_button_touch.icon b/chrome/app/vector_icons/tab_close_button_touch.icon index 8911437..661ec4e 100644 --- a/chrome/app/vector_icons/tab_close_button_touch.icon +++ b/chrome/app/vector_icons/tab_close_button_touch.icon
@@ -18,5 +18,4 @@ LINE_TO, 15.65f, 16.83f, LINE_TO, 16.83f, 15.65f, LINE_TO, 13.18f, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_close_button_touch_incognito.icon b/chrome/app/vector_icons/tab_close_button_touch_incognito.icon index a6d85b8..7e9299c 100644 --- a/chrome/app/vector_icons/tab_close_button_touch_incognito.icon +++ b/chrome/app/vector_icons/tab_close_button_touch_incognito.icon
@@ -18,5 +18,4 @@ LINE_TO, 15.65f, 16.83f, LINE_TO, 16.83f, 15.65f, LINE_TO, 13.18f, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_close_button_touch_incognito_hovered_pressed.icon b/chrome/app/vector_icons/tab_close_button_touch_incognito_hovered_pressed.icon index 47c8817b..d9cb4ac7 100644 --- a/chrome/app/vector_icons/tab_close_button_touch_incognito_hovered_pressed.icon +++ b/chrome/app/vector_icons/tab_close_button_touch_incognito_hovered_pressed.icon
@@ -18,5 +18,4 @@ LINE_TO, 15.65f, 16.83f, LINE_TO, 16.83f, 15.65f, LINE_TO, 13.18f, 12, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_close_hovered_pressed.1x.icon b/chrome/app/vector_icons/tab_close_hovered_pressed.1x.icon index facef29..1673116 100644 --- a/chrome/app/vector_icons/tab_close_hovered_pressed.1x.icon +++ b/chrome/app/vector_icons/tab_close_hovered_pressed.1x.icon
@@ -12,5 +12,4 @@ MOVE_TO, 4.75f, 4.75f, R_LINE_TO, 6.5f, 6.5f, MOVE_TO, 4.75f, 11.25f, -R_LINE_TO, 6.5f, -6.5f, -END \ No newline at end of file +R_LINE_TO, 6.5f, -6.5f
diff --git a/chrome/app/vector_icons/tab_close_hovered_pressed.icon b/chrome/app/vector_icons/tab_close_hovered_pressed.icon index 8b6696af..f8b979e2 100644 --- a/chrome/app/vector_icons/tab_close_hovered_pressed.icon +++ b/chrome/app/vector_icons/tab_close_hovered_pressed.icon
@@ -11,5 +11,4 @@ MOVE_TO, 10.25f, 10.25f, R_LINE_TO, 11.5f, 11.5f, MOVE_TO, 10.25f, 21.75f, -R_LINE_TO, 11.5f, -11.5f, -END \ No newline at end of file +R_LINE_TO, 11.5f, -11.5f
diff --git a/chrome/app/vector_icons/tab_close_normal.1x.icon b/chrome/app/vector_icons/tab_close_normal.1x.icon index 22108de..9df4bd8 100644 --- a/chrome/app/vector_icons/tab_close_normal.1x.icon +++ b/chrome/app/vector_icons/tab_close_normal.1x.icon
@@ -9,5 +9,4 @@ MOVE_TO, 4.75f, 4.75f, R_LINE_TO, 6.5f, 6.5f, MOVE_TO, 4.75f, 11.25f, -R_LINE_TO, 6.5f, -6.5f, -END \ No newline at end of file +R_LINE_TO, 6.5f, -6.5f
diff --git a/chrome/app/vector_icons/tab_close_normal.icon b/chrome/app/vector_icons/tab_close_normal.icon index 1597b26..fe6a968 100644 --- a/chrome/app/vector_icons/tab_close_normal.icon +++ b/chrome/app/vector_icons/tab_close_normal.icon
@@ -8,5 +8,4 @@ MOVE_TO, 10.25f, 10.25f, R_LINE_TO, 11.5f, 11.5f, MOVE_TO, 10.25f, 21.75f, -R_LINE_TO, 11.5f, -11.5f, -END \ No newline at end of file +R_LINE_TO, 11.5f, -11.5f
diff --git a/chrome/app/vector_icons/tab_media_capturing.icon b/chrome/app/vector_icons/tab_media_capturing.icon index ed94532..517784b3 100644 --- a/chrome/app/vector_icons/tab_media_capturing.icon +++ b/chrome/app/vector_icons/tab_media_capturing.icon
@@ -21,5 +21,4 @@ R_V_LINE_TO, 16, H_LINE_TO, 4, V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_media_capturing_with_arrow.icon b/chrome/app/vector_icons/tab_media_capturing_with_arrow.icon index 7184673..0c37cc7 100644 --- a/chrome/app/vector_icons/tab_media_capturing_with_arrow.icon +++ b/chrome/app/vector_icons/tab_media_capturing_with_arrow.icon
@@ -28,5 +28,4 @@ LINE_TO, 7.92f, 7, CUBIC_TO, 5.14f, 7, 4.38f, 9, 4, 11, CUBIC_TO, 4.93f, 9.6f, 5.88f, 8.96f, 7.92f, 9, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_media_recording.icon b/chrome/app/vector_icons/tab_media_recording.icon index b97009d..ee2bab57 100644 --- a/chrome/app/vector_icons/tab_media_recording.icon +++ b/chrome/app/vector_icons/tab_media_recording.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0, -4.42f, -3.58f, -8, -8, -8, R_CUBIC_TO, -4.42f, 0, -8, 3.58f, -8, 8, R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_usb_connected.1x.icon b/chrome/app/vector_icons/tab_usb_connected.1x.icon index 00cc795..dcf4c40 100644 --- a/chrome/app/vector_icons/tab_usb_connected.1x.icon +++ b/chrome/app/vector_icons/tab_usb_connected.1x.icon
@@ -34,5 +34,4 @@ V_LINE_TO, 6, R_H_LINE_TO, -2, R_V_LINE_TO, 2, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tab_usb_connected.icon b/chrome/app/vector_icons/tab_usb_connected.icon index 2884fdf..19978a3 100644 --- a/chrome/app/vector_icons/tab_usb_connected.icon +++ b/chrome/app/vector_icons/tab_usb_connected.icon
@@ -35,5 +35,4 @@ R_V_LINE_TO, -4, R_H_LINE_TO, -4, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/tablet.icon b/chrome/app/vector_icons/tablet.icon index 121bfd49..23f3eae 100644 --- a/chrome/app/vector_icons/tablet.icon +++ b/chrome/app/vector_icons/tablet.icon
@@ -17,5 +17,4 @@ V_LINE_TO, 12, R_H_LINE_TO, 28, R_V_LINE_TO, 24, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/translate.icon b/chrome/app/vector_icons/translate.icon index d553c9ba..6c06119 100644 --- a/chrome/app/vector_icons/translate.icon +++ b/chrome/app/vector_icons/translate.icon
@@ -71,5 +71,4 @@ CUBIC_TO, 11.26f, 7.36f, 11.02f, 8.27f, 10.17f, 9.27f, CUBIC_TO, 9.81f, 8.84f, 9.55f, 8.41f, 9.38f, 8.08f, LINE_TO, 8.69f, 8.08f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/trash_can.icon b/chrome/app/vector_icons/trash_can.icon index 70d9408..1ac9ed1 100644 --- a/chrome/app/vector_icons/trash_can.icon +++ b/chrome/app/vector_icons/trash_can.icon
@@ -18,5 +18,4 @@ H_LINE_TO, 3.33f, V_LINE_TO, 4, R_H_LINE_TO, 9.33f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/usb_security_key.icon b/chrome/app/vector_icons/usb_security_key.icon index c8110ea3..35d37b0a 100644 --- a/chrome/app/vector_icons/usb_security_key.icon +++ b/chrome/app/vector_icons/usb_security_key.icon
@@ -27,5 +27,4 @@ R_H_LINE_TO, 1.32f, R_V_LINE_TO, 0.4f, H_LINE_TO, 1.85f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/user_account_avatar.icon b/chrome/app/vector_icons/user_account_avatar.icon index 7a614704..006dec9a 100644 --- a/chrome/app/vector_icons/user_account_avatar.icon +++ b/chrome/app/vector_icons/user_account_avatar.icon
@@ -20,5 +20,4 @@ R_CUBIC_TO, 0.05f, -3.37f, 6.87f, -5.15f, 10.3f, -5.15f, R_CUBIC_TO, 3.42f, 0, 10.25f, 1.78f, 10.3f, 5.15f, R_CUBIC_TO, -2.21f, 3.06f, -6.01f, 5.15f, -10.3f, 5.15f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/user_menu_guest.icon b/chrome/app/vector_icons/user_menu_guest.icon index e0ece26..fe0fb3f 100644 --- a/chrome/app/vector_icons/user_menu_guest.icon +++ b/chrome/app/vector_icons/user_menu_guest.icon
@@ -34,5 +34,4 @@ R_CUBIC_TO, -1.33f, 0, -4, 0.73f, -4, 2.07f, V_LINE_TO, 13, R_H_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/user_menu_right_arrow.icon b/chrome/app/vector_icons/user_menu_right_arrow.icon index be4f0d7..7ecf47a 100644 --- a/chrome/app/vector_icons/user_menu_right_arrow.icon +++ b/chrome/app/vector_icons/user_menu_right_arrow.icon
@@ -6,6 +6,5 @@ MOVE_TO, 8, 5, R_V_LINE_TO, 14, R_LINE_TO, 11, -7, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/volume_up.icon b/chrome/app/vector_icons/volume_up.icon index 89774393..8f526ba 100644 --- a/chrome/app/vector_icons/volume_up.icon +++ b/chrome/app/vector_icons/volume_up.icon
@@ -23,5 +23,4 @@ V_LINE_TO, 14, CUBIC_TO, 12.01f, 13.38f, 14, 10.93f, 14, 8, R_CUBIC_TO, 0, -2.93f, -1.99f, -5.38f, -4.67f, -6, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/warning_badge.icon b/chrome/app/vector_icons/warning_badge.icon index 4e4f34a..ab1cf11 100644 --- a/chrome/app/vector_icons/warning_badge.icon +++ b/chrome/app/vector_icons/warning_badge.icon
@@ -33,5 +33,4 @@ LINE_TO, 26, 27, LINE_TO, 26, 29, LINE_TO, 24, 29, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/warning_badge_circle.1x.icon b/chrome/app/vector_icons/warning_badge_circle.1x.icon index f1a8abc..ae8b2b3 100644 --- a/chrome/app/vector_icons/warning_badge_circle.1x.icon +++ b/chrome/app/vector_icons/warning_badge_circle.1x.icon
@@ -19,5 +19,4 @@ H_LINE_TO, 32, V_LINE_TO, 30, R_H_LINE_TO, 1.5f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/warning_badge_circle.icon b/chrome/app/vector_icons/warning_badge_circle.icon index e7418ee10..c1d9f7e 100644 --- a/chrome/app/vector_icons/warning_badge_circle.icon +++ b/chrome/app/vector_icons/warning_badge_circle.icon
@@ -19,5 +19,4 @@ R_H_LINE_TO, -3, R_V_LINE_TO, -7, R_H_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/web.icon b/chrome/app/vector_icons/web.icon index 78d9b5f..497c50c 100644 --- a/chrome/app/vector_icons/web.icon +++ b/chrome/app/vector_icons/web.icon
@@ -29,5 +29,4 @@ V_LINE_TO, 18, R_H_LINE_TO, 8, R_V_LINE_TO, 18, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/zoom_minus.icon b/chrome/app/vector_icons/zoom_minus.icon index 04b5dd9..ce0d1ff1 100644 --- a/chrome/app/vector_icons/zoom_minus.icon +++ b/chrome/app/vector_icons/zoom_minus.icon
@@ -28,5 +28,4 @@ LINE_TO, 27, 18.6f, LINE_TO, 27, 21.4f, LINE_TO, 13, 21.4f, -CLOSE, -END +CLOSE
diff --git a/chrome/app/vector_icons/zoom_plus.icon b/chrome/app/vector_icons/zoom_plus.icon index 69007a3..0ee36e0 100644 --- a/chrome/app/vector_icons/zoom_plus.icon +++ b/chrome/app/vector_icons/zoom_plus.icon
@@ -38,5 +38,4 @@ LINE_TO, 27, 18.6f, LINE_TO, 27, 21.4f, LINE_TO, 27, 21.4f, -CLOSE, -END +CLOSE
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index aeb7fc93..84750b5 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2735,6 +2735,11 @@ flag_descriptions::kServiceWorkerPaymentAppsDescription, kOsAndroid | kOsDesktop, FEATURE_VALUE_TYPE(features::kServiceWorkerPaymentApps)}, + {"enable-web-payments-single-app-ui-skip", + flag_descriptions::kEnableWebPaymentsSingleAppUiSkipName, + flag_descriptions::kEnableWebPaymentsSingleAppUiSkipDescription, + kOsAndroid | kOsDesktop, + FEATURE_VALUE_TYPE(payments::features::kWebPaymentsSingleAppUiSkip)}, #if defined(OS_ANDROID) {"enable-android-pay-integration-v1", flag_descriptions::kEnableAndroidPayIntegrationV1Name, @@ -2749,11 +2754,6 @@ flag_descriptions::kEnableWebPaymentsMethodSectionOrderV2Description, kOsAndroid, FEATURE_VALUE_TYPE(payments::features::kWebPaymentsMethodSectionOrderV2)}, - {"enable-web-payments-single-app-ui-skip", - flag_descriptions::kEnableWebPaymentsSingleAppUiSkipName, - flag_descriptions::kEnableWebPaymentsSingleAppUiSkipDescription, - kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kWebPaymentsSingleAppUiSkip)}, {"android-payment-apps", flag_descriptions::kAndroidPaymentAppsName, flag_descriptions::kAndroidPaymentAppsDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kAndroidPaymentApps)},
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index b73969f8..6d38c98 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -130,7 +130,7 @@ &kVrIconInDaydreamHome, &payments::features::kWebPaymentsMethodSectionOrderV2, &payments::features::kWebPaymentsModifiers, - &kWebPaymentsSingleAppUiSkip, + &payments::features::kWebPaymentsSingleAppUiSkip, &kWebVrAutopresentFromIntent, &kWebVrCardboardSupport, &ntp_snippets::kArticleSuggestionsExpandableHeader, @@ -387,9 +387,6 @@ const base::Feature kVrIconInDaydreamHome{"VrIconInDaydreamHome", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kWebPaymentsSingleAppUiSkip{ - "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kWebVrAutopresentFromIntent{ "WebVrAutopresentFromIntent", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 9f9b7f3..b877cb49 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -85,7 +85,6 @@ extern const base::Feature kVrBrowsingInCustomTab; extern const base::Feature kVrBrowsingNativeAndroidUi; extern const base::Feature kVrIconInDaydreamHome; -extern const base::Feature kWebPaymentsSingleAppUiSkip; extern const base::Feature kWebVrAutopresentFromIntent; extern const base::Feature kWebVrCardboardSupport;
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index 02823f79..e799df1 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -176,7 +176,10 @@ // open then a reopen event does nothing. IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest, PlatformAppReopenWithWindows) { - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); + NSUInteger old_window_count = [[NSApp windows] count]; EXPECT_EQ(1u, active_browser_list_->size()); [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:YES]; @@ -190,8 +193,9 @@ IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest, ActivationFocusesBrowserWindow) { - base::scoped_nsobject<AppController> app_controller( - [[AppController alloc] init]); + AppController* app_controller = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(app_controller); ExtensionTestMessageListener listener("Launched", false); const extensions::Extension* app = @@ -233,7 +237,10 @@ // Test that in web app mode a reopen event opens the app URL. IN_PROC_BROWSER_TEST_F(AppControllerWebAppBrowserTest, WebAppReopenWithNoWindows) { - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); + EXPECT_EQ(1u, active_browser_list_->size()); BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO]; @@ -284,7 +291,10 @@ // Test that for a regular last profile, a reopen event opens a browser. IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest, RegularProfileReopenWithNoWindows) { - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); + EXPECT_EQ(1u, active_browser_list_->size()); BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO]; @@ -300,7 +310,9 @@ // minimize flakiness due to the scheduling/descheduling of tasks on the // different threads, pre-initialize the guest profile before it is needed. CreateAndWaitForSystemProfile(); - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); // Lock the active profile. base::ScopedAllowBlockingForTesting allow_blocking; @@ -322,6 +334,46 @@ UserManager::Hide(); } +// Test that for a guest last profile, commandDispatch should open UserManager +// if guest mode is disabled. Note that this test might be flaky under ASAN +// due to https://crbug.com/674475. Please disable this test under ASAN +// as the tests below if that happened. +IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest, + OpenGuestProfileOnlyIfGuestModeIsEnabled) { + CreateAndWaitForSystemProfile(); + PrefService* local_state = g_browser_process->local_state(); + local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir); + local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false); + + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); + + base::ScopedAllowBlockingForTesting allow_blocking; + Profile* profile = [ac lastProfile]; + EXPECT_TRUE(profile->IsGuestSession()); + + NSMenu* menu = [ac applicationDockMenu:NSApp]; + ASSERT_TRUE(menu); + NSMenuItem* item = [menu itemWithTag:IDC_NEW_WINDOW]; + ASSERT_TRUE(item); + EXPECT_EQ(1u, active_browser_list_->size()); + + [ac commandDispatch:item]; + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1u, active_browser_list_->size()); + EXPECT_TRUE(UserManager::IsShowing()); + UserManager::Hide(); + + local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, true); + [ac commandDispatch:item]; + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2u, active_browser_list_->size()); + EXPECT_FALSE(UserManager::IsShowing()); +} + #if defined(ADDRESS_SANITIZER) // Flaky under ASAN. See https://crbug.com/674475. #define MAYBE_GuestProfileReopenWithNoWindows DISABLED_GuestProfileReopenWithNoWindows @@ -337,7 +389,9 @@ PrefService* local_state = g_browser_process->local_state(); local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir); - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); base::ScopedAllowBlockingForTesting allow_blocking; Profile* profile = [ac lastProfile]; @@ -363,7 +417,9 @@ #endif IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest, MAYBE_AboutChromeForcesUserManager) { - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); // Create the guest profile, and set it as the last used profile so the // app controller can use it on init. @@ -577,7 +633,10 @@ IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest, BookmarksMenuIsRestoredAfterProfileSwitch) { ProfileManager* profile_manager = g_browser_process->profile_manager(); - base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + AppController* ac = base::mac::ObjCCast<AppController>( + [[NSApplication sharedApplication] delegate]); + ASSERT_TRUE(ac); + [ac awakeFromNib]; // Constants for bookmarks that we will create later.
diff --git a/chrome/browser/background_fetch/background_fetch_browsertest.cc b/chrome/browser/background_fetch/background_fetch_browsertest.cc index 4b22559..bfc2efb4 100644 --- a/chrome/browser/background_fetch/background_fetch_browsertest.cc +++ b/chrome/browser/background_fetch/background_fetch_browsertest.cc
@@ -273,7 +273,9 @@ DISALLOW_COPY_AND_ASSIGN(BackgroundFetchBrowserTest); }; -IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, DownloadService_Acceptance) { +// Flaky. See https://crbug.com/822276 +IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, + DISABLED_DownloadService_Acceptance) { // Starts a Background Fetch for a single to-be-downloaded file and waits for // that request to be scheduled with the Download Service. @@ -321,8 +323,9 @@ EXPECT_FALSE(offline_item.is_resumable); } +// Flaky. See https://crbug.com/822276 IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, - OfflineItemCollection_VerifyIconReceived) { + DISABLED_OfflineItemCollection_VerifyIconReceived) { // Starts a Background Fetch for a single to-be-downloaded file and waits for // the fetch to be registered with the offline items collection. We then // verify that the expected icon is associated with the newly added offline
diff --git a/chrome/browser/background_fetch/background_fetch_download_client.cc b/chrome/browser/background_fetch/background_fetch_download_client.cc index cf21948..f80b659 100644 --- a/chrome/browser/background_fetch/background_fetch_download_client.cc +++ b/chrome/browser/background_fetch/background_fetch_download_client.cc
@@ -7,12 +7,14 @@ #include <memory> #include <utility> +#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/background_fetch/background_fetch_delegate_impl.h" #include "chrome/browser/download/download_service_factory.h" #include "components/download/public/background_service/download_metadata.h" #include "components/download/public/background_service/download_service.h" #include "content/public/browser/background_fetch_response.h" #include "content/public/browser/browser_context.h" +#include "services/network/public/cpp/resource_request_body.h" #include "url/origin.h" BackgroundFetchDownloadClient::BackgroundFetchDownloadClient( @@ -93,3 +95,10 @@ // TODO(delphick): Return false if the background fetch hasn't finished yet return true; } + +void BackgroundFetchDownloadClient::GetUploadData( + const std::string& guid, + download::GetUploadDataCallback callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); +}
diff --git a/chrome/browser/background_fetch/background_fetch_download_client.h b/chrome/browser/background_fetch/background_fetch_download_client.h index e7aaf09..edcfae01 100644 --- a/chrome/browser/background_fetch/background_fetch_download_client.h +++ b/chrome/browser/background_fetch/background_fetch_download_client.h
@@ -43,6 +43,8 @@ const download::CompletionInfo& info) override; bool CanServiceRemoveDownloadedFile(const std::string& guid, bool force_delete) override; + void GetUploadData(const std::string& guid, + download::GetUploadDataCallback callback) override; content::BrowserContext* browser_context_; base::WeakPtr<BackgroundFetchDelegateImpl> delegate_;
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 53c6d3d..4f6c33a 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/file_select_helper.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/task_manager/web_contents_tags.h" #include "chrome/browser/ui/browser.h" @@ -988,6 +989,14 @@ base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) return nullptr; +#if defined(OS_CHROMEOS) + // Do not create DevTools if it's disabled for primary profile. + const Profile* primary_profile = ProfileManager::GetPrimaryUserProfile(); + if (primary_profile && + primary_profile->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled)) + return nullptr; +#endif + if (inspected_web_contents) { // Check for a place to dock. Browser* browser = nullptr;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index a89423f..2a23cdc 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -272,6 +272,12 @@ R"*(Validate Asm.js when "use asm" is present and then convert to )*" R"*(WebAssembly.)*"; +const char kEnableWebPaymentsSingleAppUiSkipName[] = + "Enable Web Payments single app UI skip"; +const char kEnableWebPaymentsSingleAppUiSkipDescription[] = + "Enable Web Payments to skip showing its UI if the developer specifies a " + "single app."; + const char kEnableAutofillCreditCardAblationExperimentDisplayName[] = "Credit card autofill ablation experiment."; const char kEnableAutofillCreditCardAblationExperimentDescription[] = @@ -2041,12 +2047,6 @@ "Enable this option to display payment method section above address " "section instead of below it."; -const char kEnableWebPaymentsSingleAppUiSkipName[] = - "Enable Web Payments single app UI skip"; -const char kEnableWebPaymentsSingleAppUiSkipDescription[] = - "Enable Web Payments to skip showing its UI if the developer specifies a " - "single app."; - const char kGrantNotificationsToDSEName[] = "Grant notifications to the Default Search Engine"; const char kGrantNotificationsToDSENameDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d0f4663..850bc8a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -394,6 +394,9 @@ extern const char kEnableWasmName[]; extern const char kEnableWasmDescription[]; +extern const char kEnableWebPaymentsSingleAppUiSkipName[]; +extern const char kEnableWebPaymentsSingleAppUiSkipDescription[]; + extern const char kEnableWebUsbName[]; extern const char kEnableWebUsbDescription[]; @@ -1239,9 +1242,6 @@ extern const char kEnableWebPaymentsMethodSectionOrderV2Name[]; extern const char kEnableWebPaymentsMethodSectionOrderV2Description[]; -extern const char kEnableWebPaymentsSingleAppUiSkipName[]; -extern const char kEnableWebPaymentsSingleAppUiSkipDescription[]; - extern const char kGrantNotificationsToDSEName[]; extern const char kGrantNotificationsToDSENameDescription[];
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index 6507292..48f85bc 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -350,6 +350,16 @@ base::BindOnce(&CastMediaSinkServiceImpl::OpenChannel, GetWeakPtr(), ip_endpoint, cast_sink_it->second, nullptr, SinkSource::kConnectionRetry)); + // We erase the sink here so that OpenChannel would not find an existing + // sink. + // Note: a better longer term solution is to introduce a state field to the + // sink. We would set it to ERROR here. In OpenChannel(), we would check + // create a socket only if the state is not already CONNECTED. + if (observer_) + observer_->OnSinkRemoved(cast_sink_it->second); + + current_sinks_map_.erase(cast_sink_it); + MediaSinkServiceBase::RestartTimer(); return; } @@ -382,6 +392,9 @@ } sink_cache_[last_network_id] = std::move(current_sinks); } + + // TODO(imcheng): Maybe this should clear |current_sinks_map_| and call + // |RestartTimer()| so it is more responsive? if (IsNetworkIdUnknownOrDisconnected(network_id)) return; @@ -511,7 +524,7 @@ << ip_endpoint.ToString() << " [error_state]: " << cast_channel::ChannelErrorToString(error_state); - OnChannelOpenFailed(ip_endpoint); + OnChannelOpenFailed(ip_endpoint, cast_sink); CastAnalytics::RecordCastChannelConnectResult( MediaRouterChannelConnectResults::FAILURE); return; @@ -572,6 +585,18 @@ sink_it->second = cast_sink; } + // If the sink was under a different IP address previously, remove it from + // |current_sinks_map_|. + auto old_sink_it = std::find_if( + current_sinks_map_.begin(), current_sinks_map_.end(), + [&cast_sink, &ip_endpoint]( + const std::pair<net::IPEndPoint, MediaSinkInternal>& entry) { + return !(entry.first == ip_endpoint) && + entry.second.sink().id() == cast_sink.sink().id(); + }); + if (old_sink_it != current_sinks_map_.end()) + current_sinks_map_.erase(old_sink_it); + if (observer_) observer_->OnSinkAddedOrUpdated(cast_sink, socket); @@ -580,9 +605,14 @@ } void CastMediaSinkServiceImpl::OnChannelOpenFailed( - const net::IPEndPoint& ip_endpoint) { + const net::IPEndPoint& ip_endpoint, + const MediaSinkInternal& sink) { + // It is possible that the old sink in |current_sinks_map_| is replaced with + // a new sink if a network change happened. Check the sink ID to make sure + // this is the sink we want to erase. auto it = current_sinks_map_.find(ip_endpoint); - if (it == current_sinks_map_.end()) + if (it == current_sinks_map_.end() || + it->second.sink().id() != sink.sink().id()) return; if (observer_)
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h index adb0a09..253db30 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -169,6 +169,10 @@ TestInitRetryParametersWithDefaultValue); FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnDialSinkAddedSkipsIfNonCastDevice); + FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, + TestOnChannelErrorRetry); + FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, + OpenChannelNewIPSameSink); // Holds Finch field trial parameters controlling Cast channel retry strategy. struct RetryParams { @@ -276,7 +280,7 @@ cast_channel::ChannelError error_state, SinkSource sink_source); - // Invoked when opening cast channel on IO thread succeeds. + // Invoked when opening cast channel succeeds. // |cast_sink|: Cast sink created from mDNS service description or DIAL sink. // |socket|: raw pointer of newly created cast channel. Does not take // ownership of |socket|. @@ -284,11 +288,12 @@ cast_channel::CastSocket* socket, SinkSource sink_source); - // Invoked when opening cast channel on IO thread fails after all retry + // Invoked when opening cast channel fails after all retry // attempts. // |ip_endpoint|: ip endpoint of cast channel failing to connect to. - // |sink_source|: Method of sink discovery. - void OnChannelOpenFailed(const net::IPEndPoint& ip_endpoint); + // |sink|: The sink for which channel open failed. + void OnChannelOpenFailed(const net::IPEndPoint& ip_endpoint, + const MediaSinkInternal& sink); // Returns whether the given DIAL-discovered |sink| is probably a non-Cast // device. This is heuristically determined by two things: |sink| has been
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 5970f77..62bd0fc 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -403,11 +403,66 @@ media_sink_service_impl_.OnDiscoveryComplete(); } +TEST_F(CastMediaSinkServiceImplTest, OpenChannelNewIPSameSink) { + MediaSinkInternal cast_sink1 = CreateCastSink(1); + net::IPEndPoint ip_endpoint1 = cast_sink1.cast_data().ip_endpoint; + + cast_channel::MockCastSocket socket; + socket.set_id(1); + + base::SimpleTestClock clock; + base::Time start_time = base::Time::Now(); + clock.SetNow(start_time); + media_sink_service_impl_.SetClockForTest(&clock); + + EXPECT_CALL(*mock_cast_socket_service_, + OpenSocketInternal(ip_endpoint1, _, _)) + .WillRepeatedly( + Invoke([&](const auto& ip_endpoint1, auto* net_log, auto open_cb) { + std::move(open_cb).Run(&socket); + })); + std::vector<MediaSinkInternal> sinks1 = {cast_sink1}; + media_sink_service_impl_.OpenChannels( + sinks1, CastMediaSinkServiceImpl::SinkSource::kMdns); + + mock_time_task_runner_->FastForwardUntilNoTasksRemain(); + EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_map_.size()); + + // |cast_sink1| changed IP address and is discovered by mdns before it is + // removed from |media_sink_service_impl_| first. + net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2); + CastSinkExtraData extra_data = cast_sink1.cast_data(); + extra_data.ip_endpoint = ip_endpoint2; + cast_sink1.set_cast_data(extra_data); + + EXPECT_CALL(*mock_cast_socket_service_, + OpenSocketInternal(ip_endpoint2, _, _)) + .WillRepeatedly( + Invoke([&](const auto& ip_endpoint1, auto* net_log, auto open_cb) { + std::move(open_cb).Run(&socket); + })); + + std::vector<MediaSinkInternal> updated_sinks1 = {cast_sink1}; + media_sink_service_impl_.OpenChannels( + updated_sinks1, CastMediaSinkServiceImpl::SinkSource::kMdns); + + // The entry under old IPEndPoint is removed and replaced with new IPEndPoint. + mock_time_task_runner_->FastForwardUntilNoTasksRemain(); + const auto& current_sinks_map = media_sink_service_impl_.current_sinks_map_; + EXPECT_EQ(1u, current_sinks_map.size()); + auto sink_it = current_sinks_map.find(ip_endpoint2); + ASSERT_TRUE(sink_it != current_sinks_map.end()); + EXPECT_EQ(cast_sink1, sink_it->second); +} + TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) { auto cast_sink = CreateCastSink(1); net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); cast_channel::MockCastSocket socket; socket.set_id(1); + socket.SetIPEndpoint(ip_endpoint1); + + auto cast_sink2 = CreateCastSink(2); EXPECT_CALL(observer_, OnSinkAddedOrUpdated(cast_sink, &socket)); media_sink_service_impl_.OnChannelOpenSucceeded( @@ -415,12 +470,49 @@ EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_map_.size()); - socket.SetIPEndpoint(ip_endpoint1); + // OnChannelOpenFailed called with mismatched sink: no-op. + EXPECT_CALL(observer_, OnSinkRemoved(_)).Times(0); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, cast_sink2); + EXPECT_FALSE(media_sink_service_impl_.current_sinks_map_.empty()); + EXPECT_CALL(observer_, OnSinkRemoved(cast_sink)); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, cast_sink); EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty()); } +TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorRetry) { + auto cast_sink = CreateCastSink(1); + net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); + cast_channel::MockCastSocket socket; + socket.set_id(1); + socket.SetIPEndpoint(ip_endpoint1); + EXPECT_CALL(socket, ready_state()) + .WillOnce(Return(cast_channel::ReadyState::OPEN)); + + EXPECT_CALL(observer_, OnSinkAddedOrUpdated(cast_sink, &socket)); + media_sink_service_impl_.OnChannelOpenSucceeded( + cast_sink, &socket, CastMediaSinkServiceImpl::SinkSource::kMdns); + + // Sink is removed on |OnError|, but we will retry. + EXPECT_CALL(observer_, OnSinkRemoved(cast_sink)); + EXPECT_CALL(*mock_cast_socket_service_, + OpenSocketInternal(ip_endpoint1, _, _)) + .WillRepeatedly( + Invoke([&](const auto& ip_endpoint1, auto* net_log, auto open_cb) { + std::move(open_cb).Run(&socket); + })); + media_sink_service_impl_.OnError(socket, + cast_channel::ChannelError::PING_TIMEOUT); + + EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty()); + + // Retry succeeds and sink is added back. + EXPECT_CALL(observer_, OnSinkAddedOrUpdated(cast_sink, &socket)); + mock_time_task_runner_->FastForwardUntilNoTasksRemain(); + + EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_map_.size()); +} + TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorMayRetryForConnectingChannel) { net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); @@ -666,8 +758,8 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2, sink2); MediaSinkInternal sink3 = CreateCastSink(3); net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3); @@ -738,7 +830,7 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); MediaSinkInternal sink3 = CreateCastSink(3); net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3); @@ -791,7 +883,7 @@ ExpectOpenSocketInternal(&socket1); media_sink_service_impl_.OpenChannels( sink_list1, CastMediaSinkServiceImpl::SinkSource::kMdns); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); // Connect to a new network with different sinks. fake_network_info_.clear(); @@ -872,8 +964,8 @@ net::NetworkChangeNotifier::CONNECTION_NONE); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2, sink2); MediaSinkInternal sink3 = CreateCastSink(3); net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3); @@ -941,8 +1033,8 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2, sink2); MediaSinkInternal sink3 = CreateCastSink(3); net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3); @@ -963,7 +1055,7 @@ content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3, sink3); // Resolution will fail for cached sinks. socket1.SetErrorState(cast_channel::ChannelError::CONNECT_ERROR); @@ -994,7 +1086,7 @@ net::NetworkChangeNotifier::CONNECTION_NONE); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4, sink4); // Reconnect and expect only |sink4| to be cached. EXPECT_CALL(*mock_cast_socket_service_, @@ -1034,6 +1126,12 @@ sink_list1, CastMediaSinkServiceImpl::SinkSource::kMdns); media_sink_service_impl_.OnDialSinkAdded(sink2_dial); + // CastMediaSinkServiceImpl generates a Cast sink based on |sink2_dial|. + auto sink2_it = + media_sink_service_impl_.current_sinks_map_.find(ip_endpoint2); + ASSERT_TRUE(sink2_it != media_sink_service_impl_.current_sinks_map_.end()); + MediaSinkInternal sink2_cast_from_dial = sink2_it->second; + // Connect to a new network with different sinks. fake_network_info_.clear(); net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( @@ -1046,8 +1144,9 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1_cast); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2, + sink2_cast_from_dial); MediaSinkInternal sink3_cast = CreateCastSink(3); MediaSinkInternal sink4_dial = CreateDialSink(4); @@ -1134,8 +1233,8 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast, sink1_cast); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial, sink1_dial); MediaSinkInternal sink2_cast = CreateCastSink(2); net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2); @@ -1197,8 +1296,8 @@ net::NetworkChangeNotifier::CONNECTION_WIFI); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); - media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1, sink1); + media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2, sink2); MediaSinkInternal sink3 = CreateCastSink(3); net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc index 7bf732cd..0b86f7c 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc
@@ -96,6 +96,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (base::FeatureList::IsEnabled(::features::kWebRtcRemoteEventLog)) { + VLOG(1) << "WebRTC remote-bound event logging enabled."; remote_logs_manager_ = std::make_unique<WebRtcRemoteEventLogManager>(this); }
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc index 8cdf17e..c5bfce3 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc
@@ -20,14 +20,15 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/browser_thread.h" -// TODO(eladalon): Block remote-bound logging on mobile devices. -// https://crbug.com/775415 +// TODO(crbug.com/775415): Block remote-bound logging on mobile devices. const size_t kMaxRemoteLogFileMetadataSizeBytes = 0xffffu; // 65535 static_assert(kMaxRemoteLogFileMetadataSizeBytes <= 0xFFFFFFu, "Only 24 bits available for encoding the metadata's length."); -const size_t kMaxRemoteLogFileSizeBytes = (1u << 29); // ~500MBs +// TODO(crbug.com/775415): Change back to (1u << 29) after resolving the issue +// where we read the entire file into memory. +const size_t kMaxRemoteLogFileSizeBytes = 50000000u; namespace { const base::FilePath::CharType kRemoteBoundLogSubDirectory[] = @@ -95,9 +96,9 @@ WebRtcRemoteEventLogManager::~WebRtcRemoteEventLogManager() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // TODO(eladalon): Purge from disk files which were being uploaded while - // destruction took place, thereby avoiding endless attempts to upload - // the same file. https://crbug.com/775415 + // TODO(crbug.com/775415): Purge from disk files which were being uploaded + // while destruction took place, thereby avoiding endless attempts to upload + // the same file. } void WebRtcRemoteEventLogManager::EnableForBrowserContext( @@ -119,7 +120,7 @@ enabled_browser_contexts_.insert(browser_context_id); } -// TODO(eladalon): Add unit tests. https://crbug.com/775415 +// TODO(crbug.com/775415): Add unit tests. void WebRtcRemoteEventLogManager::DisableForBrowserContext( BrowserContextId browser_context_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); @@ -282,9 +283,6 @@ base::BindOnce( &WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadCompleteInternal, base::Unretained(this))); - - // TODO(eladalon): Send indication of success/failure back to JS. - // https://crbug.com/775415 } void WebRtcRemoteEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting( @@ -344,7 +342,7 @@ return false; } - // TODO(eladalon): Test for appropriate permissions. https://crbug.com/775415 + // TODO(crbug.com/775415): Test for appropriate permissions. return true; } @@ -389,7 +387,7 @@ // Randomize a new filename. In the highly unlikely event that this filename // is already taken, it will be treated the same way as any other failure // to start the log file. - // TODO(eladalon): Add a unit test for above comment. https://crbug.com/775415 + // TODO(crbug.com/775415): Add a unit test for above comment. const std::string unique_filename = "event_log_" + std::to_string(base::RandUint64()); const base::FilePath base_path = GetLogsDirectoryPath(browser_context_dir); @@ -531,11 +529,13 @@ // The uploader takes ownership of the file; it's no longer considered to be // pending. (If the upload fails, the log will be deleted.) - // TODO(eladalon): Add more refined retry behavior, so that we would not - // delete the log permanently if the network is just down, on the one hand, - // but also would not be uploading unlimited data on endless retries on the - // other hand. https://crbug.com/775415 - // TODO(eladalon): Delay the upload's start. https://crbug.com/814362 + // TODO(crbug.com/775415): Add more refined retry behavior, so that we would + // not delete the log permanently if the network is just down, on the one + // hand, but also would not be uploading unlimited data on endless retries on + // the other hand. + // TODO(crbug.com/814362): Delay the upload's start. + // TODO(crbug.com/775415): Rename the file before uploading, so that we would + // not retry the upload after restarting Chrome, if the upload is interrupted. uploader_ = uploader_factory_->Create(pending_logs_.begin()->path, this); pending_logs_.erase(pending_logs_.begin()); }
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc index 8d5ea19..8d7f0bd 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
@@ -4,36 +4,280 @@ #include "chrome/browser/media/webrtc/webrtc_event_log_uploader.h" +#include "base/bind.h" #include "base/files/file_util.h" #include "base/logging.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "components/version_info/version_info.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/load_flags.h" +#include "net/base/mime_util.h" +#include "net/http/http_status_code.h" -WebRtcEventLogUploaderImpl::WebRtcEventLogUploaderImpl( - const base::FilePath& path, - WebRtcEventLogUploaderObserver* observer) { - DCHECK(observer); +// Explanation about the life cycle of a WebRtcEventLogUploaderImpl object, and +// about why its use of base::Unretained is safe: +// * WebRtcEventLogUploaderImpl objects are owned (indirectly) by +// WebRtcEventLogManager, which is a singleton object that is not destroyed +// during Chrome shutdown, but rather, is allowed to leak. +// * Therefore, objects of type WebRtcEventLogUploaderImpl will only be +// destroyed when their owner explicitly decides to do so. +// * The direct owner, WebRtcRemoteEventLogManager, only deletes a +// WebRtcEventLogUploaderImpl after it receives a notification +// of type OnWebRtcEventLogUploadComplete. +// * OnWebRtcEventLogUploadComplete() is only ever called as the last step, +// there are no tasks pending which have a reference to this object. +// * The previous point follows from OnURLFetchComplete being guaranteed to +// be the last callback called on a URLFetcherDelegate. - // TODO(eladalon): Provide an actual implementation; really upload the file. - // https://crbug.com/775415 +namespace { +// TODO(crbug.com/817495): Eliminate the duplication with other uploaders. +const char kUploadContentType[] = "multipart/form-data"; +const char kBoundary[] = "----**--yradnuoBgoLtrapitluMklaTelgooG--**----"; - // If the upload was successful, the file is no longer needed. - // If the upload failed, we don't want to retry, because we run the risk of - // uploading significant amounts of data once again, only for the upload to - // fail again after (as an example) wasting 50MBs of upload bandwidth. - const bool deletion_successful = base::DeleteFile(path, /*recursive=*/false); - if (!deletion_successful) { - // This is a somewhat serious (though unlikely) error, because now we'll try - // to upload this file again next time Chrome launches. - LOG(ERROR) << "Could not delete pending log file."; - } +const char kLogFilename[] = "webrtc_event_log"; +const char kLogExtension[] = "log"; - // TODO(eladalon): Provide actual success/failure of upload. - // https://crbug.com/775415 - observer->OnWebRtcEventLogUploadComplete(path, true); +constexpr size_t kExpectedMimeOverheadBytes = 1000; // Intentional overshot. + +// TODO(crbug.com/817495): Eliminate the duplication with other uploaders. +#if defined(OS_WIN) +const char kProduct[] = "Chrome"; +#elif defined(OS_MACOSX) +const char kProduct[] = "Chrome_Mac"; +#elif defined(OS_LINUX) +const char kProduct[] = "Chrome_Linux"; +#elif defined(OS_ANDROID) +const char kProduct[] = "Chrome_Android"; +#elif defined(OS_CHROMEOS) +const char kProduct[] = "Chrome_ChromeOS"; +#else +#error Platform not supported. +#endif + +// TODO(crbug.com/775415): Update comment to reflect new policy when discarding +// the command line flag. +constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("webrtc_event_log_uploader", R"( + semantics { + sender: "WebRTC Event Log uploader module" + description: + "Uploads a WebRTC event log to a server called Crash. These logs " + "will not contain private information. They will be used to " + "improve WebRTC (fix bugs, tune performance, etc.)." + trigger: + "A privileged JS application (Hangouts/Meet) has requested a peer " + "connection to be logged, and the resulting event log to be " + "uploaded at a time deemed to cause the least interference to the " + "user (i.e., when the user is not busy making other VoIP calls)." + data: + "WebRTC events such as the timing of audio playout (but not the " + "content), timing and size of RTP packets sent/received, etc." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: "This feature is only enabled if the user launches Chrome " + "with a specific command line flag: " + "--enable-features=WebRtcRemoteEventLog" + policy_exception_justification: + "Not applicable." + })"); + +void AddFileContents(const std::string& file_contents, + const std::string& content_type, + std::string* post_data) { + // net::AddMultipartValueForUpload does almost what we want to do here, except + // that it does not add the "filename" attribute. We hack it to force it to. + std::string mime_value_name = base::StringPrintf( + "%s\"; filename=\"%s.%s\"", kLogFilename, kLogFilename, kLogExtension); + net::AddMultipartValueForUpload(mime_value_name, file_contents, kBoundary, + content_type, post_data); } +std::string MimeContentType() { + const char kBoundaryKeywordAndMisc[] = "; boundary="; + + std::string content_type; + content_type.reserve(sizeof(content_type) + sizeof(kBoundaryKeywordAndMisc) + + sizeof(kBoundary)); + + content_type.append(kUploadContentType); + content_type.append(kBoundaryKeywordAndMisc); + content_type.append(kBoundary); + + return content_type; +} +} // namespace + +const char WebRtcEventLogUploaderImpl::kUploadURL[] = + "https://clients2.google.com/cr/report"; + std::unique_ptr<WebRtcEventLogUploader> WebRtcEventLogUploaderImpl::Factory::Create( const base::FilePath& log_file, WebRtcEventLogUploaderObserver* observer) { - return std::make_unique<WebRtcEventLogUploaderImpl>(log_file, observer); + DCHECK(observer); + return std::make_unique<WebRtcEventLogUploaderImpl>( + log_file, observer, kMaxRemoteLogFileSizeBytes); +} + +std::unique_ptr<WebRtcEventLogUploader> +WebRtcEventLogUploaderImpl::Factory::CreateWithCurstomMaxSizeForTesting( + const base::FilePath& log_file, + WebRtcEventLogUploaderObserver* observer, + size_t max_log_file_size_bytes) { + DCHECK(observer); + return std::make_unique<WebRtcEventLogUploaderImpl>(log_file, observer, + max_log_file_size_bytes); +} + +WebRtcEventLogUploaderImpl::Delegate::Delegate( + WebRtcEventLogUploaderImpl* owner) + : owner_(owner) {} + +void WebRtcEventLogUploaderImpl::Delegate::OnURLFetchComplete( + const net::URLFetcher* source) { + owner_->OnURLFetchComplete(source); +} + +WebRtcEventLogUploaderImpl::WebRtcEventLogUploaderImpl( + const base::FilePath& log_file, + WebRtcEventLogUploaderObserver* observer, + size_t max_log_file_size_bytes) + : delegate_(this), + log_file_(log_file), + observer_(observer), + max_log_file_size_bytes_(max_log_file_size_bytes), + request_context_getter_(nullptr), + io_task_runner_(base::SequencedTaskRunnerHandle::Get()) { + DCHECK(observer); + + if (!PrepareUploadData()) { + ReportResult(false); + return; + } + + // See the comment at the beginning of this file for an explanation about why + // base::Unretained is safe to use here. + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&WebRtcEventLogUploaderImpl::PrepareRequestContext, + base::Unretained(this))); +} + +WebRtcEventLogUploaderImpl::~WebRtcEventLogUploaderImpl() { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + // WebRtcEventLogUploaderImpl objects only deleted if either: + // 1. The upload was never started, meaning |url_fetcher_| was never set. + // 2. Upload started and finished. + // Therefore, we can be sure that when we destroy this object, there are no + // tasks pending that still hold a base::Unretained() reference to it. + DCHECK(!url_fetcher_); +} + +bool WebRtcEventLogUploaderImpl::PrepareUploadData() { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + + // TODO(crbug.com/775415): Avoid reading the entire file into memory. + std::string log_file_contents; + if (!base::ReadFileToStringWithMaxSize(log_file_, &log_file_contents, + max_log_file_size_bytes_)) { + LOG(WARNING) << "Couldn't read event log file, or max file size exceeded."; + return false; + } + + DCHECK(post_data_.empty()); + post_data_.reserve(log_file_contents.size() + kExpectedMimeOverheadBytes); + net::AddMultipartValueForUpload("prod", kProduct, kBoundary, "", &post_data_); + net::AddMultipartValueForUpload("ver", + version_info::GetVersionNumber() + "-webrtc", + kBoundary, "", &post_data_); + net::AddMultipartValueForUpload("guid", "0", kBoundary, "", &post_data_); + net::AddMultipartValueForUpload("type", kLogFilename, kBoundary, "", + &post_data_); + AddFileContents(log_file_contents, "application/log", &post_data_); + net::AddMultipartFinalDelimiterForUpload(kBoundary, &post_data_); + + return true; +} + +void WebRtcEventLogUploaderImpl::PrepareRequestContext() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // system_request_context() can only be gotten on the UI thread, but can + // then be used by any thread. + DCHECK(!request_context_getter_); + request_context_getter_ = g_browser_process->system_request_context(); + // In unit tests, request_context_getter_ will remain null. + + // See the comment at the beginning of this file for an explanation about why + // base::Unretained is safe to use here. + io_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&WebRtcEventLogUploaderImpl::StartUpload, + base::Unretained(this))); +} + +void WebRtcEventLogUploaderImpl::StartUpload() { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + + url_fetcher_ = net::URLFetcher::Create( + GURL(kUploadURL), net::URLFetcher::POST, &delegate_, kTrafficAnnotation); + url_fetcher_->SetRequestContext(request_context_getter_); + url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DO_NOT_SEND_COOKIES); + url_fetcher_->SetUploadData(MimeContentType(), post_data_); + url_fetcher_->Start(); // Delegat::OnURLFetchComplete called when finished. +} + +void WebRtcEventLogUploaderImpl::OnURLFetchComplete( + const net::URLFetcher* source) { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_EQ(source, url_fetcher_.get()); + + const bool upload_successful = + (source->GetStatus().status() == net::URLRequestStatus::SUCCESS && + source->GetResponseCode() == net::HTTP_OK); + + if (upload_successful) { + // TODO(crbug.com/775415): Update chrome://webrtc-logs. + std::string report_id; + if (!url_fetcher_->GetResponseAsString(&report_id)) { + LOG(WARNING) << "WebRTC event log completed, but report ID unknown."; + } else { + // TODO(crbug.com/775415): Remove this when chrome://webrtc-logs updated. + VLOG(1) << "WebRTC event log successfully uploaded: " << report_id; + } + } else { + LOG(WARNING) << "WebRTC event log upload failed."; + } + + ReportResult(upload_successful); + + url_fetcher_.reset(); // Explicitly maintain determinant. +} + +void WebRtcEventLogUploaderImpl::ReportResult(bool result) { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + + // If the upload was successful, the file is no longer needed. + // If the upload failed, we don't want to retry, because we run the risk of + // uploading significant amounts of data once again, only for the upload to + // fail again after (as an example) wasting 50MBs of upload bandwidth. + // TODO(crbug.com/775415): Provide refined retrial behavior. + DeleteLogFile(); + + observer_->OnWebRtcEventLogUploadComplete(log_file_, result); +} + +void WebRtcEventLogUploaderImpl::DeleteLogFile() { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); + const bool deletion_successful = + base::DeleteFile(log_file_, /*recursive=*/false); + if (!deletion_successful) { + // This is a somewhat serious (though unlikely) error, because now we'll + // try to upload this file again next time Chrome launches. + LOG(ERROR) << "Could not delete pending WebRTC event log file."; + } }
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.h b/chrome/browser/media/webrtc/webrtc_event_log_uploader.h index 0fbc946..5fe67041 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.h +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.h
@@ -6,14 +6,23 @@ #define CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_EVENT_LOG_UPLOADER_H_ #include <memory> +#include <string> #include "base/files/file_path.h" +#include "base/sequenced_task_runner.h" +#include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_fetcher_delegate.h" + +namespace net { +class URLRequestContextGetter; +} // namespace net // A class implementing this interace can register for notification of an // upload's eventual result (success/failure). class WebRtcEventLogUploaderObserver { public: - virtual void OnWebRtcEventLogUploadComplete(const base::FilePath& file_path, + virtual void OnWebRtcEventLogUploadComplete(const base::FilePath& log_file, bool upload_successful) = 0; protected: @@ -27,8 +36,6 @@ // of the upload. class WebRtcEventLogUploader { public: - virtual ~WebRtcEventLogUploader() = default; - // Since we'll need more than one instance of the abstract // WebRtcEventLogUploader, we'll need an abstract factory for it. class Factory { @@ -39,18 +46,20 @@ // rather than be memorized by the factory's constructor, because factories // created by unit tests have no visibility into the real implementation's // observer (WebRtcRemoteEventLogManager). + // This takes ownership of the file. The caller must not attempt to access + // the file after invoking Create(). virtual std::unique_ptr<WebRtcEventLogUploader> Create( const base::FilePath& log_file, WebRtcEventLogUploaderObserver* observer) = 0; }; + + virtual ~WebRtcEventLogUploader() = default; }; +// Primary implementation of WebRtcEventLogUploader. Uploads log files to crash. +// Deletes log files whether they were successfully uploaded or not. class WebRtcEventLogUploaderImpl : public WebRtcEventLogUploader { public: - WebRtcEventLogUploaderImpl(const base::FilePath& path, - WebRtcEventLogUploaderObserver* observer); - ~WebRtcEventLogUploaderImpl() override = default; - class Factory : public WebRtcEventLogUploader::Factory { public: ~Factory() override = default; @@ -58,7 +67,90 @@ std::unique_ptr<WebRtcEventLogUploader> Create( const base::FilePath& log_file, WebRtcEventLogUploaderObserver* observer) override; + + protected: + friend class WebRtcEventLogUploaderImplTest; + + std::unique_ptr<WebRtcEventLogUploader> CreateWithCurstomMaxSizeForTesting( + const base::FilePath& log_file, + WebRtcEventLogUploaderObserver* observer, + size_t max_remote_log_file_size_bytes); }; + + WebRtcEventLogUploaderImpl(const base::FilePath& log_file, + WebRtcEventLogUploaderObserver* observer, + size_t max_remote_log_file_size_bytes); + ~WebRtcEventLogUploaderImpl() override; + + protected: + friend class WebRtcEventLogUploaderImplTest; + + // Prepare the data that will be uploaded. Runs on io_task_runner_. + bool PrepareUploadData(); + + // Prepares the URLRequestContextGetter. This has to run on the UI thread, + // but once complete, the URLRequestContextGetter it produces, which is + // stored in request_context_getter_, may be used on any task context. + void PrepareRequestContext(); + + // Initiates the upload. Runs on io_task_runner_, so that the callback will + // also be called on io_task_runner_. + void StartUpload(); + + // Called on io_task_runner_. Before this is called, other methods of the + // URLFetcherDelegate API may be called, but this is guaranteed to be the + // last call, so deleting |this| is permissible afterwards. + void OnURLFetchComplete(const net::URLFetcher* source); + + // Cleanup and reporting to |observer_|. + void ReportResult(bool result); + + // Remove the log file which is owned by |this|. + void DeleteLogFile(); + + // Allows testing the behavior for excessively large files. + void SetMaxRemoteLogFileSizeBytesForTesting(size_t max_size_bytes); + + // The URL used for uploading the logs. + static const char kUploadURL[]; + + private: + class Delegate : public net::URLFetcherDelegate { + public: + explicit Delegate(WebRtcEventLogUploaderImpl* owner); + ~Delegate() override = default; + + // net::URLFetcherDelegate implementation. + void OnURLFetchComplete(const net::URLFetcher* source) override; + + private: + WebRtcEventLogUploaderImpl* const owner_; + } delegate_; + + // The path to the WebRTC event log file that this uploader is in charge of. + const base::FilePath log_file_; + + // The observer to be notified when this upload succeeds or fails. + WebRtcEventLogUploaderObserver* const observer_; + + // Maximum allowed file size. In production code, this is a hard-coded, + // but unit tests may set other values. + const size_t max_log_file_size_bytes_; + + // This is written to on the UI thread, but used on the IO thread. It allows + // the creation of URLFetcher objects. + net::URLRequestContextGetter* request_context_getter_; + + // This object is in charge of the actual upload. + std::unique_ptr<net::URLFetcher> url_fetcher_; + + // To avoid an unnecessary hop to the UI thread when something is amiss with + // the data we wish to upload, PrepareUploadData() is called first, and saves + // the data here. When back from the UI thread, StartUpload will read this. + std::string post_data_; + + // The object lives on this IO-capable task runner. + scoped_refptr<base::SequencedTaskRunner> io_task_runner_; }; #endif // CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_EVENT_LOG_UPLOADER_H_
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc new file mode 100644 index 0000000..4351f56 --- /dev/null +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc
@@ -0,0 +1,236 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/webrtc/webrtc_event_log_uploader.h" + +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/task_scheduler/post_task.h" +#include "build/build_config.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "net/http/http_status_code.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "net/url_request/url_request_status.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::StrictMock; + +namespace { +class MockWebRtcEventLogUploaderObserver + : public WebRtcEventLogUploaderObserver { + public: + explicit MockWebRtcEventLogUploaderObserver( + base::OnceClosure completion_closure) + : completion_closure_(std::move(completion_closure)) {} + + ~MockWebRtcEventLogUploaderObserver() override = default; + + // Combines the mock functionality via a helper (CompletionCallback), as well + // as calls the completion closure. + void OnWebRtcEventLogUploadComplete(const base::FilePath& log_file, + bool upload_successful) { + CompletionCallback(log_file, upload_successful); + std::move(completion_closure_).Run(); + } + + MOCK_METHOD2(CompletionCallback, void(const base::FilePath&, bool)); + + private: + base::OnceClosure completion_closure_; +}; + +#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +void RemovePermissions(const base::FilePath& path, int removed_permissions) { + int permissions; + ASSERT_TRUE(base::GetPosixFilePermissions(path, &permissions)); + permissions &= ~removed_permissions; + ASSERT_TRUE(base::SetPosixFilePermissions(path, permissions)); +} + +void RemoveReadPermissions(const base::FilePath& path) { + constexpr int read_permissions = base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_READ_BY_GROUP | + base::FILE_PERMISSION_READ_BY_OTHERS; + RemovePermissions(path, read_permissions); +} + +void RemoveWritePermissions(const base::FilePath& path) { + constexpr int write_permissions = base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_WRITE_BY_GROUP | + base::FILE_PERMISSION_WRITE_BY_OTHERS; + RemovePermissions(path, write_permissions); +} +#endif // defined(OS_POSIX) && !defined(OS_FUCHSIA) +} // namespace + +class WebRtcEventLogUploaderImplTest : public ::testing::Test { + public: + WebRtcEventLogUploaderImplTest() + : observer_run_loop_(), + url_fetcher_factory_(nullptr), + observer_(observer_run_loop_.QuitWhenIdleClosure()), + task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {} + ~WebRtcEventLogUploaderImplTest() override = default; + + void SetUp() override { + ASSERT_TRUE(log_dir_.CreateUniqueTempDir()); + ASSERT_TRUE(base::CreateTemporaryFileInDir(log_dir_.GetPath(), &log_file_)); + constexpr size_t kLogFileSizeBytes = 100u; + const std::string file_contents(kLogFileSizeBytes, 'A'); + ASSERT_EQ( + base::WriteFile(log_file_, file_contents.c_str(), file_contents.size()), + static_cast<int>(file_contents.size())); + } + + void TearDown() override { + base::RunLoop tear_down_run_loop; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](WebRtcEventLogUploaderImplTest* test, + base::OnceClosure quit_closure) { + test->uploader_.reset(); + std::move(quit_closure).Run(); + }, + base::Unretained(this), tear_down_run_loop.QuitWhenIdleClosure())); + tear_down_run_loop.Run(); + } + + void SetUrlFetcherResponse(net::HttpStatusCode http_code, + net::URLRequestStatus::Status request_status) { + const std::string kResponseId = "ec1ed029734b8f7e"; // Arbitrary. + url_fetcher_factory_.SetFakeResponse( + GURL(WebRtcEventLogUploaderImpl::kUploadURL), kResponseId, http_code, + request_status); + } + + void StartAndWaitForUpload() { + task_runner_->PostTask( + FROM_HERE, base::BindOnce( + [](WebRtcEventLogUploaderImplTest* test) { + test->uploader_ = test->uploader_factory_.Create( + test->log_file_, &test->observer_); + }, + base::Unretained(this))); + observer_run_loop_.Run(); // Observer was given quit-closure by ctor. + } + + void StartAndWaitForUploadWithCustomMaxSize(size_t max_log_size_bytes) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](WebRtcEventLogUploaderImplTest* test, + size_t max_log_size_bytes) { + test->uploader_ = + test->uploader_factory_.CreateWithCurstomMaxSizeForTesting( + test->log_file_, &test->observer_, max_log_size_bytes); + }, + base::Unretained(this), max_log_size_bytes)); + observer_run_loop_.Run(); // Observer was given quit-closure by ctor. + } + + content::TestBrowserThreadBundle test_browser_thread_bundle_; + base::RunLoop observer_run_loop_; + + base::ScopedTempDir log_dir_; + base::FilePath log_file_; + + net::FakeURLFetcherFactory url_fetcher_factory_; + + StrictMock<MockWebRtcEventLogUploaderObserver> observer_; + + // These (uploader-factory and uploader) are the units under test. + WebRtcEventLogUploaderImpl::Factory uploader_factory_; + std::unique_ptr<WebRtcEventLogUploader> uploader_; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; +}; + +TEST_F(WebRtcEventLogUploaderImplTest, SuccessfulUploadReportedToObserver) { + // Main test. + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::SUCCESS); + EXPECT_CALL(observer_, CompletionCallback(log_file_, true)).Times(1); + StartAndWaitForUpload(); + EXPECT_FALSE(base::PathExists(log_file_)); +} + +// Version #1 - request reported as successful, but got an error (404) as the +// HTTP return code. +// Due to the simplicitly of both tests, this also tests the scenario +// FileDeletedAfterUnsuccessfulUpload, rather than giving each its own test. +TEST_F(WebRtcEventLogUploaderImplTest, UnsuccessfulUploadReportedToObserver1) { + SetUrlFetcherResponse(net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS); + EXPECT_CALL(observer_, CompletionCallback(log_file_, false)).Times(1); + StartAndWaitForUpload(); + EXPECT_FALSE(base::PathExists(log_file_)); +} + +// Version #2 - request reported as failed; HTTP return code ignored, even +// if it's a purported success. +TEST_F(WebRtcEventLogUploaderImplTest, UnsuccessfulUploadReportedToObserver2) { + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::FAILED); + EXPECT_CALL(observer_, CompletionCallback(log_file_, false)).Times(1); + StartAndWaitForUpload(); + EXPECT_FALSE(base::PathExists(log_file_)); +} + +#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +TEST_F(WebRtcEventLogUploaderImplTest, FailureToReadFileReportedToObserver) { + // Show the failure was independent of the URLFetcher's primed return value. + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::SUCCESS); + + RemoveReadPermissions(log_file_); + EXPECT_CALL(observer_, CompletionCallback(log_file_, false)).Times(1); + StartAndWaitForUpload(); +} + +TEST_F(WebRtcEventLogUploaderImplTest, FailureToDeleteFileHandledGracefully) { + // Prepare for end of test cleanup. + int permissions; + ASSERT_TRUE(base::GetPosixFilePermissions(log_dir_.GetPath(), &permissions)); + + // The uploader won't be able to delete the file, but it would be able to + // read and upload it. + RemoveWritePermissions(log_dir_.GetPath()); + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::SUCCESS); + EXPECT_CALL(observer_, CompletionCallback(log_file_, true)).Times(1); + StartAndWaitForUpload(); + + // Sanity over the test itself - the file really could not be deleted. + ASSERT_TRUE(base::PathExists(log_file_)); + + // Cleaup + ASSERT_TRUE(base::SetPosixFilePermissions(log_dir_.GetPath(), permissions)); +} +#endif // defined(OS_POSIX) && !defined(OS_FUCHSIA) + +TEST_F(WebRtcEventLogUploaderImplTest, FilesUpToMaxSizeUploaded) { + int64_t log_file_size_bytes; + ASSERT_TRUE(base::GetFileSize(log_file_, &log_file_size_bytes)); + + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::SUCCESS); + EXPECT_CALL(observer_, CompletionCallback(log_file_, true)).Times(1); + StartAndWaitForUploadWithCustomMaxSize(log_file_size_bytes); + EXPECT_FALSE(base::PathExists(log_file_)); +} + +TEST_F(WebRtcEventLogUploaderImplTest, ExcessivelyLargeFilesNotUploaded) { + int64_t log_file_size_bytes; + ASSERT_TRUE(base::GetFileSize(log_file_, &log_file_size_bytes)); + + SetUrlFetcherResponse(net::HTTP_OK, net::URLRequestStatus::SUCCESS); + EXPECT_CALL(observer_, CompletionCallback(log_file_, false)).Times(1); + StartAndWaitForUploadWithCustomMaxSize(log_file_size_bytes - 1); + EXPECT_FALSE(base::PathExists(log_file_)); +}
diff --git a/chrome/browser/notifications/notification_platform_bridge_win.cc b/chrome/browser/notifications/notification_platform_bridge_win.cc index 6d848b1..dc0265893 100644 --- a/chrome/browser/notifications/notification_platform_bridge_win.cc +++ b/chrome/browser/notifications/notification_platform_bridge_win.cc
@@ -739,19 +739,18 @@ } // static -bool NotificationPlatformBridgeWin::HandleActivation() { +bool NotificationPlatformBridgeWin::HandleActivation( + const base::CommandLine& command_line) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - std::string launch_id_str = - command_line->GetSwitchValueASCII(switches::kNotificationLaunchId); - NotificationLaunchId launch_id(launch_id_str); + NotificationLaunchId launch_id( + command_line.GetSwitchValueASCII(switches::kNotificationLaunchId)); if (!launch_id.is_valid()) return false; base::Optional<base::string16> reply; base::string16 inline_reply = - command_line->GetSwitchValueNative(switches::kNotificationInlineReply); + command_line.GetSwitchValueNative(switches::kNotificationInlineReply); if (!inline_reply.empty()) reply = inline_reply;
diff --git a/chrome/browser/notifications/notification_platform_bridge_win.h b/chrome/browser/notifications/notification_platform_bridge_win.h index 9c3a5f9..876f491 100644 --- a/chrome/browser/notifications/notification_platform_bridge_win.h +++ b/chrome/browser/notifications/notification_platform_bridge_win.h
@@ -14,6 +14,10 @@ #include "base/sequenced_task_runner.h" #include "chrome/browser/notifications/notification_platform_bridge.h" +namespace base { +class CommandLine; +} + class NotificationPlatformBridgeWinImpl; class NotificationTemplateBuilder; @@ -38,9 +42,11 @@ const GetDisplayedNotificationsCallback& callback) const override; void SetReadyCallback(NotificationBridgeReadyCallback callback) override; - // Handles notification activation from the notification_helper process. - // Returns false if the launch id, passed via the command line, is invalid. - static bool HandleActivation(); + // Handles notification activation encoded in |command_line| from the + // notification_helper process. + // Returns false if |command_line| does not contain a valid + // notification-launch-id switch. + static bool HandleActivation(const base::CommandLine& command_line); // Extracts the profile ID from |launch_id_str|. static std::string GetProfileIdFromLaunchId(const std::string& launch_id_str);
diff --git a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc index 70e46d3..c501da3 100644 --- a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc +++ b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
@@ -8,6 +8,7 @@ #include "base/android/jni_string.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/guid.h" #include "base/logging.h" #include "base/memory/ptr_util.h" @@ -107,10 +108,6 @@ return tab->web_contents(); } -void SavePageLaterCallback(AddRequestResult result) { - // do nothing. -} - void SavePageIfNotNavigatedAway(const GURL& url, const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, @@ -147,8 +144,8 @@ RequestCoordinator::RequestAvailability::DISABLED_FOR_OFFLINER; params.original_url = original_url; params.request_origin = origin; - request_id = request_coordinator->SavePageLater( - params, base::Bind(&SavePageLaterCallback)); + request_id = + request_coordinator->SavePageLater(params, base::DoNothing()); } else { DVLOG(1) << "SavePageIfNotNavigatedAway has no valid coordinator."; }
diff --git a/chrome/browser/offline_pages/offline_page_tab_helper.cc b/chrome/browser/offline_pages/offline_page_tab_helper.cc index 4be14cc..501e5af 100644 --- a/chrome/browser/offline_pages/offline_page_tab_helper.cc +++ b/chrome/browser/offline_pages/offline_page_tab_helper.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/offline_pages/offline_page_tab_helper.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/guid.h" #include "base/logging.h" #include "base/memory/ptr_util.h" @@ -41,10 +42,6 @@ #endif return url.SchemeIsFile(); } - -void SavePageLaterCallback(AddRequestResult result) { - // do nothing. -} } // namespace OfflinePageTabHelper::LoadedOfflinePageInfo::LoadedOfflinePageInfo() @@ -388,8 +385,7 @@ params.url = url; params.client_id = offline_pages::ClientId(name_space, base::GenerateGUID()); params.request_origin = request_origin; - request_coordinator->SavePageLater(params, - base::Bind(&SavePageLaterCallback)); + request_coordinator->SavePageLater(params, base::DoNothing()); if (static_cast<int>(ui_action) & static_cast<int>(OfflinePageUtils::DownloadUIActionFlags::
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc index b40b3d8a..581e35a 100644 --- a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc +++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
@@ -9,11 +9,13 @@ #include <utility> #include "base/logging.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" #include "components/download/public/background_service/download_metadata.h" #include "components/offline_pages/core/prefetch/prefetch_downloader.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" +#include "services/network/public/cpp/resource_request_body.h" namespace offline_pages { @@ -99,6 +101,13 @@ return true; } +void OfflinePrefetchDownloadClient::GetUploadData( + const std::string& guid, + download::GetUploadDataCallback callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); +} + PrefetchDownloader* OfflinePrefetchDownloadClient::GetPrefetchDownloader() const { PrefetchService* prefetch_service =
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h index 2ba25d9..2f439c8 100644 --- a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h +++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h
@@ -45,6 +45,8 @@ const download::CompletionInfo& completion_info) override; bool CanServiceRemoveDownloadedFile(const std::string& guid, bool force_delete) override; + void GetUploadData(const std::string& guid, + download::GetUploadDataCallback callback) override; PrefetchDownloader* GetPrefetchDownloader() const;
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h index 3e8d25b..99deff3 100644 --- a/chrome/browser/password_manager/password_manager_test_base.h +++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "chrome/browser/ssl/cert_verifier_browser_test.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "content/public/browser/web_contents_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -208,6 +209,7 @@ net::EmbeddedTestServer& https_test_server() { return https_test_server_; } private: + test::ScopedMacViewsBrowserMode views_mode_{true}; net::EmbeddedTestServer https_test_server_; // A tab with some hooks injected. content::WebContents* web_contents_;
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.cc b/chrome/browser/payments/chrome_payment_request_delegate.cc index 2b3262a..54f2c34 100644 --- a/chrome/browser/payments/chrome_payment_request_delegate.cc +++ b/chrome/browser/payments/chrome_payment_request_delegate.cc
@@ -26,6 +26,7 @@ #include "components/autofill/core/browser/region_data_loader_impl.h" #include "components/keyed_service/core/service_access_type.h" #include "components/payments/content/payment_manifest_web_data_service.h" +#include "components/payments/content/payment_request.h" #include "components/payments/content/payment_request_dialog.h" #include "components/payments/core/payment_prefs.h" #include "components/signin/core/browser/signin_manager.h" @@ -53,31 +54,35 @@ ChromePaymentRequestDelegate::ChromePaymentRequestDelegate( content::WebContents* web_contents) - : dialog_(nullptr), web_contents_(web_contents) {} + : shown_dialog_(nullptr), web_contents_(web_contents) {} ChromePaymentRequestDelegate::~ChromePaymentRequestDelegate() {} void ChromePaymentRequestDelegate::ShowDialog(PaymentRequest* request) { - DCHECK_EQ(nullptr, dialog_); - dialog_ = chrome::CreatePaymentRequestDialog(request); - dialog_->ShowDialog(); + DCHECK_EQ(nullptr, shown_dialog_); + hidden_dialog_ = std::unique_ptr<PaymentRequestDialog>( + chrome::CreatePaymentRequestDialog(request)); + MaybeShowHiddenDialog(request); } void ChromePaymentRequestDelegate::CloseDialog() { - if (dialog_) { - dialog_->CloseDialog(); - dialog_ = nullptr; + if (shown_dialog_) { + shown_dialog_->CloseDialog(); + shown_dialog_ = nullptr; } + + if (hidden_dialog_) + hidden_dialog_.reset(); } void ChromePaymentRequestDelegate::ShowErrorMessage() { - if (dialog_) - dialog_->ShowErrorMessage(); + if (shown_dialog_) + shown_dialog_->ShowErrorMessage(); } void ChromePaymentRequestDelegate::ShowProcessingSpinner() { - if (dialog_) - dialog_->ShowProcessingSpinner(); + if (shown_dialog_) + shown_dialog_->ShowProcessingSpinner(); } autofill::PersonalDataManager* @@ -111,7 +116,9 @@ const autofill::CreditCard& credit_card, base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> result_delegate) { - dialog_->ShowCvcUnmaskPrompt(credit_card, result_delegate, web_contents_); + if (shown_dialog_) + shown_dialog_->ShowCvcUnmaskPrompt(credit_card, result_delegate, + web_contents_); } autofill::RegionDataLoader* @@ -171,10 +178,26 @@ void ChromePaymentRequestDelegate::EmbedPaymentHandlerWindow( const GURL& url, PaymentHandlerOpenWindowCallback callback) { - if (dialog_) - dialog_->ShowPaymentHandlerScreen(url, std::move(callback)); - else - std::move(callback).Run(false, 0, 0); + if (hidden_dialog_) { + shown_dialog_ = hidden_dialog_.release(); + shown_dialog_->ShowDialogAtPaymentHandlerSheet(url, std::move(callback)); + } else if (shown_dialog_) { + shown_dialog_->ShowPaymentHandlerScreen(url, std::move(callback)); + } else { + std::move(callback).Run(/*success=*/false, + /*render_process_id=*/0, + /*render_frame_id=*/0); + } +} + +void ChromePaymentRequestDelegate::MaybeShowHiddenDialog( + PaymentRequest* request) { + if (request->SatisfiesSkipUIConstraints()) { + request->Pay(); + } else { + shown_dialog_ = hidden_dialog_.release(); + shown_dialog_->ShowDialog(); + } } } // namespace payments
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.h b/chrome/browser/payments/chrome_payment_request_delegate.h index 6157bcc..761c1c6 100644 --- a/chrome/browser/payments/chrome_payment_request_delegate.h +++ b/chrome/browser/payments/chrome_payment_request_delegate.h
@@ -54,8 +54,24 @@ protected: // Reference to the dialog so that we can satisfy calls to CloseDialog(). This // reference is invalid once CloseDialog() has been called on it, because the - // dialog will be destroyed. Protected for testing. - PaymentRequestDialog* dialog_; + // dialog will be destroyed. Owned by the views:: dialog machinery. Protected + // for testing. + PaymentRequestDialog* shown_dialog_; + + // The instance of the dialog that was created but not shown yet. Since it + // hasn't been shown, it's still owned by it's creator. This is non null only + // when the current Payment Request supports skipping the payment sheet (see + // PaymentRequest::SatisfiesSkipUIConstraints) and is reset once the + // underlying pointer becomes owned by the views:: machinery (when the dialog + // is shown). + std::unique_ptr<PaymentRequestDialog> hidden_dialog_; + + // Shows |hidden_dialog_| if the current Payment Request doesn't support the + // skip UI flow. This also transfer its ownership to the views dialog code and + // keep a reference to it in |shown_dialog_|. + // Otherwise, this calls Pay() on the current Payment Request to allow the + // skip UI flow to carry on. + void MaybeShowHiddenDialog(PaymentRequest* request); private: // Not owned but outlives the PaymentRequest object that owns this.
diff --git a/chrome/browser/predictors/preconnect_manager.cc b/chrome/browser/predictors/preconnect_manager.cc index 298d0f0..bf278c2 100644 --- a/chrome/browser/predictors/preconnect_manager.cc +++ b/chrome/browser/predictors/preconnect_manager.cc
@@ -6,11 +6,14 @@ #include <utility> +#include "base/trace_event/trace_event.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_hints.h" #include "net/base/net_errors.h" #include "net/http/transport_security_state.h" +#include "net/proxy_resolution/proxy_info.h" +#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/url_request/url_request_context.h" namespace predictors { @@ -160,9 +163,16 @@ PreresolveInfo* info = job.info; if (!info || !info->was_canceled) { - int status = PreresolveUrl( - job.url, base::Bind(&PreconnectManager::OnPreresolveFinished, - weak_factory_.GetWeakPtr(), job)); + int status; + if (WouldLikelyProxyURL(job.url)) { + // Skip preresolve and go straight to preconnect if a proxy is enabled. + status = net::OK; + } else { + status = PreresolveUrl( + job.url, base::Bind(&PreconnectManager::OnPreresolveFinished, + weak_factory_.GetWeakPtr(), job)); + } + if (status == net::ERR_IO_PENDING) { // Will complete asynchronously. if (info) @@ -243,4 +253,17 @@ return url.ReplaceComponents(replacements); } +bool PreconnectManager::WouldLikelyProxyURL(const GURL& url) const { + auto* proxy_resolution_service = + context_getter_->GetURLRequestContext()->proxy_resolution_service(); + if (!proxy_resolution_service) + return false; + + net::ProxyInfo info; + bool synchronous_success = + proxy_resolution_service->TryResolveProxySynchronously( + url, std::string(), &info, nullptr, net::NetLogWithSource()); + return synchronous_success && !info.is_direct(); +} + } // namespace predictors
diff --git a/chrome/browser/predictors/preconnect_manager.h b/chrome/browser/predictors/preconnect_manager.h index e7cbb2b..1d80e6d 100644 --- a/chrome/browser/predictors/preconnect_manager.h +++ b/chrome/browser/predictors/preconnect_manager.h
@@ -141,6 +141,7 @@ void FinishPreresolve(const PreresolveJob& job, bool found, bool cached); void AllPreresolvesForUrlFinished(PreresolveInfo* info); GURL GetHSTSRedirect(const GURL& url) const; + bool WouldLikelyProxyURL(const GURL& url) const; base::WeakPtr<Delegate> delegate_; scoped_refptr<net::URLRequestContextGetter> context_getter_;
diff --git a/chrome/browser/predictors/preconnect_manager_unittest.cc b/chrome/browser/predictors/preconnect_manager_unittest.cc index d25f720..a9eddddd 100644 --- a/chrome/browser/predictors/preconnect_manager_unittest.cc +++ b/chrome/browser/predictors/preconnect_manager_unittest.cc
@@ -14,6 +14,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "net/proxy_resolution/mock_proxy_resolver.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -332,4 +335,46 @@ base::RunLoop().RunUntilIdle(); } +class MockProxyConfigService : public net::ProxyConfigService { + public: + explicit MockProxyConfigService(const net::ProxyConfig& config) + : config_(net::ProxyConfigWithAnnotation(config, + TRAFFIC_ANNOTATION_FOR_TESTS)) {} + void AddObserver(Observer* observer) override {} + void RemoveObserver(Observer* observer) override {} + ConfigAvailability GetLatestProxyConfig( + net::ProxyConfigWithAnnotation* results) override { + *results = config_; + return CONFIG_VALID; + } + + private: + net::ProxyConfigWithAnnotation config_; +}; + +// Tests that the predictor doesn't preresolve in the presence of the proxy +// server. +TEST_F(PreconnectManagerTest, TestPreresolveSkippedIfProxyEnabled) { + net::ProxyConfig proxy_config; + proxy_config.proxy_rules().ParseFromString("foopy:8080"); + proxy_config.set_auto_detect(false); + net::ProxyResolutionService proxy_service( + std::make_unique<MockProxyConfigService>(proxy_config), + std::make_unique<net::MockAsyncProxyResolverFactory>(false), nullptr); + context_getter_->GetURLRequestContext()->set_proxy_resolution_service( + &proxy_service); + + GURL main_frame_url("http://google.com"); + GURL url_to_preconnect("http://cdn.google.com"); + GURL url_to_preresolve("http://images.google.com"); + + EXPECT_CALL(*preconnect_manager_, + PreconnectUrl(url_to_preconnect, main_frame_url, 1, true)); + EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url)); + preconnect_manager_->Start(main_frame_url, + {PreconnectRequest(url_to_preconnect, 1), + PreconnectRequest(url_to_preresolve, 0)}); + base::RunLoop().RunUntilIdle(); +} + } // namespace predictors
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index 57f714e..0080f7f 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -33,6 +33,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/omnibox/browser/omnibox_edit_controller.h" #include "components/omnibox/browser/omnibox_edit_model.h" @@ -166,6 +167,9 @@ } } } + + private: + test::ScopedMacViewsBrowserMode views_mode_{true}; }; // A test interstitial page with typical HTML contents. @@ -275,7 +279,7 @@ { false, true, false, true, false } }; - for (int i = 1; i < 3; i++) { + for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { // Activate the tab. browser()->tab_strip_model()->ActivateTabAt(j, true);
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_test_util_views_cocoa.mm b/chrome/browser/ui/cocoa/extensions/browser_action_test_util_views_cocoa.mm index bb2101a..c56c265 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_action_test_util_views_cocoa.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_action_test_util_views_cocoa.mm
@@ -215,6 +215,7 @@ std::unique_ptr<BrowserActionTestUtil> CreateOverflowBar() override; gfx::Size GetMinPopupSize() override; gfx::Size GetMaxPopupSize() override; + bool CanBeResized() override; private: friend class BrowserActionTestUtil; @@ -334,6 +335,12 @@ return GetExtensionPopupTestManager()->GetMaxPopupSize(); } +bool BrowserActionTestUtilCocoa::CanBeResized() { + BrowserActionsContainerView* containerView = + [GetController(browser_, test_helper_.get()) containerView]; + return [containerView canBeResized]; +} + BrowserActionTestUtilCocoa::BrowserActionTestUtilCocoa( Browser* browser, BrowserActionTestUtilCocoa* main_bar)
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 2890c9a..a673e4d 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h
@@ -106,6 +106,9 @@ // Stops any animation in progress. - (void)stopAnimation; +// Returns true if this view is currently resizable. +- (BOOL)canBeResized; + @property(nonatomic) CGFloat minWidth; @property(nonatomic) CGFloat maxWidth; @property(nonatomic) BOOL grippyPinned;
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 251d337..a72edbc 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
@@ -140,7 +140,7 @@ if (highlight || highlight_) { highlight_ = std::move(highlight); // We don't allow resizing when the container is highlighting. - resizable_ = highlight.get() == nullptr; + resizable_ = highlight_.get() == nullptr; [self setNeedsDisplay:YES]; } } @@ -302,6 +302,10 @@ [resizeAnimation_ stopAnimation]; } +- (BOOL)canBeResized { + return resizable_; +} + #pragma mark - #pragma mark Private Methods
diff --git a/chrome/browser/ui/extensions/browser_action_test_util.h b/chrome/browser/ui/extensions/browser_action_test_util.h index 00c051c..f392ed8 100644 --- a/chrome/browser/ui/extensions/browser_action_test_util.h +++ b/chrome/browser/ui/extensions/browser_action_test_util.h
@@ -104,6 +104,9 @@ // Returns the maximum allowed size of an extension popup. virtual gfx::Size GetMaxPopupSize() = 0; + // Returns whether the browser action container can currently be resized. + virtual bool CanBeResized() = 0; + protected: BrowserActionTestUtil() {}
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index 9a9a46ff..47258dd 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -399,7 +399,7 @@ // Launch() call is from notification_helper.exe to process toast activation. // Delegate to the notification system; do not open a browser window here. if (command_line_.HasSwitch(switches::kNotificationLaunchId)) { - if (NotificationPlatformBridgeWin::HandleActivation()) { + if (NotificationPlatformBridgeWin::HandleActivation(command_line_)) { RecordLaunchModeHistogram(LM_WIN_PLATFORM_NOTIFICATION); return true; }
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc index 7bc0fefc..5187060 100644 --- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -19,6 +19,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -86,6 +87,8 @@ } private: + test::ScopedMacViewsBrowserMode views_mode_{true}; + DISALLOW_COPY_AND_ASSIGN(FindInPageTest); };
diff --git a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc index f38b1a2..483e975d 100644 --- a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/location_bar/star_view.h" #include "base/command_line.h" +#include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -16,6 +17,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "components/prefs/pref_service.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -30,7 +32,16 @@ namespace { -typedef InProcessBrowserTest StarViewTest; +class StarViewTest : public InProcessBrowserTest { + public: + StarViewTest() = default; + ~StarViewTest() override = default; + + private: + test::ScopedMacViewsBrowserMode views_mode_{true}; + + DISALLOW_COPY_AND_ASSIGN(StarViewTest); +}; // Verify that clicking the bookmark star a second time hides the bookmark // bubble.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 7fa59e6..2a1e15d53 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -127,6 +127,14 @@ } // namespace //////////////////////////////////////////////////////////////////////////////// +// OmniboxResultView: + +class OmniboxImageView : public views::ImageView { + public: + bool CanProcessEventsWithinSubtree() const override { return false; } +}; + +//////////////////////////////////////////////////////////////////////////////// // OmniboxResultView, public: OmniboxResultView::OmniboxResultView(OmniboxPopupContentsView* model, @@ -139,9 +147,9 @@ font_list.GetHeight(), font_list.DeriveWithWeight(gfx::Font::Weight::BOLD).GetHeight())), animation_(new gfx::SlideAnimation(this)), - icon_view_(AddImageView()), - image_view_(AddImageView()), - keyword_icon_view_(AddImageView()), + icon_view_(AddOmniboxImageView()), + image_view_(AddOmniboxImageView()), + keyword_icon_view_(AddOmniboxImageView()), content_view_(AddOmniboxTextView(font_list)), description_view_(AddOmniboxTextView(font_list)), keyword_content_view_(AddOmniboxTextView(font_list)), @@ -183,9 +191,7 @@ match_ = match.GetMatchWithContentsAndDescriptionPossiblySwapped(); animation_->Reset(); is_hovered_ = false; - icon_view_->SetImage(GetIcon().ToImageSkia()); image_view_->SetVisible(false); // Until SetAnswerImage is called. - keyword_icon_view_->SetVisible(match_.associated_keyword.get()); if (tab_switch_button_) { if (match.type == AutocompleteMatchType::TAB_SEARCH && @@ -220,6 +226,16 @@ SetBackground(CreateBackgroundWithColor(color)); } + // Recreate the icons in case the color needs to change. + // Note: if this is an extension icon or favicon then this can be done in + // SetMatch() once (rather than repeatedly, as happens here). There may + // be an optimization opportunity here. + // TODO(dschuyler): determine whether to optimize the color changes. + icon_view_->SetImage(GetIcon().ToImageSkia()); + keyword_icon_view_->SetImage(gfx::CreateVectorIcon( + omnibox::kKeywordSearchIcon, GetLayoutConstant(LOCATION_BAR_ICON_SIZE), + GetVectorIconColor())); + if (match_.answer) { content_view_->SetText(match_.answer->first_line()); description_view_->SetText(match_.answer->second_line()); @@ -390,8 +406,8 @@ //////////////////////////////////////////////////////////////////////////////// // OmniboxResultView, private: -views::ImageView* OmniboxResultView::AddImageView() { - views::ImageView* view = new views::ImageView(); +OmniboxImageView* OmniboxResultView::AddOmniboxImageView() { + OmniboxImageView* view = new OmniboxImageView(); AddChildView(view); return view; }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h index 001b7de..555b260 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -29,6 +29,7 @@ class Image; } +class OmniboxImageView; class OmniboxTabSwitchButton; class OmniboxTextView; @@ -97,7 +98,7 @@ private: // Create instance and add it as a child. - views::ImageView* AddImageView(); + OmniboxImageView* AddOmniboxImageView(); OmniboxTextView* AddOmniboxTextView(const gfx::FontList& font_list); // Returns the height of the text portion of the result view.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc index be49242e..15fbecba 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -121,6 +121,10 @@ return render_text_->GetStringSize(); } +bool OmniboxTextView::CanProcessEventsWithinSubtree() const { + return false; +} + const char* OmniboxTextView::GetClassName() const { return "OmniboxTextView"; }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.h b/chrome/browser/ui/views/omnibox/omnibox_text_view.h index 743c76c..5c62fa4 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.h
@@ -32,6 +32,7 @@ // views::View. gfx::Size CalculatePreferredSize() const override; + bool CanProcessEventsWithinSubtree() const override; const char* GetClassName() const override; int GetHeightForWidth(int width) const override; void OnPaint(gfx::Canvas* canvas) override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc index 418f3a8..c53283df 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -22,6 +22,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "components/omnibox/browser/omnibox_popup_model.h" #include "components/omnibox/browser/test_scheme_classifier.h" #include "content/public/browser/web_contents.h" @@ -116,6 +117,8 @@ ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); } + test::ScopedMacViewsBrowserMode views_mode_{true}; + DISALLOW_COPY_AND_ASSIGN(OmniboxViewViewsTest); };
diff --git a/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc b/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc index b7dc50a..263c596 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_interactive_uitest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host.h" #include "content/public/common/content_features.h" @@ -93,6 +94,7 @@ } private: + test::ScopedMacViewsBrowserMode views_mode_{true}; base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(PasswordBubbleInteractiveUiTest);
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc index a75b083ab..e02a940 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -141,6 +141,19 @@ constrained_window::ShowWebModalDialogViews(this, request_->web_contents()); } +void PaymentRequestDialogView::ShowDialogAtPaymentHandlerSheet( + const GURL& url, + PaymentHandlerOpenWindowCallback callback) { + view_stack_->Push(CreateViewAndInstallController( + std::make_unique<PaymentHandlerWebFlowViewController>( + request_->spec(), request_->state(), this, + GetProfile(), url, std::move(callback)), + &controller_map_), + /* animate = */ false); + HideProcessingSpinner(); + ShowDialog(); +} + void PaymentRequestDialogView::CloseDialog() { // This calls PaymentRequestDialogView::Cancel() before closing. // ViewHierarchyChanged() also gets called after Cancel().
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h index 652570d..6037b176 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -106,6 +106,9 @@ // payments::PaymentRequestDialog: void ShowDialog() override; + void ShowDialogAtPaymentHandlerSheet( + const GURL& url, + PaymentHandlerOpenWindowCallback callback) override; void CloseDialog() override; void ShowErrorMessage() override; void ShowProcessingSpinner() override;
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc index 7f203003..f1c400c1 100644 --- a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/permissions/permission_request_manager.h" #include "chrome/browser/ui/browser.h" @@ -11,9 +12,11 @@ #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/autofill/core/browser/autofill_test_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/payments/content/service_worker_payment_app_factory.h" +#include "components/payments/core/features.h" #include "components/payments/core/test_payment_manifest_downloader.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" @@ -33,7 +36,7 @@ bobpay_(net::EmbeddedTestServer::TYPE_HTTPS), frankpay_(net::EmbeddedTestServer::TYPE_HTTPS) { scoped_feature_list_.InitAndEnableFeature( - features::kServiceWorkerPaymentApps); + ::features::kServiceWorkerPaymentApps); } PermissionRequestManager* GetPermissionRequestManager() { @@ -73,6 +76,26 @@ << contents; } + // Invokes the JavaScript function install(|method_name|) in + // components/test/data/payments/bobpay.com/app1/index.js, which responds + // back via domAutomationController. + void InstallBobPayForMethod(const std::string& method_name) { + ui_test_utils::NavigateToURL(browser(), + bobpay_.GetURL("bobpay.com", "/app1/")); + + std::string contents; + std::string script = "install('" + method_name + "');"; + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + browser()->tab_strip_model()->GetActiveWebContents(), script, + &contents)) + << "Script execution failed: " << script; + ASSERT_NE(std::string::npos, + contents.find("Payment app for \"" + method_name + + "\" method installed.")) + << method_name << " method install message not found in:\n" + << contents; + } + void BlockAlicePay() { GURL origin = alicepay_.GetURL("alicepay.com", "/app1/").GetOrigin(); HostContentSettingsMapFactory::GetForProfile(browser()->profile()) @@ -366,4 +389,99 @@ } } +IN_PROC_BROWSER_TEST_F(PaymentRequestPaymentAppTest, SkipUIEnabledWithBobPay) { + base::test::ScopedFeatureList features; + features.InitWithFeatures( + { + payments::features::kWebPaymentsSingleAppUiSkip, + ::features::kServiceWorkerPaymentApps, + }, + {}); + InstallBobPayForMethod("https://bobpay.com"); + + { + SetDownloaderAndIgnorePortInAppScopeForTesting(); + + NavigateTo("/payment_request_bobpay_ui_skip_test.html"); + + // Since the skip UI flow is available, the request will complete without + // interaction besides hitting "pay" on the website. + ResetEventWaiterForSequence( + {DialogEvent::DIALOG_OPENED, DialogEvent::DIALOG_CLOSED}); + 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)); + WaitForObservedEvent(); + + ExpectBodyContains({"bobpay.com"}); + } +} + +IN_PROC_BROWSER_TEST_F(PaymentRequestPaymentAppTest, + SkipUIDisabledWithMultipleAcceptedMethods) { + base::test::ScopedFeatureList features; + features.InitWithFeatures( + { + payments::features::kWebPaymentsSingleAppUiSkip, + ::features::kServiceWorkerPaymentApps, + }, + {}); + InstallBobPayForMethod("https://bobpay.com"); + + { + SetDownloaderAndIgnorePortInAppScopeForTesting(); + + NavigateTo("/payment_request_bobpay_test.html"); + + // Since the skip UI flow is not available, the request will complete only + // after clicking on the Pay button in the dialog. + InvokePaymentRequestUI(); + + ResetEventWaiterForSequence( + {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED}); + ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view()); + + ExpectBodyContains({"bobpay.com"}); + } +} + +IN_PROC_BROWSER_TEST_F(PaymentRequestPaymentAppTest, + SkipUIDisabledWithRequestedPayerEmail) { + base::test::ScopedFeatureList features; + features.InitWithFeatures( + { + payments::features::kWebPaymentsSingleAppUiSkip, + ::features::kServiceWorkerPaymentApps, + }, + {}); + InstallBobPayForMethod("https://bobpay.com"); + autofill::AutofillProfile profile(autofill::test::GetFullProfile()); + AddAutofillProfile(profile); + + { + SetDownloaderAndIgnorePortInAppScopeForTesting(); + + NavigateTo("/payment_request_bobpay_ui_skip_test.html"); + + // Since the skip UI flow is not available because the payer's email is + // requested, the request will complete only after clicking on the Pay + // button in the dialog. + ResetEventWaiter(DialogEvent::DIALOG_OPENED); + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_buy_button_js = + "(function() { " + "document.getElementById('buyWithRequestedEmail').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_buy_button_js)); + WaitForObservedEvent(); + EXPECT_TRUE(IsPayButtonEnabled()); + + ResetEventWaiterForSequence( + {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED}); + ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view()); + + ExpectBodyContains({"bobpay.com"}); + } +} + } // namespace payments
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 index a503560..97d498d8 100644 --- a/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.cc +++ b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.cc
@@ -22,10 +22,9 @@ is_browser_window_active_(is_browser_window_active) {} void TestChromePaymentRequestDelegate::ShowDialog(PaymentRequest* request) { - PaymentRequestDialogView* dialog_view = - new PaymentRequestDialogView(request, observer_); - dialog_view->ShowDialog(); - dialog_ = dialog_view; + hidden_dialog_ = + std::make_unique<PaymentRequestDialogView>(request, observer_); + MaybeShowHiddenDialog(request); } bool TestChromePaymentRequestDelegate::IsIncognito() const {
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 index e0d5eaa..4208c5f 100644 --- a/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h +++ b/chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h
@@ -41,7 +41,7 @@ bool IsBrowserWindowActive() const override; PaymentRequestDialogView* dialog_view() { - return static_cast<PaymentRequestDialogView*>(dialog_); + return static_cast<PaymentRequestDialogView*>(shown_dialog_); } private:
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 4fa6e91..815b33ffb 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/profile_chooser_constants.h" #include "chrome/browser/ui/singleton_tabs.h" +#include "chrome/browser/ui/sync/sync_promo_ui.h" #include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" @@ -180,13 +181,18 @@ } BadgedProfilePhoto::BadgeType GetProfileBadgeType(Profile* profile) { - if (!profile->IsSupervised()) { - return AccountConsistencyModeManager::IsDiceEnabledForProfile(profile) - ? BadgedProfilePhoto::BADGE_TYPE_SYNC_COMPLETE - : BadgedProfilePhoto::BADGE_TYPE_NONE; + if (profile->IsSupervised()) { + return profile->IsChild() ? BadgedProfilePhoto::BADGE_TYPE_CHILD + : BadgedProfilePhoto::BADGE_TYPE_SUPERVISOR; } - return profile->IsChild() ? BadgedProfilePhoto::BADGE_TYPE_CHILD - : BadgedProfilePhoto::BADGE_TYPE_SUPERVISOR; + // |Profile::IsSyncAllowed| is needed to check whether sync is allowed by GPO + // policy. + if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile) && + profile->IsSyncAllowed() && + SigninManagerFactory::GetForProfile(profile)->IsAuthenticated()) { + return BadgedProfilePhoto::BADGE_TYPE_SYNC_COMPLETE; + } + return BadgedProfilePhoto::BADGE_TYPE_NONE; } std::vector<gfx::Image> GetImagesForAccounts( @@ -655,9 +661,13 @@ profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT : profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER); } else if (sender == current_profile_card_) { - if (dice_enabled_) { + if (dice_enabled_ && + SigninManagerFactory::GetForProfile(browser_->profile()) + ->IsAuthenticated()) { chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage); } else { + // Open settings to edit profile name and image. The profile doesn't need + // to be authenticated to open this. avatar_menu_->EditProfile(avatar_menu_->GetActiveProfileIndex()); PostActionPerformed(ProfileMetrics::PROFILE_DESKTOP_MENU_EDIT_IMAGE); PostActionPerformed(ProfileMetrics::PROFILE_DESKTOP_MENU_EDIT_NAME); @@ -933,8 +943,10 @@ views::View* ProfileChooserView::CreateCurrentProfileView( const AvatarMenu::Item& avatar_item, bool is_guest) { - if (!avatar_item.signed_in && dice_enabled_) + if (!avatar_item.signed_in && dice_enabled_ && + SyncPromoUI::ShouldShowSyncPromo(browser_->profile())) { return CreateDiceSigninView(); + } ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); @@ -959,8 +971,9 @@ bool show_email = !is_guest && avatar_item.signed_in && !account_consistency_enabled; const base::string16 hover_button_title = - dice_enabled_ ? l10n_util::GetStringUTF16(IDS_PROFILES_SYNCED_TO_TITLE) - : profile_name; + dice_enabled_ && browser_->profile()->IsSyncAllowed() + ? l10n_util::GetStringUTF16(IDS_PROFILES_SYNCED_TO_TITLE) + : profile_name; HoverButton* profile_card = new HoverButton( this, std::move(current_profile_photo), hover_button_title, show_email ? avatar_item.username : base::string16()); @@ -997,9 +1010,8 @@ return view; } - SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile( - browser_->profile()->GetOriginalProfile()); - if (signin_manager->IsSigninAllowed()) { + if (!dice_enabled_ && SigninManagerFactory::GetForProfile(browser_->profile()) + ->IsSigninAllowed()) { views::View* extra_links_view = new views::View(); extra_links_view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kVertical,
diff --git a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc index dd1c3991..ec1caa65 100644 --- a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
@@ -13,6 +13,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/result_codes.h" @@ -126,6 +127,8 @@ } private: + test::ScopedMacViewsBrowserMode views_mode_{true}; + DISALLOW_COPY_AND_ASSIGN(SadTabViewInteractiveUITest); };
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index d394cb5f..ad49921 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -38,6 +38,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_service.h" @@ -551,6 +552,8 @@ Browser* browser() const { return InProcessBrowserTest::browser(); } private: + test::ScopedMacViewsBrowserMode views_mode_{true}; + #if defined(OS_CHROMEOS) std::unique_ptr<ui::test::EventGenerator> event_generator_; #endif
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc index e3edd35..fc5eb8af 100644 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc +++ b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc
@@ -198,6 +198,19 @@ return gfx::Size(ExtensionPopup::kMaxWidth, ExtensionPopup::kMaxHeight); } +bool BrowserActionTestUtilViews::CanBeResized() { + BrowserActionsContainer* container = + BrowserView::GetBrowserViewForBrowser(browser_) + ->toolbar() + ->browser_actions(); + + // The container can only be resized if we can start a drag for the view. + DCHECK_LE(1u, container->num_toolbar_actions()); + ToolbarActionView* action_view = container->GetToolbarActionViewAt(0); + gfx::Point point(action_view->x(), action_view->y()); + return container->CanStartDragForView(action_view, point, point); +} + BrowserActionTestUtilViews::BrowserActionTestUtilViews( Browser* browser, BrowserActionTestUtilViews* main_bar)
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h index 0a67b46..908a3cc6 100644 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h +++ b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h
@@ -32,6 +32,7 @@ std::unique_ptr<BrowserActionTestUtil> CreateOverflowBar() override; gfx::Size GetMinPopupSize() override; gfx::Size GetMaxPopupSize() override; + bool CanBeResized() override; private: friend class BrowserActionTestUtil;
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc index 9a9d0f4..c67312c 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" @@ -27,6 +28,8 @@ #include "ui/views/test/test_views.h" #include "ui/views/view.h" +namespace { + // TODO(devlin): Continue moving any tests that should be platform independent // from this file to the crossplatform tests in // chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc. @@ -34,7 +37,16 @@ // Test that dragging browser actions works, and that dragging a browser action // from the overflow menu results in it "popping" out (growing the container // size by 1), rather than just reordering the extensions. -IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, DragBrowserActions) { + +// The two drag & drop tests are currently restricted to Views browsers in the +// absence of a good way to abstract drag & drop actions. +class BrowserActionsBarViewsBrowserTest : public BrowserActionsBarBrowserTest { + private: + test::ScopedMacViewsBrowserMode views_mode_{true}; +}; +} // namespace + +IN_PROC_BROWSER_TEST_F(BrowserActionsBarViewsBrowserTest, DragBrowserActions) { LoadExtensions(); // Sanity check: All extensions showing; order is A B C. @@ -147,7 +159,7 @@ // Test that changes performed in one container affect containers in other // windows so that it is consistent. -IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, MultipleWindows) { +IN_PROC_BROWSER_TEST_F(BrowserActionsBarViewsBrowserTest, MultipleWindows) { LoadExtensions(); BrowserActionsContainer* first = BrowserView::GetBrowserViewForBrowser(browser())->toolbar()-> @@ -214,16 +226,7 @@ EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - - BrowserActionsContainer* container = - BrowserView::GetBrowserViewForBrowser(browser()) - ->toolbar()->browser_actions(); - - // Currently, dragging should be enabled. - ToolbarActionView* action_view = container->GetToolbarActionViewAt(0); - ASSERT_TRUE(action_view); - gfx::Point point(action_view->x(), action_view->y()); - EXPECT_TRUE(container->CanStartDragForView(action_view, point, point)); + EXPECT_TRUE(browser_actions_bar()->CanBeResized()); std::vector<std::string> action_ids; action_ids.push_back(extension_a()->id()); @@ -236,15 +239,13 @@ EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions()); // We shouldn't be able to drag in highlight mode. - action_view = container->GetToolbarActionViewAt(0); - EXPECT_FALSE(container->CanStartDragForView(action_view, point, point)); + EXPECT_FALSE(browser_actions_bar()->CanBeResized()); // We should go back to normal after leaving highlight mode. toolbar_model()->StopHighlighting(); EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions()); EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions()); - action_view = container->GetToolbarActionViewAt(0); - EXPECT_TRUE(container->CanStartDragForView(action_view, point, point)); + EXPECT_TRUE(browser_actions_bar()->CanBeResized()); } // Test the behavior of the overflow container for Extension Actions.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc index 8f2ecc6..9f015618 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "extensions/browser/notification_types.h" #include "extensions/common/extension_builder.h" #include "extensions/common/feature_switch.h" @@ -141,6 +142,8 @@ void TearDownOnMainThread() override; private: + test::ScopedMacViewsBrowserMode views_mode_{true}; + DISALLOW_COPY_AND_ASSIGN(ToolbarActionViewInteractiveUITest); };
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc index bc72b510..91dfd885 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -6,11 +6,11 @@ #include "base/base64.h" #include "base/containers/flat_set.h" -#include "base/i18n/rtl.h" #include "base/json/json_writer.h" #include "base/memory/ref_counted_memory.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/icu_test_util.h" #include "base/values.h" #include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" @@ -342,7 +342,7 @@ void Initialize() { // Set locale since the delimeters we check in VerifyInitialSettings() // depend on it. - base::i18n::SetICUDefaultLocale("en"); + base::test::ScopedRestoreICUDefaultLocale scoped_locale("en"); // Sending this message will enable javascript, so it must always be called // before any other messages are sent. @@ -394,14 +394,14 @@ ASSERT_TRUE(settings->FindKeyOfType("isInAppKioskMode", base::Value::Type::BOOLEAN)); - const base::Value* thousandsDelimeter = settings->FindKeyOfType( + const base::Value* thousands_delimeter = settings->FindKeyOfType( "thousandsDelimeter", base::Value::Type::STRING); - ASSERT_TRUE(thousandsDelimeter); - EXPECT_EQ(",", thousandsDelimeter->GetString()); - const base::Value* decimalDelimeter = + ASSERT_TRUE(thousands_delimeter); + EXPECT_EQ(",", thousands_delimeter->GetString()); + const base::Value* decimal_delimeter = settings->FindKeyOfType("decimalDelimeter", base::Value::Type::STRING); - ASSERT_TRUE(decimalDelimeter); - EXPECT_EQ(".", decimalDelimeter->GetString()); + ASSERT_TRUE(decimal_delimeter); + EXPECT_EQ(".", decimal_delimeter->GetString()); ASSERT_TRUE( settings->FindKeyOfType("unitType", base::Value::Type::INTEGER));
diff --git a/chrome/browser/vr/elements/draw_phase.cc b/chrome/browser/vr/elements/draw_phase.cc index 4ffdda01..ec8ad62 100644 --- a/chrome/browser/vr/elements/draw_phase.cc +++ b/chrome/browser/vr/elements/draw_phase.cc
@@ -11,8 +11,8 @@ namespace { static const char* g_draw_phase_strings[] = { - "kPhaseNone", "kPhaseBackground", "kPhaseForeground", - "kPhaseOverlayForeground", + "kPhaseNone", "kPhaseBackground", "kPhaseBackplanes", + "kPhaseForeground", "kPhaseOverlayForeground", }; static_assert(
diff --git a/chrome/browser/vr/elements/draw_phase.h b/chrome/browser/vr/elements/draw_phase.h index b525fa50..f8533eb 100644 --- a/chrome/browser/vr/elements/draw_phase.h +++ b/chrome/browser/vr/elements/draw_phase.h
@@ -16,6 +16,7 @@ // kPhaseNone is to be used for elements that do not draw. Eg, layouts. kPhaseNone = 0, kPhaseBackground, + kPhaseBackplanes, kPhaseForeground, kPhaseOverlayForeground, kNumDrawPhases = kPhaseOverlayForeground
diff --git a/chrome/browser/vr/elements/repositioner.cc b/chrome/browser/vr/elements/repositioner.cc index 14c47d2..1d6b359 100644 --- a/chrome/browser/vr/elements/repositioner.cc +++ b/chrome/browser/vr/elements/repositioner.cc
@@ -13,6 +13,7 @@ namespace { +constexpr float kDragThresholdDegrees = 3.0f; constexpr float kHeadUpTransitionStartDegrees = 60.0f; constexpr float kHeadUpTransitionEndDegrees = 30.0f; constexpr gfx::Vector3dF kUp = {0, 1, 0}; @@ -58,6 +59,7 @@ if (enabled) { initial_transform_ = transform_; initial_laser_direction_ = laser_direction_; + has_moved_beyond_threshold_ = false; } } @@ -93,6 +95,10 @@ gfx::Vector3dF expected_right = gfx::CrossProduct(new_forward, up); gfx::Quaternion rotate_to_expected_right(new_right, expected_right); transform_.ConcatTransform(gfx::Transform(rotate_to_expected_right)); + if (gfx::AngleBetweenVectorsInDegrees( + initial_laser_direction_, laser_direction_) > kDragThresholdDegrees) { + has_moved_beyond_threshold_ = true; + } // Potentially bake our current transform, to avoid situations where // |laser_direction_| and |initial_laser_direction_| are nearly 180 degrees
diff --git a/chrome/browser/vr/elements/repositioner.h b/chrome/browser/vr/elements/repositioner.h index 33487b5..47e74197 100644 --- a/chrome/browser/vr/elements/repositioner.h +++ b/chrome/browser/vr/elements/repositioner.h
@@ -32,6 +32,11 @@ void SetEnabled(bool enabled); void Reset(); + // This method returns true if the user has repositioned far enough that we + // should consider it an intentional drag (and the UI may want to respond + // different if this has happened). + bool HasMovedBeyondThreshold() const { return has_moved_beyond_threshold_; } + private: gfx::Transform LocalTransform() const override; gfx::Transform GetTargetLocalTransform() const override; @@ -43,6 +48,7 @@ #endif bool enabled_ = false; + bool has_moved_beyond_threshold_ = false; gfx::Transform transform_; gfx::Vector3dF laser_direction_;
diff --git a/chrome/browser/vr/elements/reticle.cc b/chrome/browser/vr/elements/reticle.cc index 21cdac1..873a826 100644 --- a/chrome/browser/vr/elements/reticle.cc +++ b/chrome/browser/vr/elements/reticle.cc
@@ -5,10 +5,14 @@ #include "chrome/browser/vr/elements/reticle.h" #include "base/numerics/math_constants.h" +#include "chrome/browser/vr/databinding/binding.h" +#include "chrome/browser/vr/elements/rect.h" +#include "chrome/browser/vr/elements/vector_icon.h" #include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/ui_element_renderer.h" #include "chrome/browser/vr/ui_scene.h" #include "chrome/browser/vr/ui_scene_constants.h" +#include "chrome/browser/vr/vector_icons/vector_icons.h" #include "chrome/browser/vr/vr_gl_util.h" namespace vr { @@ -64,13 +68,13 @@ ); // clang-format on -static constexpr float kRingDiameter = 1.0f; -static constexpr float kInnerHole = 0.0f; -static constexpr float kInnerRingEnd = 0.177f; -static constexpr float kInnerRingThickness = 0.14f; -static constexpr float kMidRingEnd = 0.177f; -static constexpr float kMidRingOpacity = 0.22f; -static constexpr float kReticleColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; +constexpr float kRingDiameter = 1.0f; +constexpr float kInnerHole = 0.0f; +constexpr float kInnerRingEnd = 0.177f; +constexpr float kInnerRingThickness = 0.14f; +constexpr float kMidRingEnd = 0.177f; +constexpr float kMidRingOpacity = 0.22f; +constexpr float kReticleColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; } // namespace @@ -87,34 +91,10 @@ void Reticle::Render(UiElementRenderer* renderer, const CameraModel& model) const { - // Scale the reticle to have a fixed FOV size at any distance. - const float eye_to_target = - std::sqrt(model_->reticle.target_point.SquaredDistanceTo(kOrigin)); - - gfx::Transform mat; - mat.Scale3d(kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1); - - gfx::Quaternion rotation; - - UiElement* target = TargetElement(); - if (target) { - // Make the reticle planar to the element it's hitting. - rotation = gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), - -target->GetNormal()); - } else { - // Rotate the reticle to directly face the eyes. - rotation = gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), - model_->reticle.target_point - kOrigin); - } - gfx::Transform rotation_mat(rotation); - mat = rotation_mat * mat; - - mat.matrix().postTranslate(model_->reticle.target_point.x(), - model_->reticle.target_point.y(), - model_->reticle.target_point.z()); - gfx::Transform transform = - model.view_proj_matrix * world_space_transform() * mat; - renderer->DrawReticle(computed_opacity(), transform); + if (model_->reticle.cursor_type != kCursorDefault) + return; + renderer->DrawReticle(computed_opacity(), + model.view_proj_matrix * world_space_transform()); } Reticle::Renderer::Renderer() @@ -162,4 +142,33 @@ return kVertexShader; } +gfx::Transform Reticle::LocalTransform() const { + // Scale the reticle to have a fixed FOV size at any distance. + const float eye_to_target = + std::sqrt(model_->reticle.target_point.SquaredDistanceTo(kOrigin)); + + if (eye_to_target == 0.0f) + return gfx::Transform(); + + gfx::Transform mat; + mat.Scale3d(kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1); + + // This will make the reticle planar to the target element (if there is one), + // and directly face the user, otherwise. + UiElement* target = TargetElement(); + gfx::Transform rotation_mat(gfx::Quaternion( + gfx::Vector3dF(0.0f, 0.0f, -1.0f), + target ? -target->GetNormal() : model_->reticle.target_point - kOrigin)); + mat = rotation_mat * mat; + + mat.matrix().postTranslate(model_->reticle.target_point.x(), + model_->reticle.target_point.y(), + model_->reticle.target_point.z()); + return mat; +} + +gfx::Transform Reticle::GetTargetLocalTransform() const { + return LocalTransform(); +} + } // namespace vr
diff --git a/chrome/browser/vr/elements/reticle.h b/chrome/browser/vr/elements/reticle.h index 8d73cb2..1000013 100644 --- a/chrome/browser/vr/elements/reticle.h +++ b/chrome/browser/vr/elements/reticle.h
@@ -47,6 +47,8 @@ private: void Render(UiElementRenderer* renderer, const CameraModel& model) const final; + gfx::Transform LocalTransform() const final; + gfx::Transform GetTargetLocalTransform() const final; gfx::Point3F origin_; gfx::Point3F target_;
diff --git a/chrome/browser/vr/elements/shadow.cc b/chrome/browser/vr/elements/shadow.cc index 8474533..6f0d7bda 100644 --- a/chrome/browser/vr/elements/shadow.cc +++ b/chrome/browser/vr/elements/shadow.cc
@@ -121,15 +121,18 @@ Shadow::Shadow() { set_bounds_contain_children(true); + set_bounds_contain_padding(false); } Shadow::~Shadow() {} void Shadow::Render(UiElementRenderer* renderer, const CameraModel& camera_model) const { + DCHECK_EQ(left_padding(), right_padding()); + DCHECK_EQ(top_padding(), bottom_padding()); renderer->DrawShadow( camera_model.view_proj_matrix * world_space_transform(), size(), - x_padding(), y_padding(), + left_padding(), right_padding(), gfx::Tween::FloatValueBetween(depth_, 0.0f, 1.0f), SK_ColorBLACK, computed_opacity() * kShadowOpacity * intensity_, corner_radius()); } @@ -149,12 +152,6 @@ set_corner_radius(children().front()->corner_radii().MaxRadius()); } -gfx::SizeF Shadow::ContributedSize() const { - gfx::RectF bounds(size()); - bounds.Inset(x_padding(), y_padding()); - return bounds.size(); -} - Shadow::Renderer::Renderer() : BaseQuadRenderer(kVertexShader, kFragmentShader) { model_view_proj_matrix_handle_ =
diff --git a/chrome/browser/vr/elements/shadow.h b/chrome/browser/vr/elements/shadow.h index c773c0f..1e1a7e4 100644 --- a/chrome/browser/vr/elements/shadow.h +++ b/chrome/browser/vr/elements/shadow.h
@@ -25,8 +25,6 @@ void LayOutChildren() override; void set_intensity(float intensity) { intensity_ = intensity; } - gfx::SizeF ContributedSize() const override; - class Renderer : public BaseQuadRenderer { public: Renderer();
diff --git a/chrome/browser/vr/elements/shadow_unittest.cc b/chrome/browser/vr/elements/shadow_unittest.cc index a6f3aca9..994d572 100644 --- a/chrome/browser/vr/elements/shadow_unittest.cc +++ b/chrome/browser/vr/elements/shadow_unittest.cc
@@ -26,17 +26,17 @@ scene.AddUiElement(kRoot, std::move(shadow)); scene.OnBeginFrame(MsToTicks(0), kStartHeadPose); - float old_x_padding = shadow_ptr->x_padding(); - float old_y_padding = shadow_ptr->y_padding(); - EXPECT_LE(0.0f, old_x_padding); - EXPECT_LE(0.0f, old_y_padding); + float old_left_padding = shadow_ptr->left_padding(); + float old_top_padding = shadow_ptr->top_padding(); + EXPECT_LE(0.0f, old_left_padding); + EXPECT_LE(0.0f, old_top_padding); rect_ptr->SetTranslate(0, 0, 0.15); scene.OnBeginFrame(MsToTicks(0), kStartHeadPose); - float new_x_padding = shadow_ptr->x_padding(); - float new_y_padding = shadow_ptr->y_padding(); - EXPECT_LE(old_x_padding, new_x_padding); - EXPECT_LE(old_y_padding, new_y_padding); + float new_left_padding = shadow_ptr->left_padding(); + float new_top_padding = shadow_ptr->top_padding(); + EXPECT_LE(old_left_padding, new_left_padding); + EXPECT_LE(old_top_padding, new_top_padding); } } // namespace vr
diff --git a/chrome/browser/vr/elements/ui_element.cc b/chrome/browser/vr/elements/ui_element.cc index d47e608..8f4e597e 100644 --- a/chrome/browser/vr/elements/ui_element.cc +++ b/chrome/browser/vr/elements/ui_element.cc
@@ -87,6 +87,7 @@ EventHandlers::EventHandlers() = default; EventHandlers::~EventHandlers() = default; +EventHandlers::EventHandlers(const EventHandlers& other) = default; UiElement::UiElement() : id_(AllocateId()) { animation_.set_target(this); @@ -256,7 +257,11 @@ void UiElement::OnSetSize(const gfx::SizeF& size) {} gfx::SizeF UiElement::ContributedSize() const { - return size(); + gfx::RectF bounds(size()); + if (!bounds_contain_padding_) { + bounds.Inset(left_padding_, bottom_padding_, right_padding_, top_padding_); + } + return bounds.size(); } void UiElement::SetVisible(bool visible) { @@ -687,8 +692,10 @@ void UiElement::DoLayOutChildren() { LayOutChildren(); if (!bounds_contain_children_) { - DCHECK_EQ(0.0f, x_padding_); - DCHECK_EQ(0.0f, y_padding_); + DCHECK_EQ(0.0f, right_padding_); + DCHECK_EQ(0.0f, left_padding_); + DCHECK_EQ(0.0f, top_padding_); + DCHECK_EQ(0.0f, bottom_padding_); return; } @@ -719,7 +726,8 @@ bounds.Union(local_rect); } - bounds.Inset(-x_padding_, -y_padding_); + bounds.Inset(-left_padding_, -bottom_padding_, -right_padding_, + -top_padding_); bounds.set_origin(bounds.CenterPoint()); local_origin_ = bounds.origin(); if (bounds.size() == GetTargetSize())
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h index b16db7e2..df491db 100644 --- a/chrome/browser/vr/elements/ui_element.h +++ b/chrome/browser/vr/elements/ui_element.h
@@ -23,6 +23,7 @@ #include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/elements/ui_element_type.h" #include "chrome/browser/vr/model/camera_model.h" +#include "chrome/browser/vr/model/reticle_model.h" #include "chrome/browser/vr/target_property.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/quaternion.h" @@ -57,6 +58,7 @@ struct EventHandlers { EventHandlers(); + EventHandlers(const EventHandlers& other); ~EventHandlers(); base::RepeatingCallback<void()> hover_enter; base::RepeatingCallback<void()> hover_leave; @@ -228,7 +230,7 @@ // their children. Eg, for shadows. // TODO(crbug.com/820507): change this to LayoutSize and update all layout // code to make use of this instead of size(). - virtual gfx::SizeF ContributedSize() const; + gfx::SizeF ContributedSize() const; gfx::PointF local_origin() const { return local_origin_; } @@ -298,6 +300,11 @@ bounds_contain_children_ = bounds_contain_children; } + bool bounds_contain_padding() const { return bounds_contain_padding_; } + void set_bounds_contain_padding(bool bounds_contain_padding) { + bounds_contain_padding_ = bounds_contain_padding; + } + bool contributes_to_parent_bounds() const { return contributes_to_parent_bounds_; } @@ -305,11 +312,23 @@ contributes_to_parent_bounds_ = value; } - float x_padding() const { return x_padding_; } - float y_padding() const { return y_padding_; } - void set_padding(float x_padding, float y_padding) { - x_padding_ = x_padding; - y_padding_ = y_padding; + float left_padding() const { return left_padding_; } + float right_padding() const { return right_padding_; } + float top_padding() const { return top_padding_; } + float bottom_padding() const { return bottom_padding_; } + + void set_padding(float x, float y) { + left_padding_ = x; + right_padding_ = x; + top_padding_ = y; + bottom_padding_ = y; + } + + void set_padding(float left, float top, float right, float bottom) { + left_padding_ = left; + right_padding_ = right; + top_padding_ = top; + bottom_padding_ = bottom; } const gfx::Transform& inheritable_transform() const { @@ -433,6 +452,9 @@ return updated_visibility_this_frame_; } + void set_cursor_type(CursorType cursor_type) { cursor_type_ = cursor_type; } + CursorType cursor_type() const { return cursor_type_; } + std::string DebugName() const; #ifndef NDEBUG @@ -539,9 +561,12 @@ // size to accommodate all descendants, adding in the padding below along the // x and y axes. bool bounds_contain_children_ = false; + bool bounds_contain_padding_ = true; bool contributes_to_parent_bounds_ = true; - float x_padding_ = 0.0f; - float y_padding_ = 0.0f; + float left_padding_ = 0.0f; + float right_padding_ = 0.0f; + float top_padding_ = 0.0f; + float bottom_padding_ = 0.0f; Animation animation_; @@ -595,6 +620,8 @@ // Indicates that this element may be resized by parent layout elements. bool resizable_by_layout_ = false; + CursorType cursor_type_ = kCursorDefault; + DISALLOW_COPY_AND_ASSIGN(UiElement); };
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc index a6b9af04..0010ac9 100644 --- a/chrome/browser/vr/elements/ui_element_name.cc +++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -32,6 +32,7 @@ "kControllerGroup", "kLaser", "kController", + "kRepositionCursor", "kReticle", "kReticleLaserGroup", "kKeyboardVisibilityControlForVoice", @@ -42,6 +43,7 @@ "kFloor", "kStars", "kUpdateKeyboardPrompt", + "kUrlBarBackplane", "kUrlBarPositioner", "kUrlBarDmmRoot", "kUrlBar",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index 4774010..e3a4b41 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -31,6 +31,7 @@ kControllerGroup, kLaser, kController, + kRepositionCursor, kReticle, kReticleLaserGroup, kKeyboardVisibilityControlForVoice, @@ -41,6 +42,7 @@ kFloor, kStars, kUpdateKeyboardPrompt, + kUrlBarBackplane, kUrlBarPositioner, kUrlBarDmmRoot, kUrlBar,
diff --git a/chrome/browser/vr/elements/ui_element_type.cc b/chrome/browser/vr/elements/ui_element_type.cc index c4f088d..e82595c1 100644 --- a/chrome/browser/vr/elements/ui_element_type.cc +++ b/chrome/browser/vr/elements/ui_element_type.cc
@@ -36,6 +36,8 @@ "kTypeToastText", "kTypeSnackbarButton", "kTypeSnackbarDescription", + "kTypeCursorBackground", + "kTypeCursorForeground", }; static_assert(
diff --git a/chrome/browser/vr/elements/ui_element_type.h b/chrome/browser/vr/elements/ui_element_type.h index acb4dc08..7c69daf 100644 --- a/chrome/browser/vr/elements/ui_element_type.h +++ b/chrome/browser/vr/elements/ui_element_type.h
@@ -36,6 +36,8 @@ kTypeToastText, kTypeSnackbarButton, kTypeSnackbarDescription, + kTypeCursorBackground, + kTypeCursorForeground, // This must be last. kNumUiElementTypes,
diff --git a/chrome/browser/vr/model/color_scheme.cc b/chrome/browser/vr/model/color_scheme.cc index 8b29674..6a1226d 100644 --- a/chrome/browser/vr/model/color_scheme.cc +++ b/chrome/browser/vr/model/color_scheme.cc
@@ -152,6 +152,10 @@ normal_scheme.incognito_factor = 0.0f; normal_scheme.fullscreen_factor = 0.0f; + normal_scheme.cursor_background_center = 0x24000000; + normal_scheme.cursor_background_edge = SK_ColorTRANSPARENT; + normal_scheme.cursor_foreground = SK_ColorWHITE; + g_fullscreen_scheme.Get() = normal_scheme; ColorScheme& fullscreen_scheme = g_fullscreen_scheme.Get(); fullscreen_scheme.world_background = 0xFF000714;
diff --git a/chrome/browser/vr/model/color_scheme.h b/chrome/browser/vr/model/color_scheme.h index ce17eb2..3fde9c2d 100644 --- a/chrome/browser/vr/model/color_scheme.h +++ b/chrome/browser/vr/model/color_scheme.h
@@ -137,6 +137,10 @@ SkColor reposition_label; SkColor reposition_label_background; + SkColor cursor_background_center; + SkColor cursor_background_edge; + SkColor cursor_foreground; + // These are used for blending between colors that are available only in // shaders. They are, as you might expect, one for a given mode, but zero // otherwise.
diff --git a/chrome/browser/vr/model/reticle_model.h b/chrome/browser/vr/model/reticle_model.h index 768ae3e..9a32c13b 100644 --- a/chrome/browser/vr/model/reticle_model.h +++ b/chrome/browser/vr/model/reticle_model.h
@@ -9,6 +9,11 @@ namespace vr { +enum CursorType { + kCursorDefault, + kCursorReposition, +}; + // The ReticleModel contains information related to the target of the // controller's laser. It is computed by the UiInputManager and is used by the // input manager in the production of gestures as well as by the Reticle element @@ -17,6 +22,7 @@ gfx::Point3F target_point; gfx::PointF target_local_point; int target_element_id = 0; + CursorType cursor_type = kCursorDefault; }; } // namespace vr
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc index a861bec..bf72bcff 100644 --- a/chrome/browser/vr/ui_input_manager.cc +++ b/chrome/browser/vr/ui_input_manager.cc
@@ -84,6 +84,7 @@ reticle_model->target_element_id = element->id(); reticle_model->target_local_point = result.local_hit_point; reticle_model->target_point = result.hit_point; + reticle_model->cursor_type = element->cursor_type(); break; } }
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc index f780f5d..5d83300 100644 --- a/chrome/browser/vr/ui_scene.cc +++ b/chrome/browser/vr/ui_scene.cc
@@ -167,6 +167,7 @@ UiScene::Elements UiScene::GetVisibleElementsToDraw() const { return GetVisibleElements(GetUiElementByName(kRoot), [](UiElement* element) { return element->draw_phase() == kPhaseForeground || + element->draw_phase() == kPhaseBackplanes || element->draw_phase() == kPhaseBackground; }); }
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index fcecad38..e78c8cf17 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -75,6 +75,8 @@ static constexpr float kUrlBarSecuritySeparatorHeightDMM = 0.026f; static constexpr float kUrlBarOriginFadeWidth = 0.044f; static constexpr float kUrlBarOriginMinimumPathWidth = 0.044f; +static constexpr float kUrlBarBackplaneTopPadding = 0.065f; +static constexpr float kUrlBarBackplanePadding = 0.005f; static constexpr float kOverlayPlaneDistance = 2.3f; @@ -283,20 +285,7 @@ static constexpr float kSkyDistance = 1000.0f; static constexpr float kGridOpacity = 0.5f; -static constexpr float kRepositionButtonDiameter = 0.75f * kCloseButtonDiameter; -// This allows the button to be hittable even when hidden. -static constexpr float kRepositionButtonMinOpacity = 0.001f; -static constexpr float kRepositionButtonMidOpacity = 0.3f; -static constexpr float kRepositionButtonMaxOpacity = 1.0f; -static constexpr float kRepositionButtonXOffset = kIndicatorGap; -static constexpr float kRepositionButtonYOffset = 0.5f * kIndicatorGap; -static constexpr int kRepositionButtonTransitionDurationMs = 750; -static constexpr float kRepositionLabelWidth = 0.55f * kContentWidth; -static constexpr float kRepositionLabelFontHeight = kControllerLabelFontHeight; -static constexpr float kRepositionLabelFontScale = 1.5f; -static constexpr float kRepositionLabelBackgroundPadding = 0.06f; static constexpr float kRepositionContentOpacity = 0.2f; -static constexpr float kRepositionLabelBackgroundCornerRadius = 0.02f; static constexpr float kPromptWidthDMM = 0.63f; static constexpr float kPromptHeightDMM = 0.218f; @@ -304,6 +293,9 @@ static constexpr float kPromptShadowOffsetDMM = 0.1f; static constexpr float kPromptDistance = 2.4f; +static constexpr float kRepositionCursorBackgroundSize = 1.4f; +static constexpr float kRepositionCursorSize = 1.2f; + static constexpr float kMinResizerScale = 0.5f; static constexpr float kMaxResizerScale = 1.5f;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index eac1ff6..56fab4be 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -588,6 +588,22 @@ return controller; } +EventHandlers CreateRepositioningHandlers(Model* model, UiScene* scene) { + EventHandlers handlers; + handlers.button_down = base::BindRepeating( + [](Model* model) { model->push_mode(kModeRepositionWindow); }, + base::Unretained(model)); + handlers.button_up = base::BindRepeating( + [](Model* model, Repositioner* repositioner) { + if (repositioner->HasMovedBeyondThreshold()) + model->pop_mode(kModeRepositionWindow); + }, + base::Unretained(model), + base::Unretained(static_cast<Repositioner*>( + scene->GetUiElementByName(k2dBrowsingRepositioner)))); + return handlers; +} + } // namespace UiSceneCreator::UiSceneCreator(UiBrowserInterface* browser, @@ -925,9 +941,13 @@ void UiSceneCreator::CreateContentQuad() { // Place an invisible but hittable plane behind the content quad, to keep the // reticle roughly planar with the content if near content. - auto hit_plane = Create<InvisibleHitTarget>(kBackplane, kPhaseForeground); + auto hit_plane = Create<InvisibleHitTarget>(kBackplane, kPhaseBackplanes); hit_plane->SetSize(kBackplaneSize, kSceneHeight); hit_plane->set_contributes_to_parent_bounds(false); + hit_plane->set_cursor_type(kCursorReposition); + + hit_plane->set_event_handlers(CreateRepositioningHandlers(model_, scene_)); + scene_->AddUiElement(k2dBrowsingContentGroup, std::move(hit_plane)); auto resizer = Create<Resizer>(kContentResizer, kPhaseNone); @@ -1476,77 +1496,6 @@ } void UiSceneCreator::CreateContentRepositioningAffordance() { - auto reposition_button = Create<DiscButton>( - kContentQuadRepositionButton, kPhaseForeground, - base::BindRepeating( - [](Model* model) { model->push_mode(kModeRepositionWindow); }, - base::Unretained(model_)), - kRepositionIcon, audio_delegate_); - reposition_button->SetSize(kRepositionButtonDiameter, - kRepositionButtonDiameter); - reposition_button->set_y_anchoring(BOTTOM); - reposition_button->set_x_anchoring(RIGHT); - reposition_button->set_x_centering(LEFT); - reposition_button->set_y_centering(BOTTOM); - reposition_button->SetTranslate(kRepositionButtonXOffset, - kRepositionButtonYOffset, 0); - reposition_button->SetTransitionedProperties({OPACITY}); - reposition_button->SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kRepositionButtonTransitionDurationMs)); - reposition_button->background()->SetTransitionedProperties( - {BACKGROUND_COLOR, TRANSFORM}); - reposition_button->SetOpacity(kRepositionButtonMinOpacity); - reposition_button->SetSounds(kSoundNone, kSoundNone, nullptr); - reposition_button->AddBinding(std::make_unique<Binding<float>>( - VR_BIND_LAMBDA( - [](Model* model, Button* button) { - if (!model->experimental_features_enabled) - return 0.0f; - if (button->hovered()) - return kRepositionButtonMaxOpacity; - if (!model->controller.quiescent) - return kRepositionButtonMidOpacity; - return kRepositionButtonMinOpacity; - }, - base::Unretained(model_), base::Unretained(reposition_button.get())), - VR_BIND_LAMBDA( - [](UiElement* button, const float& opacity) { - if (opacity == 1.0f) - button->SetVisibleImmediately(true); - else - button->SetOpacity(opacity); - }, - base::Unretained(reposition_button.get())))); - VR_BIND_BUTTON_COLORS(model_, reposition_button.get(), - &ColorScheme::button_colors, - &DiscButton::SetButtonColors); - scene_->AddUiElement(kContentQuad, std::move(reposition_button)); - - auto label_background = - Create<Rect>(kContentRepositionLabel, kPhaseForeground); - label_background->set_bounds_contain_children(true); - label_background->set_corner_radius(kRepositionLabelBackgroundCornerRadius); - label_background->set_padding(kRepositionLabelBackgroundPadding, - kRepositionLabelBackgroundPadding); - label_background->set_contributes_to_parent_bounds(false); - VR_BIND_COLOR(model_, label_background.get(), - &ColorScheme::reposition_label_background, &Rect::SetColor); - VR_BIND_VISIBILITY(label_background, model->reposition_window_enabled()); - - auto label = - Create<Text>(kNone, kPhaseForeground, kRepositionLabelFontHeight); - label->SetText(l10n_util::GetStringUTF16(IDS_VR_REPOSITION_LABEL)); - label->SetVisible(true); - label->SetAlignment(UiTexture::kTextAlignmentCenter); - label->SetLayoutMode(kSingleLineFixedHeight); - label->SetScale(kRepositionLabelFontScale, kRepositionLabelFontScale, - kRepositionLabelFontScale); - VR_BIND_COLOR(model_, label.get(), &ColorScheme::reposition_label, - &Text::SetColor); - - label_background->AddChild(std::move(label)); - scene_->AddUiElement(k2dBrowsingContentGroup, std::move(label_background)); - auto content_toggle = Create<UiElement>(kContentRepositionVisibilityToggle, kPhaseNone); content_toggle->SetTransitionedProperties({OPACITY}); @@ -1555,13 +1504,15 @@ float, Model, model_, model->reposition_window_enabled() ? kRepositionContentOpacity : 1.0f, UiElement, content_toggle.get(), SetOpacity)); - scene_->AddParentUiElement(kContentResizer, std::move(content_toggle)); + scene_->AddParentUiElement(k2dBrowsingForeground, + std::move(content_toggle)); auto hit_plane = Create<InvisibleHitTarget>(kContentRepositionHitPlane, kPhaseForeground); hit_plane->set_contributes_to_parent_bounds(false); hit_plane->SetSize(kSceneSize, kSceneSize); hit_plane->SetTranslate(0.0f, 0.0f, -kContentDistance); + hit_plane->set_cursor_type(kCursorReposition); EventHandlers event_handlers; event_handlers.button_up = base::BindRepeating( [](Model* m) { @@ -1653,6 +1604,35 @@ auto reticle = std::make_unique<Reticle>(scene_, model_); reticle->SetDrawPhase(kPhaseForeground); + auto reposition_group = Create<UiElement>(kRepositionCursor, kPhaseNone); + VR_BIND_VISIBILITY(reposition_group, + model->reticle.cursor_type == kCursorReposition); + + auto reposition_bg = Create<Rect>(kNone, kPhaseForeground); + reposition_bg->set_owner_name_for_test(kRepositionCursor); + reposition_bg->SetType(kTypeCursorBackground); + reposition_bg->SetSize(kRepositionCursorBackgroundSize, + kRepositionCursorBackgroundSize); + reposition_bg->SetDrawPhase(kPhaseForeground); + VR_BIND_COLOR(model_, reposition_bg.get(), + &ColorScheme::cursor_background_edge, &Rect::SetEdgeColor); + VR_BIND_COLOR(model_, reposition_bg.get(), + &ColorScheme::cursor_background_center, &Rect::SetCenterColor); + + auto reposition_icon = std::make_unique<VectorIcon>(128); + reposition_icon->set_owner_name_for_test(kRepositionCursor); + reposition_icon->SetType(kTypeCursorForeground); + reposition_icon->SetIcon(kRepositionIcon); + reposition_icon->SetDrawPhase(kPhaseForeground); + reposition_icon->SetSize(kRepositionCursorSize, kRepositionCursorSize); + VR_BIND_COLOR(model_, reposition_icon.get(), &ColorScheme::cursor_foreground, + &VectorIcon::SetColor); + + reposition_group->AddChild(std::move(reposition_bg)); + reposition_group->AddChild(std::move(reposition_icon)); + + reticle->AddChild(std::move(reposition_group)); + reticle_laser_group->AddChild(std::move(laser)); reticle_laser_group->AddChild(std::move(reticle)); @@ -1706,11 +1686,20 @@ scaler->set_contributes_to_parent_bounds(false); scene_->AddUiElement(kUrlBarPositioner, std::move(scaler)); + auto backplane = + Create<InvisibleHitTarget>(kUrlBarBackplane, kPhaseBackplanes); + backplane->set_bounds_contain_children(true); + backplane->set_contributes_to_parent_bounds(false); + backplane->set_padding(kUrlBarBackplanePadding, kUrlBarBackplaneTopPadding, + kUrlBarBackplanePadding, kUrlBarBackplanePadding); + backplane->set_event_handlers(CreateRepositioningHandlers(model_, scene_)); + VR_BIND_VISIBILITY(backplane, !model->fullscreen_enabled()); + scene_->AddUiElement(kUrlBarDmmRoot, std::move(backplane)); + auto url_bar = Create<UiElement>(kUrlBar, kPhaseNone); url_bar->SetRotate(1, 0, 0, kUrlBarRotationRad); url_bar->set_bounds_contain_children(true); - VR_BIND_VISIBILITY(url_bar, !model->fullscreen_enabled()); - scene_->AddUiElement(kUrlBarDmmRoot, std::move(url_bar)); + scene_->AddUiElement(kUrlBarBackplane, std::move(url_bar)); auto layout = Create<LinearLayout>(kUrlBarLayout, kPhaseNone, LinearLayout::kRight);
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index d2736985..6594260a 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -52,6 +52,7 @@ kContentQuad, kContentQuadShadow, kBackplane, + kUrlBarBackplane, kUrlBarBackButton, kUrlBarBackButtonIcon, kUrlBarSeparator, @@ -1193,36 +1194,6 @@ EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); } -TEST_F(UiTest, RepositionButton) { - CreateScene(kNotInCct, kNotInWebVr); - DiscButton* button = static_cast<DiscButton*>( - scene_->GetUiElementByName(kContentQuadRepositionButton)); - EXPECT_FALSE(IsVisible(button->name())); - - model_->experimental_features_enabled = true; - model_->controller.quiescent = true; - OnBeginFrame(); - EXPECT_EQ(kRepositionButtonMinOpacity, button->GetTargetOpacity()); - - model_->controller.quiescent = false; - OnBeginFrame(); - EXPECT_EQ(kRepositionButtonMidOpacity, button->GetTargetOpacity()); - - button->OnHoverEnter({0, 0}); - OnBeginFrame(); - EXPECT_EQ(kRepositionButtonMaxOpacity, button->GetTargetOpacity()); - - // If hovered, the button should remain visible, even the controller is - // quiescent. - model_->controller.quiescent = true; - OnBeginFrame(); - EXPECT_EQ(kRepositionButtonMaxOpacity, button->GetTargetOpacity()); - - button->OnHoverLeave(); - OnBeginFrame(); - EXPECT_EQ(kRepositionButtonMinOpacity, button->GetTargetOpacity()); -} - TEST_F(UiTest, ResetRepositioner) { CreateScene(kNotInCct, kNotInWebVr);
diff --git a/chrome/browser/vr/vector_icons/daydream_controller_app_button.icon b/chrome/browser/vr/vector_icons/daydream_controller_app_button.icon index 446554f5..ea1b5d59 100644 --- a/chrome/browser/vr/vector_icons/daydream_controller_app_button.icon +++ b/chrome/browser/vr/vector_icons/daydream_controller_app_button.icon
@@ -15,5 +15,4 @@ CUBIC_TO, 36.88f, 27, 38, 25.88f, 38, 24.5f, CUBIC_TO, 38, 23.12f, 36.88f, 22, 35.5f, 22, LINE_TO, 12.5f, 22, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/browser/vr/vector_icons/daydream_controller_home_button.icon b/chrome/browser/vr/vector_icons/daydream_controller_home_button.icon index aac6e7a..59a3cabd 100644 --- a/chrome/browser/vr/vector_icons/daydream_controller_home_button.icon +++ b/chrome/browser/vr/vector_icons/daydream_controller_home_button.icon
@@ -19,5 +19,4 @@ CUBIC_TO, 16, 19.58f, 19.58f, 16, 24, 16, CUBIC_TO, 28.42f, 16, 32, 19.58f, 32, 24, CUBIC_TO, 32, 28.42f, 28.42f, 32, 24, 32, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/browser/vr/vector_icons/file_download_done.icon b/chrome/browser/vr/vector_icons/file_download_done.icon index d5c94e4..6bc679b 100644 --- a/chrome/browser/vr/vector_icons/file_download_done.icon +++ b/chrome/browser/vr/vector_icons/file_download_done.icon
@@ -16,5 +16,4 @@ LINE_TO, 17, 4, R_LINE_TO, 2, 2, R_LINE_TO, -9.4f, 9.3f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/chrome/browser/vr/vector_icons/reposition.icon b/chrome/browser/vr/vector_icons/reposition.icon index a703388..3476931 100644 --- a/chrome/browser/vr/vector_icons/reposition.icon +++ b/chrome/browser/vr/vector_icons/reposition.icon
@@ -38,5 +38,4 @@ R_LINE_TO, 5, -5, R_H_LINE_TO, -3, R_V_LINE_TO, -3, -CLOSE, -END +CLOSE
diff --git a/chrome/browser/vr/vector_icons/sad_tab.icon b/chrome/browser/vr/vector_icons/sad_tab.icon index 9e3e3ddd..69a69c6 100644 --- a/chrome/browser/vr/vector_icons/sad_tab.icon +++ b/chrome/browser/vr/vector_icons/sad_tab.icon
@@ -44,5 +44,4 @@ LINE_TO, 28, 23, LINE_TO, 28, 18, LINE_TO, 28, 18, -CLOSE, -END +CLOSE
diff --git a/chrome/browser/webshare/share_service_impl.cc b/chrome/browser/webshare/share_service_impl.cc index 81757c03..d785f94 100644 --- a/chrome/browser/webshare/share_service_impl.cc +++ b/chrome/browser/webshare/share_service_impl.cc
@@ -9,7 +9,6 @@ #include <map> #include <utility> -#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" @@ -21,81 +20,8 @@ #include "chrome/browser/webshare/webshare_target.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" +#include "content/public/common/manifest_share_target_util.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "net/base/escape.h" - -namespace { - -// Determines whether a character is allowed in a URL template placeholder. -bool IsIdentifier(char c) { - return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || c == '-' || c == '_'; -} - -// Returns to |out| the result of running the "replace placeholders" algorithm -// on |template_string|. The algorithm is specified at -// https://wicg.github.io/web-share-target/#dfn-replace-placeholders -bool ReplacePlaceholders(base::StringPiece template_string, - base::StringPiece title, - base::StringPiece text, - const GURL& share_url, - std::string* out) { - constexpr char kTitlePlaceholder[] = "title"; - constexpr char kTextPlaceholder[] = "text"; - constexpr char kUrlPlaceholder[] = "url"; - - std::map<base::StringPiece, std::string> placeholder_to_data; - placeholder_to_data[kTitlePlaceholder] = - net::EscapeQueryParamValue(title, false); - placeholder_to_data[kTextPlaceholder] = - net::EscapeQueryParamValue(text, false); - placeholder_to_data[kUrlPlaceholder] = - net::EscapeQueryParamValue(share_url.spec(), false); - - std::vector<base::StringPiece> split_template; - bool last_saw_open = false; - size_t start_index_to_copy = 0; - for (size_t i = 0; i < template_string.size(); ++i) { - if (last_saw_open) { - if (template_string[i] == '}') { - base::StringPiece placeholder = template_string.substr( - start_index_to_copy + 1, i - 1 - start_index_to_copy); - auto it = placeholder_to_data.find(placeholder); - if (it != placeholder_to_data.end()) { - // Replace the placeholder text with the parameter value. - split_template.push_back(it->second); - } - - last_saw_open = false; - start_index_to_copy = i + 1; - } else if (!IsIdentifier(template_string[i])) { - // Error: Non-identifier character seen after open. - return false; - } - } else { - if (template_string[i] == '}') { - // Error: Saw close, with no corresponding open. - return false; - } else if (template_string[i] == '{') { - split_template.push_back(template_string.substr( - start_index_to_copy, i - start_index_to_copy)); - - last_saw_open = true; - start_index_to_copy = i; - } - } - } - if (last_saw_open) { - // Error: Saw open that was never closed. - return false; - } - split_template.push_back(template_string.substr( - start_index_to_copy, template_string.size() - start_index_to_copy)); - - *out = base::StrCat(split_template); - return true; -} - -} // namespace ShareServiceImpl::ShareServiceImpl() : weak_factory_(this) {} ShareServiceImpl::~ShareServiceImpl() = default; @@ -106,32 +32,6 @@ std::move(request)); } -// static -bool ShareServiceImpl::ReplaceUrlPlaceholders(const GURL& url_template, - base::StringPiece title, - base::StringPiece text, - const GURL& share_url, - GURL* url_template_filled) { - std::string new_query; - std::string new_ref; - if (!ReplacePlaceholders(url_template.query_piece(), title, text, share_url, - &new_query) || - !ReplacePlaceholders(url_template.ref_piece(), title, text, share_url, - &new_ref)) { - return false; - } - - // Check whether |url_template| has a query in order to preserve the '?' in a - // URL with an empty query. e.g. http://www.google.com/? - GURL::Replacements url_replacements; - if (url_template.has_query()) - url_replacements.SetQueryStr(new_query); - if (url_template.has_ref()) - url_replacements.SetRefStr(new_ref); - *url_template_filled = url_template.ReplaceComponents(url_replacements); - return true; -} - void ShareServiceImpl::ShowPickerDialog( std::vector<WebShareTarget> targets, chrome::WebShareTargetPickerCallback callback) { @@ -223,8 +123,9 @@ } GURL url_template_filled; - if (!ReplaceUrlPlaceholders(result->url_template(), title, text, share_url, - &url_template_filled)) { + if (!content::ReplaceWebShareUrlPlaceholders(result->url_template(), title, + text, share_url, + &url_template_filled)) { // TODO(mgiuca): This error should not be possible at share time, because // targets with invalid templates should not be chooseable. Fix // https://crbug.com/694380 and replace this with a DCHECK.
diff --git a/chrome/browser/webshare/share_service_impl.h b/chrome/browser/webshare/share_service_impl.h index 0db65fd..1ac4eccd 100644 --- a/chrome/browser/webshare/share_service_impl.h +++ b/chrome/browser/webshare/share_service_impl.h
@@ -39,12 +39,6 @@ ShareCallback callback) override; private: - FRIEND_TEST_ALL_PREFIXES(ShareServiceImplUnittest, - ReplaceUrlPlaceholdersInvalidTemplate); - FRIEND_TEST_ALL_PREFIXES(ShareServiceImplUnittest, ReplaceUrlPlaceholders); - FRIEND_TEST_ALL_PREFIXES(ShareServiceImplUnittest, - ReplaceUrlPlaceholders_Escaping); - Browser* GetBrowser(); // Returns the URL template of the target identified by |target_url| @@ -73,20 +67,6 @@ // with the user. std::vector<WebShareTarget> GetTargetsWithSufficientEngagement(); - // Writes to |url_template_filled|, a copy of |url_template| with all - // instances of "{title}", "{text}", and "{url}" in the query and fragment - // parts of the URL replaced with |title|, |text|, and |url| respectively. - // Replaces instances of "{X}" where "X" is any string besides "title", - // "text", and "url", with an empty string, for forwards compatibility. - // Returns false, if there are badly nested placeholders. - // This includes any case in which two "{" occur before a "}", or a "}" - // occurs with no preceding "{". - static bool ReplaceUrlPlaceholders(const GURL& url_template, - base::StringPiece title, - base::StringPiece text, - const GURL& share_url, - GURL* url_template_filled); - void OnPickerClosed(const std::string& title, const std::string& text, const GURL& share_url,
diff --git a/chrome/browser/webshare/share_service_impl_unittest.cc b/chrome/browser/webshare/share_service_impl_unittest.cc index 998dab0..bf3dcd7 100644 --- a/chrome/browser/webshare/share_service_impl_unittest.cc +++ b/chrome/browser/webshare/share_service_impl_unittest.cc
@@ -380,240 +380,3 @@ // Pick example-low.com. std::move(picker_callback).Run(&expected_targets[0]); } - -TEST_F(ShareServiceImplUnittest, ReplaceUrlPlaceholdersInvalidTemplate) { - const GURL kUrl(kUrlSpec); - GURL url_template_filled; - - // Badly nested placeholders. - GURL url_template = GURL("http://example.com/?q={"); - bool succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - url_template = GURL("http://example.com/?q={title"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - url_template = GURL("http://example.com/?q={title{text}}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - url_template = GURL("http://example.com/?q={title{}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - url_template = GURL("http://example.com/?q={{title}}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - // Placeholder with non-identifier character. - url_template = GURL("http://example.com/?q={title?}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); - - // Invalid placeholder in URL fragment. - url_template = GURL("http://example.com/#{title?}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_FALSE(succeeded); -} - -TEST_F(ShareServiceImplUnittest, ReplaceUrlPlaceholders) { - const GURL kUrl(kUrlSpec); - - // No placeholders. - GURL url_template = GURL("http://example.com/?q=a#a"); - GURL url_template_filled; - bool succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ(url_template, url_template_filled); - - // Empty |url_template| - url_template = GURL(); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ(GURL(), url_template_filled); - - // One title placeholder. - url_template = GURL("http://example.com/#{title}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#My%20title", url_template_filled.spec()); - - // One text placeholder. - url_template = GURL("http://example.com/#{text}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#My%20text", url_template_filled.spec()); - - // One url placeholder. - url_template = GURL("http://example.com/#{url}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#https%3A%2F%2Fwww.google.com%2F", - url_template_filled.spec()); - - // One of each placeholder, in title, text, url order. - url_template = GURL("http://example.com/#{title}{text}{url}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://example.com/#My%20titleMy%20texthttps%3A%2F%2Fwww.google.com%2F", - url_template_filled.spec()); - - // One of each placeholder, in url, text, title order. - url_template = GURL("http://example.com/#{url}{text}{title}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://example.com/#https%3A%2F%2Fwww.google.com%2FMy%20textMy%20title", - url_template_filled.spec()); - - // Two of each placeholder, some next to each other, others not. - url_template = - GURL("http://example.com/#{title}{url}{text}{text}{title}{url}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://example.com/" - "#My%20titlehttps%3A%2F%2Fwww.google.com%2FMy%20textMy%20textMy%" - "20titlehttps%3A%2F%2Fwww.google.com%2F", - url_template_filled.spec()); - - // Placeholders are in a query string, as values. The expected use case. - // Two of each placeholder, some next to each other, others not. - url_template = GURL( - "http://example.com?title={title}&url={url}&text={text}&text={text}&" - "title={title}&url={url}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://" - "example.com/?title=My%20title&url=https%3A%2F%2Fwww.google.com%2F&" - "text=My%20text&" - "text=My%20text&title=My%20title&url=https%3A%2F%2Fwww.google.com%2F", - url_template_filled.spec()); - - // Placeholder with digit character. - url_template = GURL("http://example.com/#{title1}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#", url_template_filled.spec()); - - // Empty placeholder. - url_template = GURL("http://example.com/#{}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#", url_template_filled.spec()); - - // Unexpected placeholders. - url_template = GURL("http://example.com/#{nonexistentplaceholder}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#", url_template_filled.spec()); - - // Placeholders should only be replaced in query and fragment. - url_template = GURL("http://example.com/subpath{title}/?q={title}#{title}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/subpath%7Btitle%7D/?q=My%20title#My%20title", - url_template_filled.spec()); - - // Braces in the path, which would be invalid, but should parse fine as they - // are escaped. - url_template = GURL("http://example.com/subpath{/?q={title}"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/subpath%7B/?q=My%20title", - url_template_filled.spec()); - - // |url_template| with % escapes. - url_template = GURL("http://example.com#%20{title}%20"); - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - url_template, kTitle, kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#%20My%20title%20", url_template_filled.spec()); -} - -// Test URL escaping done by ReplaceUrlPlaceholders(). -TEST_F(ShareServiceImplUnittest, ReplaceUrlPlaceholders_Escaping) { - const GURL kUrl(kUrlSpec); - const GURL kUrlTemplate("http://example.com/#{title}"); - - // Share data that contains percent escapes. - GURL url_template_filled; - bool succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, "My%20title", kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#My%2520title", url_template_filled.spec()); - - // Share data that contains placeholders. These should not be replaced. - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, "{title}", kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#%7Btitle%7D", url_template_filled.spec()); - - // All characters that shouldn't be escaped. - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, - "-_.!~*'()0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz", - kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://example.com/#-_.!~*'()0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz", - url_template_filled.spec()); - - // All characters that should be escaped. - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, " \"#$%&+,/:;<=>?@[\\]^`{|}", kText, kUrl, - &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ( - "http://example.com/" - "#%20%22%23%24%25%26%2B%2C%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%60%7B%7C%" - "7D", - url_template_filled.spec()); - - // Unicode chars. - // U+263B - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, "\xe2\x98\xbb", kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#%E2%98%BB", url_template_filled.spec()); - - // U+00E9 - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, "\xc3\xa9", kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#%C3%A9", url_template_filled.spec()); - - // U+1F4A9 - succeeded = ShareServiceImpl::ReplaceUrlPlaceholders( - kUrlTemplate, "\xf0\x9f\x92\xa9", kText, kUrl, &url_template_filled); - EXPECT_TRUE(succeeded); - EXPECT_EQ("http://example.com/#%F0%9F%92%A9", url_template_filled.spec()); -}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9043946..12b8b0ca 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2851,6 +2851,7 @@ "../browser/media/router/discovery/discovery_network_monitor_unittest.cc", "../browser/media/webrtc/tab_desktop_media_list_unittest.cc", "../browser/media/webrtc/webrtc_event_log_manager_unittest.cc", + "../browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc", "../browser/media_galleries/fileapi/native_media_file_util_unittest.cc", "../browser/media_galleries/gallery_watch_manager_unittest.cc", "../browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm", @@ -4908,6 +4909,11 @@ } if (is_mac) { + sources += [ + "base/interactive_test_utils_cocoa.h", + "base/interactive_test_utils_cocoa.mm", + ] + data_deps += [ "//chrome", "//chrome:chrome_framework", @@ -4922,7 +4928,6 @@ "../browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm", "../browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm", "../browser/ui/cocoa/translate/translate_bubble_test_utils_views_cocoa.mm", - "base/interactive_test_utils_cocoa.mm", ] } }
diff --git a/chrome/test/base/interactive_test_utils_cocoa.h b/chrome/test/base/interactive_test_utils_cocoa.h new file mode 100644 index 0000000..9bd2407 --- /dev/null +++ b/chrome/test/base/interactive_test_utils_cocoa.h
@@ -0,0 +1,27 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_COCOA_H_ +#define CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_COCOA_H_ + +#include "chrome/browser/ui/view_ids.h" + +class Browser; + +namespace ui_test_utils { +namespace internal { + +// Returns true of |vid| in |browser| is focused. +bool IsViewFocusedCocoa(const Browser* browser, ViewID vid); + +// Simulates a mouse click on |vid| in |browser|. +void ClickOnViewCocoa(const Browser* browser, ViewID vid); + +// Moves focus to |vid| in |browser| +void FocusViewCocoa(const Browser* browser, ViewID vid); + +} // namespace internal +} // namespace ui_test_utils + +#endif // CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_COCOA_H_
diff --git a/chrome/test/base/interactive_test_utils_cocoa.mm b/chrome/test/base/interactive_test_utils_cocoa.mm index 7743d9eb..ab1c185 100644 --- a/chrome/test/base/interactive_test_utils_cocoa.mm +++ b/chrome/test/base/interactive_test_utils_cocoa.mm
@@ -2,21 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/test/base/interactive_test_utils.h" +#include "chrome/test/base/interactive_test_utils_cocoa.h" #import <Cocoa/Cocoa.h> #include "base/bind.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "build/buildflag.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/view_id_util.h" +#include "chrome/test/base/interactive_test_utils.h" #include "ui/base/cocoa/cocoa_base_utils.h" +#include "ui/base/ui_features.h" namespace ui_test_utils { +namespace internal { + namespace { void MoveMouseToNSViewCenterAndPress( @@ -43,7 +48,7 @@ } // namespace -bool IsViewFocused(const Browser* browser, ViewID vid) { +bool IsViewFocusedCocoa(const Browser* browser, ViewID vid) { NSWindow* window = browser->window()->GetNativeWindow(); DCHECK(window); NSView* view = view_id_util::GetView(window, vid); @@ -72,7 +77,7 @@ return false; } -void ClickOnView(const Browser* browser, ViewID vid) { +void ClickOnViewCocoa(const Browser* browser, ViewID vid) { NSWindow* window = browser->window()->GetNativeWindow(); DCHECK(window); NSView* view = view_id_util::GetView(window, vid); @@ -85,12 +90,28 @@ content::RunMessageLoop(); } +void FocusViewCocoa(const Browser* browser, ViewID vid) { + NSWindow* window = browser->window()->GetNativeWindow(); + DCHECK(window); + NSView* view = view_id_util::GetView(window, vid); + DCHECK(view); + [window makeFirstResponder:view]; +} + +} // namespace internal + +#if !BUILDFLAG(MAC_VIEWS_BROWSER) +bool IsViewFocused(const Browser* browser, ViewID vid) { + return internal::IsViewFocusedCocoa(browser, vid); +} + +void ClickOnView(const Browser* browser, ViewID vid) { + internal::ClickOnViewCocoa(browser, vid); +} + void FocusView(const Browser* browser, ViewID vid) { - NSWindow* window = browser->window()->GetNativeWindow(); - DCHECK(window); - NSView* view = view_id_util::GetView(window, vid); - DCHECK(view); - [window makeFirstResponder:view]; - } + internal::FocusViewCocoa(browser, vid); +} +#endif // !BUILDFLAG(MAC_VIEWS_BROWSER) } // namespace ui_test_utils
diff --git a/chrome/test/base/interactive_test_utils_views.cc b/chrome/test/base/interactive_test_utils_views.cc index f1dce9d..5388a78f 100644 --- a/chrome/test/base/interactive_test_utils_views.cc +++ b/chrome/test/base/interactive_test_utils_views.cc
@@ -5,13 +5,25 @@ #include "chrome/test/base/interactive_test_utils.h" #include "base/message_loop/message_loop.h" +#include "build/buildflag.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views_mode_controller.h" +#include "ui/base/ui_features.h" #include "ui/views/focus/focus_manager.h" +#if BUILDFLAG(MAC_VIEWS_BROWSER) +#include "chrome/test/base/interactive_test_utils_cocoa.h" +#endif + namespace ui_test_utils { bool IsViewFocused(const Browser* browser, ViewID vid) { +#if BUILDFLAG(MAC_VIEWS_BROWSER) + if (views_mode_controller::IsViewsBrowserCocoa()) + return internal::IsViewFocusedCocoa(browser, vid); +#endif + BrowserWindow* browser_window = browser->window(); DCHECK(browser_window); gfx::NativeWindow window = browser_window->GetNativeWindow(); @@ -25,6 +37,11 @@ } void ClickOnView(const Browser* browser, ViewID vid) { +#if BUILDFLAG(MAC_VIEWS_BROWSER) + if (views_mode_controller::IsViewsBrowserCocoa()) + return internal::ClickOnViewCocoa(browser, vid); +#endif + views::View* view = BrowserView::GetBrowserViewForBrowser(browser)->GetViewByID(vid); DCHECK(view); @@ -35,6 +52,11 @@ } void FocusView(const Browser* browser, ViewID vid) { +#if BUILDFLAG(MAC_VIEWS_BROWSER) + if (views_mode_controller::IsViewsBrowserCocoa()) + return internal::FocusViewCocoa(browser, vid); +#endif + views::View* view = BrowserView::GetBrowserViewForBrowser(browser)->GetViewByID(vid); DCHECK(view);
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py index dca48d4..a267c39 100644 --- a/chrome/test/chromedriver/client/command_executor.py +++ b/chrome/test/chromedriver/client/command_executor.py
@@ -62,6 +62,8 @@ HOVER_OVER_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/hover') GET_ELEMENT_LOCATION = ( _Method.GET, '/session/:sessionId/element/:id/location') + GET_ELEMENT_RECT = ( + _Method.GET, '/session/:sessionId/element/:id/rect') GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW = ( _Method.GET, '/session/:sessionId/element/:id/location_in_view') GET_ELEMENT_SIZE = (_Method.GET, '/session/:sessionId/element/:id/size')
diff --git a/chrome/test/chromedriver/client/webelement.py b/chrome/test/chromedriver/client/webelement.py index 1e150f38..f1a0796 100644 --- a/chrome/test/chromedriver/client/webelement.py +++ b/chrome/test/chromedriver/client/webelement.py
@@ -61,5 +61,8 @@ def GetLocation(self): return self._Execute(Command.GET_ELEMENT_LOCATION) + def GetRect(self): + return self._Execute(Command.GET_ELEMENT_RECT) + def IsDisplayed(self): return self._Execute(Command.IS_ELEMENT_DISPLAYED)
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc index e5edc7ff..6358b81 100644 --- a/chrome/test/chromedriver/element_commands.cc +++ b/chrome/test/chromedriver/element_commands.cc
@@ -469,6 +469,58 @@ value); } +Status ExecuteGetElementRect(Session* session, + WebView* web_view, + const std::string& element_id, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value) { + base::ListValue args; + args.Append(CreateElement(element_id)); + + std::unique_ptr<base::Value> location; + Status status = web_view->CallFunction( + session->GetCurrentFrameId(), + webdriver::atoms::asString(webdriver::atoms::GET_LOCATION), args, + &location); + if (status.IsError()) + return status; + + std::unique_ptr<base::Value> size; + web_view->CallFunction(session->GetCurrentFrameId(), + webdriver::atoms::asString(webdriver::atoms::GET_SIZE), + args, &size); + + // do type conversions + base::DictionaryValue* size_dict; + if (!size->GetAsDictionary(&size_dict)) + return Status(kUnknownError, "could not convert to DictionaryValue"); + base::DictionaryValue* location_dict; + if (!location->GetAsDictionary(&location_dict)) + return Status(kUnknownError, "could not convert to DictionaryValue"); + + // grab values + int x, y, width, height; + if (!location_dict->GetInteger("x", &x)) + return Status(kUnknownError, "getting size failed to return x"); + + if (!location_dict->GetInteger("y", &y)) + return Status(kUnknownError, "getting size failed to return y"); + + if (!size_dict->GetInteger("height", &height)) + return Status(kUnknownError, "getting location failed to return height"); + + if (!size_dict->GetInteger("width", &width)) + return Status(kUnknownError, "getting location failed to return width"); + + base::DictionaryValue ret; + ret.SetInteger("x", x); + ret.SetInteger("y", y); + ret.SetInteger("width", width); + ret.SetInteger("height", height); + value->reset(ret.DeepCopy()); + return Status(kOk); +} + Status ExecuteGetElementLocationOnceScrolledIntoView( Session* session, WebView* web_view,
diff --git a/chrome/test/chromedriver/element_commands.h b/chrome/test/chromedriver/element_commands.h index 320c3ee..566d29d 100644 --- a/chrome/test/chromedriver/element_commands.h +++ b/chrome/test/chromedriver/element_commands.h
@@ -161,6 +161,12 @@ const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); +Status ExecuteGetElementRect(Session* session, + WebView* web_view, + const std::string& element_id, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value); + // Returns the location of a given element in client coordinates, after // scrolling it into view. Status ExecuteGetElementLocationOnceScrolledIntoView(
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 9374edda..25a7bfa 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -318,6 +318,9 @@ WrapToCommand("GetElementLocation", base::Bind(&ExecuteGetElementLocation))), CommandMapping( + kGet, "session/:sessionId/element/:id/rect", + WrapToCommand("GetElementRect", base::Bind(&ExecuteGetElementRect))), + CommandMapping( kGet, "session/:sessionId/element/:id/location_in_view", WrapToCommand( "GetElementLocationInView",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index eec3f7d..c16322f 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1362,6 +1362,16 @@ self._driver.TouchUp(location['x'] + 1, location['y'] + 1) self.assertEquals('events: touchstart touchmove touchend', events.GetText()) + def testGetElementRect(self): + self._driver.Load(self.GetHttpUrlForFile( + '/chromedriver/absolute_position_element.html')) + target = self._driver.FindElement('id', 'target') + rect = target.GetRect() + self.assertEquals(18, rect['x']) + self.assertEquals(10, rect['y']) + self.assertEquals(200, rect['height']) + self.assertEquals(210, rect['width']) + def testTouchScrollElement(self): self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/touch_action_tests.html'))
diff --git a/chrome/test/data/chromedriver/absolute_position_element.html b/chrome/test/data/chromedriver/absolute_position_element.html new file mode 100644 index 0000000..1d00a4a --- /dev/null +++ b/chrome/test/data/chromedriver/absolute_position_element.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> + <body> + <div x="80px" y="10px" style="position: absolute; left: 18px; top: 10px; width: 210px; height: 200px;" type="text" id="target"> + </body> +</html>
diff --git a/chrome/test/data/plugin_power_saver/poster_tests.html b/chrome/test/data/plugin_power_saver/poster_tests.html index 0bfefb4..c9afb75 100644 --- a/chrome/test/data/plugin_power_saver/poster_tests.html +++ b/chrome/test/data/plugin_power_saver/poster_tests.html
@@ -1,3 +1,10 @@ +<head> + <style> + * { + line-height: 18px; + } + </style> +</head> <object id='plugin_src' type='application/x-shockwave-flash' width='100' height='100' poster='click_me.png'></object> <object id='plugin_srcset' type='application/x-shockwave-flash' width='100'
diff --git a/chrome/test/data/plugin_power_saver/small_cross_origin.html b/chrome/test/data/plugin_power_saver/small_cross_origin.html index 432ddcf..340f521 100644 --- a/chrome/test/data/plugin_power_saver/small_cross_origin.html +++ b/chrome/test/data/plugin_power_saver/small_cross_origin.html
@@ -1,3 +1,10 @@ +<head> + <style> + * { + line-height: 18px; + } + </style> +</head> <object id='plugin' data='http://otherorigin.com/fake.swf' type='application/x-shockwave-flash' width='400' height='100'></object> <br>
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc index 69e5aca..afa3c9f4 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -887,8 +887,9 @@ RunBasicTest(); } +// TODO(crbug.com/822300): Flaky test. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationIncognitoBrowserTest, - ReconnectSession) { + MANUAL_ReconnectSession) { RunReconnectSessionTest(); }
diff --git a/components/BUILD.gn b/components/BUILD.gn index 16f332d..7166a3b 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -581,5 +581,15 @@ deps += [ "//v8:v8_external_startup_data_assets" ] } } + + if (!is_android) { + sources += [ "safe_browsing/db/v4_store_perftest.cc" ] + deps += [ + "//components/safe_browsing/db:v4_protocol_manager_util", + "//components/safe_browsing/db:v4_store", + "//components/safe_browsing/db:v4_test_util", + "//crypto", + ] + } } }
diff --git a/components/arc/common/usb_host.mojom b/components/arc/common/usb_host.mojom index d47e6df7..a08aecb9 100644 --- a/components/arc/common/usb_host.mojom +++ b/components/arc/common/usb_host.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next MinVersion: 1 +// Next MinVersion: 2 module arc.mojom; // re-use device.mojom.UsbDeviceInfo @@ -10,11 +10,14 @@ // Next method ID: 3 interface UsbHostHost { - // Tries the open the USB device node for the device named 'guid' - // and returns an open file descriptor to this node. - // You need to have previously called RequestPermission for this 'guid' - // else this call will fail. - OpenDevice@0(string guid) => (handle usb_fd); + // Tries to open the USB device node for the device named 'guid' for caller + // 'pkg_name' and returns an open file descriptor to this node. 'pkg_name' + // needs to have previously called RequestPermission for this 'guid' else this + // call will fail. Note the 'pkg_name' is informational purposes only, there + // is no effective way that host can restrict access to only a specific + // package at the security boundary formed by this Mojo interface. + OpenDevice@0(string guid, + [Minversion=1] string? pkg_name) => (handle usb_fd); // Returns the USB device descriptors for the device named 'guid'. GetDeviceInfo@1(string guid) => (string device_name,
diff --git a/components/arc/usb/usb_host_bridge.cc b/components/arc/usb/usb_host_bridge.cc index 1a00796..2aed8b9 100644 --- a/components/arc/usb/usb_host_bridge.cc +++ b/components/arc/usb/usb_host_bridge.cc
@@ -120,14 +120,14 @@ RequestPermissionCallback callback) { VLOG(2) << "USB RequestPermission " << guid << " package " << package; // Permission already requested. - if (HasPermissionForDevice(guid)) { + if (HasPermissionForDevice(guid, package)) { std::move(callback).Run(true); return; } // The other side was just checking, fail without asking the user. if (!interactive) { - std::move(callback).Run(false); + std::move(callback).Run(HasPermissionForDevice(guid, package)); return; } @@ -136,8 +136,9 @@ } void ArcUsbHostBridge::OpenDevice(const std::string& guid, + const base::Optional<std::string>& package, OpenDeviceCallback callback) { - if (!usb_service_) { + if (!usb_service_ || !package) { std::move(callback).Run(mojo::ScopedHandle()); return; } @@ -150,7 +151,7 @@ } // The RequestPermission was never done, abort. - if (!HasPermissionForDevice(guid)) { + if (!HasPermissionForDevice(guid, package.value())) { std::move(callback).Run(mojo::ScopedHandle()); return; } @@ -297,10 +298,23 @@ std::move(callback)); } -bool ArcUsbHostBridge::HasPermissionForDevice(const std::string& guid) { - // TODO(lgcheng): implement permission settings - // fail close for now - return false; +bool ArcUsbHostBridge::HasPermissionForDevice(const std::string& guid, + const std::string& package) { + if (!ui_delegate_) + return false; + + if (!usb_service_) + return false; + + scoped_refptr<device::UsbDevice> device = usb_service_->GetDevice(guid); + if (!device.get()) { + LOG(WARNING) << "Unknown USB device " << guid; + return false; + } + + return ui_delegate_->HasUsbAccessPermission( + package, guid, device->serial_number(), device->vendor_id(), + device->product_id()); } } // namespace arc
diff --git a/components/arc/usb/usb_host_bridge.h b/components/arc/usb/usb_host_bridge.h index f5490349..df88128f 100644 --- a/components/arc/usb/usb_host_bridge.h +++ b/components/arc/usb/usb_host_bridge.h
@@ -54,6 +54,7 @@ bool interactive, RequestPermissionCallback callback) override; void OpenDevice(const std::string& guid, + const base::Optional<std::string>& package, OpenDeviceCallback callback) override; void GetDeviceInfo(const std::string& guid, GetDeviceInfoCallback callback) override; @@ -77,7 +78,8 @@ void DoRequestUserAuthorization(const std::string& guid, const std::string& package, RequestPermissionCallback callback); - bool HasPermissionForDevice(const std::string& guid); + bool HasPermissionForDevice(const std::string& guid, + const std::string& package); ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. mojom::UsbHostHostPtr usb_host_ptr_;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc index cf3e45b..ef2d3122 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -373,6 +373,12 @@ DataReductionProxyInfo* data_reduction_proxy_info) { DCHECK(data_reduction_proxy_info); + // Responses from the warmup URL probe should not be checked for bypass types. + // Doing so may unnecessarily cause all data saver proxies to be marked as + // bad (e.g., when via header is missing on the response to the probe from the + // HTTP proxy). + DCHECK(url_chain.empty() || (params::GetWarmupURL() != url_chain.back())); + bool has_via_header = HasDataReductionProxyViaHeader(headers, nullptr); if (has_via_header && HasURLRedirectCycle(url_chain)) {
diff --git a/components/download/content/internal/download_driver_impl.cc b/components/download/content/internal/download_driver_impl.cc index 47a9e6b..050d79d7 100644 --- a/components/download/content/internal/download_driver_impl.cc +++ b/components/download/content/internal/download_driver_impl.cc
@@ -138,6 +138,7 @@ const RequestParams& request_params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(!request_params.url.is_empty()); DCHECK(!guid.empty()); @@ -168,6 +169,7 @@ download_url_params->set_fetch_error_body(true); download_url_params->set_download_source( download::DownloadSource::INTERNAL_API); + download_url_params->set_post_body(post_body); download_manager_->DownloadUrl(std::move(download_url_params), nullptr); }
diff --git a/components/download/content/internal/download_driver_impl.h b/components/download/content/internal/download_driver_impl.h index bc3a06e..f9a155f60 100644 --- a/components/download/content/internal/download_driver_impl.h +++ b/components/download/content/internal/download_driver_impl.h
@@ -42,6 +42,7 @@ const RequestParams& request_params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) override; void Remove(const std::string& guid) override; void Pause(const std::string& guid) override;
diff --git a/components/download/internal/background_service/config.cc b/components/download/internal/background_service/config.cc index 81aaaaa..99529ad7 100644 --- a/components/download/internal/background_service/config.cc +++ b/components/download/internal/background_service/config.cc
@@ -76,6 +76,10 @@ const base::TimeDelta kDefaultNavigationTimeoutDelay = base::TimeDelta::FromSeconds(300); +// The default timeout for a pending upload. +const base::TimeDelta kDefaultPendingUploadTimeoutDelay = + base::TimeDelta::FromSeconds(30); + // The default value of download retry delay when the download is failed. const base::TimeDelta kDefaultDownloadRetryDelay = base::TimeDelta::FromSeconds(20); @@ -146,6 +150,11 @@ base::TimeDelta::FromSeconds(base::saturated_cast<int>( GetFinchConfigUInt(kNavigationTimeoutDelaySecondsConfig, kDefaultNavigationTimeoutDelay.InSeconds()))); + config->pending_upload_timeout_delay = + base::TimeDelta::FromSeconds(base::saturated_cast<int>( + GetFinchConfigUInt(kPendingUploadTimeoutDelaySecondsConfig, + kDefaultPendingUploadTimeoutDelay.InSeconds()))); + config->download_retry_delay = base::TimeDelta::FromMilliseconds(base::saturated_cast<int>( GetFinchConfigUInt(kDownloadRetryDelayMsConfig, @@ -170,6 +179,7 @@ network_change_delay(kDefaultNetworkChangeDelay), navigation_completion_delay(kDefaultNavigationCompletionDelay), navigation_timeout_delay(kDefaultNavigationTimeoutDelay), + pending_upload_timeout_delay(kDefaultPendingUploadTimeoutDelay), download_retry_delay(kDefaultDownloadRetryDelay) {} } // namespace download
diff --git a/components/download/internal/background_service/config.h b/components/download/internal/background_service/config.h index 67276613..4e276f3 100644 --- a/components/download/internal/background_service/config.h +++ b/components/download/internal/background_service/config.h
@@ -69,6 +69,12 @@ constexpr char kNavigationTimeoutDelaySecondsConfig[] = "navigation_timeout_delay_seconds"; +// Configuration name for the timeout value after which an upload will be killed +// if the client still hasn't responded with the upload data. Measured in +// seconds. +constexpr char kPendingUploadTimeoutDelaySecondsConfig[] = + "pending_upload_timeout_delay_seconds"; + // Configuration name for the retry delay when the download is failed, measured // in milliseconds. constexpr char kDownloadRetryDelayMsConfig[] = "retry_delay_ms"; @@ -142,6 +148,10 @@ // The timeout to wait for after a navigation starts. base::TimeDelta navigation_timeout_delay; + // The timeout after which upload entries waiting on data from their clients + // will be aborted. + base::TimeDelta pending_upload_timeout_delay; + // The delay to retry a download when the download is failed. base::TimeDelta download_retry_delay;
diff --git a/components/download/internal/background_service/controller_impl.cc b/components/download/internal/background_service/controller_impl.cc index a0b841e0..77e5ada 100644 --- a/components/download/internal/background_service/controller_impl.cc +++ b/components/download/internal/background_service/controller_impl.cc
@@ -32,6 +32,7 @@ #include "components/download/public/background_service/download_metadata.h" #include "components/download/public/background_service/navigation_monitor.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request_body.h" namespace download { namespace { @@ -962,7 +963,7 @@ } else { stats::LogEntryEvent(stats::DownloadEvent::START); driver_->Start( - entry->request_params, entry->guid, entry->target_file_path, + entry->request_params, entry->guid, entry->target_file_path, nullptr, net::NetworkTrafficAnnotationTag(entry->traffic_annotation)); } }
diff --git a/components/download/internal/background_service/controller_impl_unittest.cc b/components/download/internal/background_service/controller_impl_unittest.cc index d98af57a..aaa2dda 100644 --- a/components/download/internal/background_service/controller_impl_unittest.cc +++ b/components/download/internal/background_service/controller_impl_unittest.cc
@@ -31,6 +31,7 @@ #include "components/download/public/background_service/test/empty_client.h" #include "components/download/public/background_service/test/mock_client.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/resource_request_body.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1129,7 +1130,7 @@ EXPECT_CALL(*client_, OnDownloadFailed(entry2.guid, Client::FailureReason::ABORTED)) .Times(1); - driver_->Start(RequestParams(), entry2.guid, entry2.target_file_path, + driver_->Start(RequestParams(), entry2.guid, entry2.target_file_path, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); // Test FailureReason::NETWORK. @@ -1346,6 +1347,7 @@ // Simulate a successful external download. driver_->NotifyDownloadSucceeded(dentry2); + task_runner_->RunUntilIdle(); EXPECT_TRUE(driver_->Find(entry1.guid).has_value()); EXPECT_FALSE(driver_->Find(entry1.guid).value().paused); @@ -1391,7 +1393,7 @@ // Simulate a newly created external download. driver_->Start(RequestParams(), dentry2.guid, dentry2.current_file_path, - TRAFFIC_ANNOTATION_FOR_TESTS); + nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_TRUE(driver_->Find(entry1.guid).value().paused); EXPECT_FALSE(driver_->Find(entry2.guid).value().paused); @@ -1420,7 +1422,7 @@ // Rebuild the download so we can simulate more. dentry2.state = DriverEntry::State::IN_PROGRESS; driver_->Start(RequestParams(), dentry2.guid, dentry2.current_file_path, - TRAFFIC_ANNOTATION_FOR_TESTS); + nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_TRUE(driver_->Find(entry1.guid).value().paused); EXPECT_FALSE(driver_->Find(entry2.guid).value().paused);
diff --git a/components/download/internal/background_service/debugging_client.cc b/components/download/internal/background_service/debugging_client.cc index dedf1c1..427bf4d 100644 --- a/components/download/internal/background_service/debugging_client.cc +++ b/components/download/internal/background_service/debugging_client.cc
@@ -4,6 +4,9 @@ #include "components/download/internal/background_service/debugging_client.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "services/network/public/cpp/resource_request_body.h" + namespace download { void DebuggingClient::OnServiceInitialized( @@ -37,4 +40,10 @@ return true; } +void DebuggingClient::GetUploadData(const std::string& guid, + GetUploadDataCallback callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); +} + } // namespace download
diff --git a/components/download/internal/background_service/debugging_client.h b/components/download/internal/background_service/debugging_client.h index bd249f3..89fc7a5 100644 --- a/components/download/internal/background_service/debugging_client.h +++ b/components/download/internal/background_service/debugging_client.h
@@ -34,6 +34,8 @@ const CompletionInfo& completion_info) override; bool CanServiceRemoveDownloadedFile(const std::string& guid, bool force_delete) override; + void GetUploadData(const std::string& guid, + GetUploadDataCallback callback) override; DISALLOW_COPY_AND_ASSIGN(DebuggingClient); };
diff --git a/components/download/internal/background_service/download_driver.h b/components/download/internal/background_service/download_driver.h index 476fa76..0243340 100644 --- a/components/download/internal/background_service/download_driver.h +++ b/components/download/internal/background_service/download_driver.h
@@ -17,6 +17,10 @@ class FilePath; } // namespace base +namespace network { +class ResourceRequestBody; +} // namespace network + namespace download { struct RequestParams; @@ -84,6 +88,7 @@ const RequestParams& request_params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) = 0; // Cancels an existing download, all data associated with this download should
diff --git a/components/download/internal/background_service/entry.cc b/components/download/internal/background_service/entry.cc index 137b390..c13e42d 100644 --- a/components/download/internal/background_service/entry.cc +++ b/components/download/internal/background_service/entry.cc
@@ -12,7 +12,8 @@ : bytes_downloaded(0u), attempt_count(0), resumption_count(0), - cleanup_attempt_count(0) {} + cleanup_attempt_count(0), + has_upload_data(false) {} Entry::Entry(const Entry& other) = default; Entry::Entry(const DownloadParams& params) @@ -25,6 +26,7 @@ attempt_count(0), resumption_count(0), cleanup_attempt_count(0), + has_upload_data(false), traffic_annotation(params.traffic_annotation) {} Entry::~Entry() = default; @@ -49,6 +51,7 @@ attempt_count == other.attempt_count && resumption_count == other.resumption_count && cleanup_attempt_count == other.cleanup_attempt_count && + has_upload_data == other.has_upload_data && traffic_annotation == other.traffic_annotation; }
diff --git a/components/download/internal/background_service/entry.h b/components/download/internal/background_service/entry.h index f3efe2b..85a24e3 100644 --- a/components/download/internal/background_service/entry.h +++ b/components/download/internal/background_service/entry.h
@@ -96,6 +96,9 @@ // Stores the number of times the service tried to delete the download file. uint32_t cleanup_attempt_count; + // Stores whether this request also has some data to be uploaded. + bool has_upload_data; + // Traffic annotation for the network request. net::MutableNetworkTrafficAnnotationTag traffic_annotation; };
diff --git a/components/download/internal/background_service/in_memory_download_driver.cc b/components/download/internal/background_service/in_memory_download_driver.cc index 9425674..99ba097 100644 --- a/components/download/internal/background_service/in_memory_download_driver.cc +++ b/components/download/internal/background_service/in_memory_download_driver.cc
@@ -5,6 +5,7 @@ #include "components/download/internal/background_service/in_memory_download_driver.h" #include "components/download/internal/background_service/in_memory_download.h" +#include "services/network/public/cpp/resource_request_body.h" namespace download { @@ -97,6 +98,7 @@ const RequestParams& request_params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) { std::unique_ptr<InMemoryDownload> download = download_factory_->Create(guid, request_params, traffic_annotation, this);
diff --git a/components/download/internal/background_service/in_memory_download_driver.h b/components/download/internal/background_service/in_memory_download_driver.h index 881a0b9..b159499 100644 --- a/components/download/internal/background_service/in_memory_download_driver.h +++ b/components/download/internal/background_service/in_memory_download_driver.h
@@ -61,6 +61,7 @@ const RequestParams& request_params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) override; void Remove(const std::string& guid) override; void Pause(const std::string& guid) override;
diff --git a/components/download/internal/background_service/in_memory_download_driver_unittest.cc b/components/download/internal/background_service/in_memory_download_driver_unittest.cc index 675391c..cc7af9b 100644 --- a/components/download/internal/background_service/in_memory_download_driver_unittest.cc +++ b/components/download/internal/background_service/in_memory_download_driver_unittest.cc
@@ -8,6 +8,7 @@ #include "components/download/internal/background_service/test/mock_download_driver_client.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/resource_request_body.h" #include "storage/browser/blob/blob_data_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -111,7 +112,7 @@ void Start(const std::string& guid) { RequestParams params; base::FilePath path; - driver()->Start(params, guid, path, TRAFFIC_ANNOTATION_FOR_TESTS); + driver()->Start(params, guid, path, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); } private:
diff --git a/components/download/internal/background_service/proto/entry.proto b/components/download/internal/background_service/proto/entry.proto index 2e7cfbb..9ebdbca 100644 --- a/components/download/internal/background_service/proto/entry.proto +++ b/components/download/internal/background_service/proto/entry.proto
@@ -66,4 +66,5 @@ optional uint32 cleanup_attempt_count = 13; optional uint32 resumption_count = 14; + optional bool has_upload_data = 15; }
diff --git a/components/download/internal/background_service/proto_conversions.cc b/components/download/internal/background_service/proto_conversions.cc index ef1398eb..efd23472 100644 --- a/components/download/internal/background_service/proto_conversions.cc +++ b/components/download/internal/background_service/proto_conversions.cc
@@ -281,6 +281,7 @@ entry.attempt_count = proto.attempt_count(); entry.resumption_count = proto.resumption_count(); entry.cleanup_attempt_count = proto.cleanup_attempt_count(); + entry.has_upload_data = proto.has_upload_data(); entry.traffic_annotation = net::MutableNetworkTrafficAnnotationTag({proto.traffic_annotation()}); entry.bytes_downloaded = proto.bytes_downloaded(); @@ -305,6 +306,7 @@ proto.set_attempt_count(entry.attempt_count); proto.set_resumption_count(entry.resumption_count); proto.set_cleanup_attempt_count(entry.cleanup_attempt_count); + proto.set_has_upload_data(entry.has_upload_data); proto.set_traffic_annotation(entry.traffic_annotation.unique_id_hash_code); proto.set_bytes_downloaded(entry.bytes_downloaded); return proto;
diff --git a/components/download/internal/background_service/test/BUILD.gn b/components/download/internal/background_service/test/BUILD.gn index 6dc81dd7..0ed3e44 100644 --- a/components/download/internal/background_service/test/BUILD.gn +++ b/components/download/internal/background_service/test/BUILD.gn
@@ -43,5 +43,6 @@ deps = [ "//components/download/internal/background_service:internal", + "//services/network/public/cpp", ] }
diff --git a/components/download/internal/background_service/test/test_download_driver.cc b/components/download/internal/background_service/test/test_download_driver.cc index 17a91765..54634cf 100644 --- a/components/download/internal/background_service/test/test_download_driver.cc +++ b/components/download/internal/background_service/test/test_download_driver.cc
@@ -7,6 +7,7 @@ #include "base/files/file_path.h" #include "components/download/public/background_service/download_params.h" #include "net/http/http_response_headers.h" +#include "services/network/public/cpp/resource_request_body.h" namespace download { namespace test { @@ -71,6 +72,7 @@ const RequestParams& params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) { DriverEntry entry; entry.guid = guid;
diff --git a/components/download/internal/background_service/test/test_download_driver.h b/components/download/internal/background_service/test/test_download_driver.h index 9e89577..34b4e86 100644 --- a/components/download/internal/background_service/test/test_download_driver.h +++ b/components/download/internal/background_service/test/test_download_driver.h
@@ -42,6 +42,7 @@ const RequestParams& params, const std::string& guid, const base::FilePath& file_path, + scoped_refptr<network::ResourceRequestBody> post_body, const net::NetworkTrafficAnnotationTag& traffic_annotation) override; void Remove(const std::string& guid) override; void Pause(const std::string& guid) override;
diff --git a/components/download/public/background_service/DEPS b/components/download/public/background_service/DEPS index 072ddca8..4d8aa673 100644 --- a/components/download/public/background_service/DEPS +++ b/components/download/public/background_service/DEPS
@@ -4,6 +4,7 @@ "+components/keyed_service", "+net/http", "+net/traffic_annotation", + "+services/network/public/cpp", "+storage/browser", "+url", ]
diff --git a/components/download/public/background_service/client.h b/components/download/public/background_service/client.h index 8f0e6bcc..d42380e6 100644 --- a/components/download/public/background_service/client.h +++ b/components/download/public/background_service/client.h
@@ -8,15 +8,23 @@ #include <string> #include <vector> +#include "base/callback.h" #include "base/files/file_path.h" #include "net/http/http_response_headers.h" #include "url/gurl.h" +namespace network { +class ResourceRequestBody; +} // namespace network + namespace download { struct CompletionInfo; struct DownloadMetaData; +using GetUploadDataCallback = + base::OnceCallback<void(scoped_refptr<network::ResourceRequestBody>)>; + // The Client interface required by any feature that wants to start a download // through the DownloadService. Should be registered immediately at startup // when the DownloadService is created (see the factory). @@ -116,6 +124,12 @@ // the outcome of this function. virtual bool CanServiceRemoveDownloadedFile(const std::string& guid, bool force_delete) = 0; + + // Called by the service to ask the client to provide the upload data. + // The client is responsible for posting the callback with an appropriate + // ResourceRequestBody or nullptr, if it is a regular download. + virtual void GetUploadData(const std::string& guid, + GetUploadDataCallback callback) = 0; }; } // namespace download
diff --git a/components/download/public/background_service/test/BUILD.gn b/components/download/public/background_service/test/BUILD.gn index 39bfe9bb..fbe08cec 100644 --- a/components/download/public/background_service/test/BUILD.gn +++ b/components/download/public/background_service/test/BUILD.gn
@@ -23,6 +23,10 @@ "test_download_service.h", ] + deps = [ + "//services/network/public/cpp", + ] + public_deps = [ "//base", "//components/download/public/background_service:public",
diff --git a/components/download/public/background_service/test/empty_client.cc b/components/download/public/background_service/test/empty_client.cc index c908732ce..231e152 100644 --- a/components/download/public/background_service/test/empty_client.cc +++ b/components/download/public/background_service/test/empty_client.cc
@@ -4,6 +4,9 @@ #include "components/download/public/background_service/test/empty_client.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "services/network/public/cpp/resource_request_body.h" + namespace download { namespace test { @@ -33,5 +36,11 @@ return true; } +void EmptyClient::GetUploadData(const std::string& guid, + GetUploadDataCallback callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); +} + } // namespace test } // namespace download
diff --git a/components/download/public/background_service/test/empty_client.h b/components/download/public/background_service/test/empty_client.h index d708d83..2c911e0 100644 --- a/components/download/public/background_service/test/empty_client.h +++ b/components/download/public/background_service/test/empty_client.h
@@ -33,6 +33,8 @@ const CompletionInfo& completion_info) override; bool CanServiceRemoveDownloadedFile(const std::string& guid, bool force_delete) override; + void GetUploadData(const std::string& guid, + GetUploadDataCallback callback) override; private: DISALLOW_COPY_AND_ASSIGN(EmptyClient);
diff --git a/components/download/public/background_service/test/mock_client.cc b/components/download/public/background_service/test/mock_client.cc index 7ae6151b..99662f1 100644 --- a/components/download/public/background_service/test/mock_client.cc +++ b/components/download/public/background_service/test/mock_client.cc
@@ -4,11 +4,20 @@ #include "components/download/public/background_service/test/mock_client.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "services/network/public/cpp/resource_request_body.h" + namespace download { namespace test { MockClient::MockClient() = default; MockClient::~MockClient() = default; +void MockClient::GetUploadData(const std::string& guid, + GetUploadDataCallback callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); +} + } // namespace test } // namespace download
diff --git a/components/download/public/background_service/test/mock_client.h b/components/download/public/background_service/test/mock_client.h index a96c3885..763d650 100644 --- a/components/download/public/background_service/test/mock_client.h +++ b/components/download/public/background_service/test/mock_client.h
@@ -32,6 +32,8 @@ MOCK_METHOD2(OnDownloadSucceeded, void(const std::string&, const CompletionInfo&)); MOCK_METHOD2(CanServiceRemoveDownloadedFile, bool(const std::string&, bool)); + void GetUploadData(const std::string& guid, + GetUploadDataCallback callback) override; private: DISALLOW_COPY_AND_ASSIGN(MockClient);
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc index 837b295..07f59dd 100644 --- a/components/history/core/browser/download_database.cc +++ b/components/history/core/browser/download_database.cc
@@ -453,8 +453,6 @@ info->total_bytes = statement_main.ColumnInt64(column++); int state = statement_main.ColumnInt(column++); info->state = IntToDownloadState(state); - if (info->state == DownloadState::INVALID) - UMA_HISTOGRAM_COUNTS("Download.DatabaseInvalidState", state); info->danger_type = IntToDownloadDangerType(statement_main.ColumnInt(column++)); info->interrupt_reason =
diff --git a/components/omnibox/browser/vector_icons/blank.1x.icon b/components/omnibox/browser/vector_icons/blank.1x.icon index 4e64b92..27913f6c 100644 --- a/components/omnibox/browser/vector_icons/blank.1x.icon +++ b/components/omnibox/browser/vector_icons/blank.1x.icon
@@ -2,5 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -END +CANVAS_DIMENSIONS, 16
diff --git a/components/omnibox/browser/vector_icons/blank.icon b/components/omnibox/browser/vector_icons/blank.icon index d7b844f..521d94a 100644 --- a/components/omnibox/browser/vector_icons/blank.icon +++ b/components/omnibox/browser/vector_icons/blank.icon
@@ -2,5 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 32, -END +CANVAS_DIMENSIONS, 32
diff --git a/components/omnibox/browser/vector_icons/calculator.1x.icon b/components/omnibox/browser/vector_icons/calculator.1x.icon index 351e9f5..4ddd046 100644 --- a/components/omnibox/browser/vector_icons/calculator.1x.icon +++ b/components/omnibox/browser/vector_icons/calculator.1x.icon
@@ -16,5 +16,4 @@ LINE_TO, 4, 11, LINE_TO, 4, 9, LINE_TO, 4, 9, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/calculator.icon b/components/omnibox/browser/vector_icons/calculator.icon index 33a96db..da2e2f4 100644 --- a/components/omnibox/browser/vector_icons/calculator.icon +++ b/components/omnibox/browser/vector_icons/calculator.icon
@@ -16,5 +16,4 @@ LINE_TO, 8, 21, LINE_TO, 8, 18, LINE_TO, 8, 18, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/extension_app.1x.icon b/components/omnibox/browser/vector_icons/extension_app.1x.icon index d4782de..d2079f6 100644 --- a/components/omnibox/browser/vector_icons/extension_app.1x.icon +++ b/components/omnibox/browser/vector_icons/extension_app.1x.icon
@@ -32,5 +32,4 @@ CUBIC_TO, 14.36f, 9.57f, 15, 8.93f, 15, 8.14f, CUBIC_TO, 15, 7.35f, 14.36f, 6.71f, 13.57f, 6.71f, LINE_TO, 12.71f, 6.71f, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/extension_app.icon b/components/omnibox/browser/vector_icons/extension_app.icon index feaa917..f3270e8e 100644 --- a/components/omnibox/browser/vector_icons/extension_app.icon +++ b/components/omnibox/browser/vector_icons/extension_app.icon
@@ -32,5 +32,4 @@ CUBIC_TO, 27.72f, 20.14f, 29, 18.5f, 29, 17, CUBIC_TO, 29, 15.5f, 27.72f, 14.43f, 26, 14, LINE_TO, 24, 14, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/http.icon b/components/omnibox/browser/vector_icons/http.icon index 3323410b..dea3f3dcb 100644 --- a/components/omnibox/browser/vector_icons/http.icon +++ b/components/omnibox/browser/vector_icons/http.icon
@@ -22,5 +22,4 @@ LINE_TO, 11, 6, LINE_TO, 11, 13, LINE_TO, 5, 13, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/keyword_search.icon b/components/omnibox/browser/vector_icons/keyword_search.icon index cfd650b..f4ef5b4 100644 --- a/components/omnibox/browser/vector_icons/keyword_search.icon +++ b/components/omnibox/browser/vector_icons/keyword_search.icon
@@ -16,5 +16,4 @@ R_CUBIC_TO, 0, -0.83f, 0.77f, -1.5f, 1.71f, -1.5f, R_CUBIC_TO, 0.47f, 0, 0.9f, 0.17f, 1.21f, 0.44f, R_LINE_TO, 8.57f, 7.5f, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/star.1x.icon b/components/omnibox/browser/vector_icons/star.1x.icon index fc814dc..a3dab5a 100644 --- a/components/omnibox/browser/vector_icons/star.1x.icon +++ b/components/omnibox/browser/vector_icons/star.1x.icon
@@ -14,5 +14,4 @@ LINE_TO, 9.69f, 6.19f, LINE_TO, 8, 2, LINE_TO, 6.31f, 6.19f, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/star.icon b/components/omnibox/browser/vector_icons/star.icon index f6d8377..f1d4ff5 100644 --- a/components/omnibox/browser/vector_icons/star.icon +++ b/components/omnibox/browser/vector_icons/star.icon
@@ -14,5 +14,4 @@ LINE_TO, 19.73f, 12.67f, LINE_TO, 16.5f, 5, LINE_TO, 13.27f, 12.67f, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/switch.icon b/components/omnibox/browser/vector_icons/switch.icon index c34e69aa..e4c82d1 100644 --- a/components/omnibox/browser/vector_icons/switch.icon +++ b/components/omnibox/browser/vector_icons/switch.icon
@@ -15,5 +15,4 @@ LINE_TO, 16, 13, LINE_TO, 16, 7, LINE_TO, 4, 7, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/tab.icon b/components/omnibox/browser/vector_icons/tab.icon index 641e06d..7b99b5c 100644 --- a/components/omnibox/browser/vector_icons/tab.icon +++ b/components/omnibox/browser/vector_icons/tab.icon
@@ -12,5 +12,4 @@ LINE_TO, 9, 16, LINE_TO, 7, 26, LINE_TO, 3, 26, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/touchable_bookmark.icon b/components/omnibox/browser/vector_icons/touchable_bookmark.icon index 3610301..8942f9a 100644 --- a/components/omnibox/browser/vector_icons/touchable_bookmark.icon +++ b/components/omnibox/browser/vector_icons/touchable_bookmark.icon
@@ -18,5 +18,4 @@ R_LINE_TO, 2.73f, 2.49f, R_LINE_TO, -0.82f, 3.7f, LINE_TO, 10, 13.04f, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/touchable_clear.icon b/components/omnibox/browser/vector_icons/touchable_clear.icon index c81df6e..302c26c 100644 --- a/components/omnibox/browser/vector_icons/touchable_clear.icon +++ b/components/omnibox/browser/vector_icons/touchable_clear.icon
@@ -26,5 +26,4 @@ R_LINE_TO, 2.53f, 2.52f, R_LINE_TO, 0.81f, -0.81f, LINE_TO, 14.14f, 10, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/touchable_page.icon b/components/omnibox/browser/vector_icons/touchable_page.icon index 8c809680..869f53fe 100644 --- a/components/omnibox/browser/vector_icons/touchable_page.icon +++ b/components/omnibox/browser/vector_icons/touchable_page.icon
@@ -17,5 +17,4 @@ LINE_TO, 9, 11, LINE_TO, 9, 7, LINE_TO, 13, 11, -CLOSE, -END +CLOSE
diff --git a/components/omnibox/browser/vector_icons/touchable_search.icon b/components/omnibox/browser/vector_icons/touchable_search.icon index e19765a..ae427b6 100644 --- a/components/omnibox/browser/vector_icons/touchable_search.icon +++ b/components/omnibox/browser/vector_icons/touchable_search.icon
@@ -21,5 +21,4 @@ ARC_TO, 2.67f, 2.67f, 0, 0, 1, 9.86f, 7.33f, ARC_TO, 2.67f, 2.67f, 0, 0, 1, 12.53f, 10, R_ARC_TO, 2.67f, 2.67f, 0, 0, 1, -2.67f, 2.67f, -CLOSE, -END +CLOSE
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index d253cc5..687ee54 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -16,6 +16,7 @@ #include "components/payments/content/payment_request_converter.h" #include "components/payments/content/payment_request_web_contents_manager.h" #include "components/payments/core/can_make_payment_query.h" +#include "components/payments/core/features.h" #include "components/payments/core/payment_details.h" #include "components/payments/core/payment_details_validation.h" #include "components/payments/core/payment_prefs.h" @@ -352,6 +353,19 @@ return delegate_->IsIncognito(); } +bool PaymentRequest::SatisfiesSkipUIConstraints() const { + return base::FeatureList::IsEnabled(features::kWebPaymentsSingleAppUiSkip) && + base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps) && + state()->is_get_all_instruments_finished() && + state()->available_instruments().size() == 1 && + spec()->stringified_method_data().size() == 1 && + !spec()->request_shipping() && !spec()->request_payer_name() && + !spec()->request_payer_phone() && + !spec()->request_payer_email() + // Only allowing URL base payment apps to skip the payment sheet. + && spec()->url_payment_method_identifiers().size() == 1; +} + void PaymentRequest::RecordFirstAbortReason( JourneyLogger::AbortReason abort_reason) { if (!has_recorded_completion_) { @@ -382,7 +396,7 @@ if (delegate_->IsIncognito()) { can_make_payment = spec()->HasBasicCardMethodName() || - base::FeatureList::IsEnabled(features::kServiceWorkerPaymentApps); + base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps); } mojom::CanMakePaymentQueryResult positive =
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h index 30a7c556..400ae351 100644 --- a/components/payments/content/payment_request.h +++ b/components/payments/content/payment_request.h
@@ -103,11 +103,19 @@ bool IsIncognito() const; + // Returns true if this payment request supports skipping the Payment Sheet. + // Typically, this means only one payment method is supported, it's a URL + // based method, and no other info is requested from the user. + bool SatisfiesSkipUIConstraints() const; + content::WebContents* web_contents() { return web_contents_; } PaymentRequestSpec* spec() { return spec_.get(); } PaymentRequestState* state() { return state_.get(); } + PaymentRequestSpec* spec() const { return spec_.get(); } + PaymentRequestState* state() const { return state_.get(); } + private: // Only records the abort reason if it's the first completion for this Payment // Request. This is necessary since the aborts cascade into one another with
diff --git a/components/payments/content/payment_request_dialog.h b/components/payments/content/payment_request_dialog.h index 3d23fcb..a08c1e64 100644 --- a/components/payments/content/payment_request_dialog.h +++ b/components/payments/content/payment_request_dialog.h
@@ -22,6 +22,10 @@ virtual void ShowDialog() = 0; + virtual void ShowDialogAtPaymentHandlerSheet( + const GURL& url, + PaymentHandlerOpenWindowCallback callback) = 0; + virtual void CloseDialog() = 0; virtual void ShowErrorMessage() = 0;
diff --git a/components/payments/content/payment_request_display_manager.cc b/components/payments/content/payment_request_display_manager.cc index 22283b2..5796321 100644 --- a/components/payments/content/payment_request_display_manager.cc +++ b/components/payments/content/payment_request_display_manager.cc
@@ -27,7 +27,6 @@ PaymentRequest* request) { DCHECK(request); DCHECK(delegate_); - delegate_->ShowDialog(request); }
diff --git a/components/payments/core/features.cc b/components/payments/core/features.cc index f60eae5..73e143e 100644 --- a/components/payments/core/features.cc +++ b/components/payments/core/features.cc
@@ -21,5 +21,13 @@ const base::Feature kWebPaymentsModifiers{"WebPaymentsModifiers", base::FEATURE_ENABLED_BY_DEFAULT}; +#if defined(OS_ANDROID) +const base::Feature kWebPaymentsSingleAppUiSkip{ + "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; +#else +const base::Feature kWebPaymentsSingleAppUiSkip{ + "WebPaymentsSingleAppUiSkip", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + } // namespace features } // namespace payments
diff --git a/components/payments/core/features.h b/components/payments/core/features.h index a7e4a48cf..fe66a9f 100644 --- a/components/payments/core/features.h +++ b/components/payments/core/features.h
@@ -27,6 +27,10 @@ // Used to control the support for Payment Details modifiers. extern const base::Feature kWebPaymentsModifiers; +// Used to control whether the Payment Sheet can be skipped for Payment Requests +// with a single URL based payment app and no other info requested. +extern const base::Feature kWebPaymentsSingleAppUiSkip; + } // namespace features } // namespace payments
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index cc65cd0..fc7f1b5 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -40,7 +40,7 @@ // Request from device to server to register a device, user or browser. message DeviceRegisterRequest { - reserved 5; + reserved 5, 10; // Reregister device without erasing server state. It can be used // to refresh dmtoken etc. Client MUST set this value to true if it @@ -131,14 +131,16 @@ // Enumerates different expected lifetimes of registration. enum Lifetime { - // Default case, no expiration. - LIFETIME_INDEFINITE = 0; + // Default case. + LIFETIME_UNDEFINED = 0; + // No expiration, most of the registrations have this lifetime. + LIFETIME_INDEFINITE = 1; // Lifetime for ephemeral user policy registration. - LIFETIME_EPHEMERAL_USER = 1; + LIFETIME_EPHEMERAL_USER = 2; } // Indicates the expected lifetime of registration. - optional Lifetime lifetime = 10; + optional Lifetime lifetime = 11 [default = LIFETIME_INDEFINITE]; } // Response from server to device register request.
diff --git a/components/safe_browsing/db/BUILD.gn b/components/safe_browsing/db/BUILD.gn index 487b155c..c34eb11 100644 --- a/components/safe_browsing/db/BUILD.gn +++ b/components/safe_browsing/db/BUILD.gn
@@ -217,6 +217,17 @@ ] } +source_set("prefix_iterator") { + sources = [ + "prefix_iterator.cc", + "prefix_iterator.h", + ] + deps = [ + ":v4_protocol_manager_util", + "//base", + ] +} + if (is_android) { import("//build/config/android/rules.gni") java_cpp_enum("sb_threat_values") { @@ -247,6 +258,7 @@ ":v4_store_proto", ] deps = [ + ":prefix_iterator", ":v4_protocol_manager_util", ":v4_rice", "//base",
diff --git a/components/safe_browsing/db/prefix_iterator.cc b/components/safe_browsing/db/prefix_iterator.cc new file mode 100644 index 0000000..e7471ff --- /dev/null +++ b/components/safe_browsing/db/prefix_iterator.cc
@@ -0,0 +1,17 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_browsing/db/prefix_iterator.h" + +namespace safe_browsing { + +PrefixIterator::PrefixIterator(base::StringPiece prefixes, + size_t index, + size_t size) + : prefixes_(prefixes), index_(index), size_(size) {} + +PrefixIterator::PrefixIterator(const PrefixIterator& rhs) + : prefixes_(rhs.prefixes_), index_(rhs.index_), size_(rhs.size_) {} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/db/prefix_iterator.h b/components/safe_browsing/db/prefix_iterator.h new file mode 100644 index 0000000..1f95b1e --- /dev/null +++ b/components/safe_browsing/db/prefix_iterator.h
@@ -0,0 +1,99 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SAFE_BROWSING_DB_PREFIX_ITERATOR_H_ +#define COMPONENTS_SAFE_BROWSING_DB_PREFIX_ITERATOR_H_ + +#include <cstddef> +#include <iterator> + +#include "base/strings/string_piece.h" +#include "components/safe_browsing/db/v4_protocol_manager_util.h" + +namespace safe_browsing { + +// The prefix iterator is used to binary search within a |HashPrefixes|. It is +// essentially a random access iterator that steps |PrefixSize| steps within the +// underlying buffer. +class PrefixIterator + : public std::iterator<std::random_access_iterator_tag, base::StringPiece> { + public: + using difference_type = + typename std::iterator<std::random_access_iterator_tag, + base::StringPiece>::difference_type; + + PrefixIterator(base::StringPiece prefixes, size_t index, size_t size); + PrefixIterator(const PrefixIterator& rhs); + + base::StringPiece operator*() const { return GetPiece(index_); } + base::StringPiece operator[](const int& rhs) const { + return GetPiece(index_ + rhs); + } + + PrefixIterator& operator=(const PrefixIterator& rhs) { + index_ = rhs.index_; + return *this; + } + PrefixIterator& operator+=(const int& rhs) { + index_ += rhs; + return *this; + } + PrefixIterator& operator-=(const int& rhs) { + index_ -= rhs; + return *this; + } + PrefixIterator& operator++() { + index_++; + return *this; + } + PrefixIterator& operator--() { + index_--; + return *this; + } + + PrefixIterator operator+(const PrefixIterator& rhs) const { + return PrefixIterator(prefixes_, index_ + rhs.index_, size_); + } + difference_type operator-(const PrefixIterator& rhs) const { + return index_ - rhs.index_; + } + PrefixIterator operator+(const int& rhs) const { + return PrefixIterator(prefixes_, index_ + rhs, size_); + } + PrefixIterator operator-(const int& rhs) const { + return PrefixIterator(prefixes_, index_ - rhs, size_); + } + + bool operator==(const PrefixIterator& rhs) const { + return index_ == rhs.index_; + } + bool operator!=(const PrefixIterator& rhs) const { + return index_ != rhs.index_; + } + bool operator>(const PrefixIterator& rhs) const { + return index_ > rhs.index_; + } + bool operator<(const PrefixIterator& rhs) const { + return index_ < rhs.index_; + } + bool operator>=(const PrefixIterator& rhs) const { + return index_ >= rhs.index_; + } + bool operator<=(const PrefixIterator& rhs) const { + return index_ <= rhs.index_; + } + + private: + base::StringPiece GetPiece(size_t index) const { + return prefixes_.substr(index * size_, size_); + } + + base::StringPiece prefixes_; + size_t index_; + size_t size_; +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_DB_PREFIX_ITERATOR_H_
diff --git a/components/safe_browsing/db/v4_store.cc b/components/safe_browsing/db/v4_store.cc index 3ebcfcd..5911ca1 100644 --- a/components/safe_browsing/db/v4_store.cc +++ b/components/safe_browsing/db/v4_store.cc
@@ -4,6 +4,7 @@ #include "components/safe_browsing/db/v4_store.h" +#include <algorithm> #include <utility> #include "base/base64.h" @@ -13,6 +14,7 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" +#include "components/safe_browsing/db/prefix_iterator.h" #include "components/safe_browsing/db/v4_rice.h" #include "components/safe_browsing/db/v4_store.pb.h" #include "components/safe_browsing/proto/webui.pb.h" @@ -782,37 +784,20 @@ checks_attempted_++; for (const auto& pair : hash_prefix_map_) { const PrefixSize& prefix_size = pair.first; - const HashPrefixes& hash_prefixes = pair.second; - HashPrefix hash_prefix = full_hash.substr(0, prefix_size); - if (HashPrefixMatches(hash_prefix, hash_prefixes.begin(), - hash_prefixes.end())) { - return hash_prefix; - } + base::StringPiece hash_prefix = + base::StringPiece(full_hash).substr(0, prefix_size); + if (HashPrefixMatches(hash_prefix, pair.second, prefix_size)) + return hash_prefix.as_string(); } return HashPrefix(); } -// static -bool V4Store::HashPrefixMatches(const HashPrefix& hash_prefix, - const HashPrefixes::const_iterator& begin, - const HashPrefixes::const_iterator& end) { - if (begin == end) { - return false; - } - size_t distance = std::distance(begin, end); - const PrefixSize prefix_size = hash_prefix.length(); - DCHECK_EQ(0u, distance % prefix_size); - size_t mid_prefix_index = ((distance / prefix_size) / 2) * prefix_size; - HashPrefixes::const_iterator mid = begin + mid_prefix_index; - HashPrefix mid_prefix = HashPrefix(mid, mid + prefix_size); - int result = hash_prefix.compare(mid_prefix); - if (result == 0) { - return true; - } else if (result < 0) { - return HashPrefixMatches(hash_prefix, begin, mid); - } else { - return HashPrefixMatches(hash_prefix, mid + prefix_size, end); - } +bool V4Store::HashPrefixMatches(base::StringPiece prefix, + const HashPrefixes& prefixes, + const PrefixSize& size) { + return std::binary_search( + PrefixIterator(prefixes, 0, size), + PrefixIterator(prefixes, prefixes.size() / size, size), prefix); } bool V4Store::VerifyChecksum() {
diff --git a/components/safe_browsing/db/v4_store.h b/components/safe_browsing/db/v4_store.h index 4477e33..6db059f 100644 --- a/components/safe_browsing/db/v4_store.h +++ b/components/safe_browsing/db/v4_store.h
@@ -319,10 +319,11 @@ const IteratorMap& iterator_map, HashPrefix* smallest_hash_prefix); - // Returns true if |hash_prefix| exists between |begin| and |end| iterators. - static bool HashPrefixMatches(const HashPrefix& hash_prefix, - const HashPrefixes::const_iterator& begin, - const HashPrefixes::const_iterator& end); + // Returns true if |hash_prefix| with PrefixSize |size| exists in |prefixes|. + // This small method is exposed in the header so it can be tested separately. + static bool HashPrefixMatches(base::StringPiece prefix, + const HashPrefixes& prefixes, + const PrefixSize& size); // For each key in |hash_prefix_map|, sets the iterator at that key // |iterator_map| to hash_prefix_map[key].begin().
diff --git a/components/safe_browsing/db/v4_store_perftest.cc b/components/safe_browsing/db/v4_store_perftest.cc new file mode 100644 index 0000000..e187dc4 --- /dev/null +++ b/components/safe_browsing/db/v4_store_perftest.cc
@@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/strings/stringprintf.h" +#include "base/test/test_simple_task_runner.h" +#include "base/timer/elapsed_timer.h" +#include "components/safe_browsing/db/v4_protocol_manager_util.h" +#include "components/safe_browsing/db/v4_test_util.h" +#include "crypto/sha2.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/perf/perf_test.h" + +namespace safe_browsing { + +class V4StorePerftest : public testing::Test {}; + +TEST_F(V4StorePerftest, StressTest) { + const int kNumPrefixes = 2000000; + std::vector<std::string> prefixes; + std::vector<std::string> full_hashes; + for (size_t i = 0; i < kNumPrefixes; i++) { + std::string sha256 = crypto::SHA256HashString(base::StringPrintf("%zu", i)); + DCHECK_EQ(crypto::kSHA256Length, kMaxHashPrefixLength); + full_hashes.push_back(sha256); + prefixes.push_back(sha256.substr(0, kMinHashPrefixLength)); + } + + auto store = std::make_unique<TestV4Store>( + base::MakeRefCounted<base::TestSimpleTaskRunner>(), base::FilePath()); + store->SetPrefixes(std::move(prefixes), kMinHashPrefixLength); + + size_t matches = 0; + base::ElapsedTimer timer; + for (const auto& full_hash : full_hashes) { + matches += !store->GetMatchingHashPrefix(full_hash).empty(); + } + perf_test::PrintResult("GetMachingHashPrefix", "", "", + timer.Elapsed().InMillisecondsF(), "ms", true); + + EXPECT_EQ(matches, full_hashes.size()); +} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/db/v4_store_unittest.cc b/components/safe_browsing/db/v4_store_unittest.cc index c37efae..5f5e525 100644 --- a/components/safe_browsing/db/v4_store_unittest.cc +++ b/components/safe_browsing/db/v4_store_unittest.cc
@@ -593,43 +593,37 @@ TEST_F(V4StoreTest, TestHashPrefixExistsAtTheBeginning) { HashPrefixes hash_prefixes = "abcdebbbbbccccc"; HashPrefix hash_prefix = "abcde"; - EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, std::begin(hash_prefixes), - std::end(hash_prefixes))); + EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestHashPrefixExistsInTheMiddle) { HashPrefixes hash_prefixes = "abcdebbbbbccccc"; HashPrefix hash_prefix = "bbbbb"; - EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, std::begin(hash_prefixes), - std::end(hash_prefixes))); + EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestHashPrefixExistsAtTheEnd) { HashPrefixes hash_prefixes = "abcdebbbbbccccc"; HashPrefix hash_prefix = "ccccc"; - EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, std::begin(hash_prefixes), - std::end(hash_prefixes))); + EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestHashPrefixExistsAtTheBeginningOfEven) { HashPrefixes hash_prefixes = "abcdebbbbb"; HashPrefix hash_prefix = "abcde"; - EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, std::begin(hash_prefixes), - std::end(hash_prefixes))); + EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestHashPrefixExistsAtTheEndOfEven) { HashPrefixes hash_prefixes = "abcdebbbbb"; HashPrefix hash_prefix = "bbbbb"; - EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, std::begin(hash_prefixes), - std::end(hash_prefixes))); + EXPECT_TRUE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestHashPrefixDoesNotExistInConcatenatedList) { HashPrefixes hash_prefixes = "abcdebbbbb"; HashPrefix hash_prefix = "bbbbc"; - EXPECT_FALSE(V4Store::HashPrefixMatches( - hash_prefix, std::begin(hash_prefixes), std::end(hash_prefixes))); + EXPECT_FALSE(V4Store::HashPrefixMatches(hash_prefix, hash_prefixes, 5)); } TEST_F(V4StoreTest, TestFullHashExistsInMapWithSingleSize) {
diff --git a/components/safe_browsing/db/v4_test_util.cc b/components/safe_browsing/db/v4_test_util.cc index 59eb8dc..cc275f8 100644 --- a/components/safe_browsing/db/v4_test_util.cc +++ b/components/safe_browsing/db/v4_test_util.cc
@@ -4,9 +4,11 @@ #include "components/safe_browsing/db/v4_test_util.h" +#include <algorithm> #include <string> #include <utility> +#include "base/strings/strcat.h" #include "components/safe_browsing/db/util.h" #include "crypto/sha2.h" @@ -47,7 +49,16 @@ } void TestV4Store::MarkPrefixAsBad(HashPrefix prefix) { - hash_prefix_map_[prefix.size()] += prefix; + auto& vec = mock_prefixes_[prefix.size()]; + vec.insert(std::upper_bound(vec.begin(), vec.end(), prefix), prefix); + hash_prefix_map_[prefix.size()] = base::StrCat(vec); +} + +void TestV4Store::SetPrefixes(std::vector<HashPrefix> prefixes, + PrefixSize size) { + std::sort(prefixes.begin(), prefixes.end()); + mock_prefixes_[size] = prefixes; + hash_prefix_map_[size] = base::StrCat(prefixes); } TestV4Database::TestV4Database(
diff --git a/components/safe_browsing/db/v4_test_util.h b/components/safe_browsing/db/v4_test_util.h index 693f988..ddf1327 100644 --- a/components/safe_browsing/db/v4_test_util.h +++ b/components/safe_browsing/db/v4_test_util.h
@@ -7,8 +7,10 @@ // Contains classes and methods useful for tests. +#include <map> #include <memory> #include <ostream> +#include <vector> #include "components/safe_browsing/db/v4_database.h" #include "components/safe_browsing/db/v4_get_hash_protocol_manager.h" @@ -31,6 +33,14 @@ bool HasValidData() const override; void MarkPrefixAsBad(HashPrefix prefix); + + // |prefixes| does not need to be sorted. + void SetPrefixes(std::vector<HashPrefix> prefixes, PrefixSize size); + + private: + // Holds mock prefixes from calls to MarkPrefixAsBad / SetPrefixes. Stored as + // a vector for simplicity. + std::map<PrefixSize, std::vector<HashPrefix>> mock_prefixes_; }; class TestV4StoreFactory : public V4StoreFactory {
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java index b4ddb9a..4604ac1 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -35,7 +35,6 @@ import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; -import org.chromium.base.annotations.MainDex; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.RecordHistogram; @@ -46,7 +45,6 @@ * Default implementation of {@link AccountManagerDelegate} which delegates all calls to the * Android account manager. */ -@MainDex public class SystemAccountManagerDelegate implements AccountManagerDelegate { private final AccountManager mAccountManager; private final ObserverList<AccountsChangeObserver> mObservers = new ObserverList<>();
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc index f848f68..23921e0 100644 --- a/components/sync/driver/about_sync_util.cc +++ b/components/sync/driver/about_sync_util.cc
@@ -6,12 +6,11 @@ #include <string> #include <utility> +#include <vector> -#include "base/location.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string16.h" #include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/strings/grit/components_strings.h" @@ -24,9 +23,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" -using base::DictionaryValue; -using base::ListValue; - namespace syncer { namespace sync_ui_util { @@ -77,156 +73,112 @@ namespace { -// Creates a 'section' for display on about:sync, consisting of a title and a -// list of fields. Returns a pointer to the new section. Note that -// |parent_list|, not the caller, owns the newly added section. -base::ListValue* AddSection(base::ListValue* parent_list, - const std::string& title) { - auto section = std::make_unique<base::DictionaryValue>(); - section->SetString("title", title); - base::ListValue* section_contents = - section->SetList("data", std::make_unique<base::ListValue>()); - section->SetBoolean("is_sensitive", false); - // If the following |Append| results in a reallocation, pointers to the - // members of |parent_list| will be invalidated. This would result in - // use-after-free in |*SyncStat::SetValue|. This is why the following DCHECK - // is necessary to ensure no reallocation takes place. - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - DCHECK_LT(parent_list->GetSize(), parent_list->GetList().capacity()); - parent_list->Append(std::move(section)); - return section_contents; -} +const char kUninitialized[] = "Uninitialized"; -// Same as AddSection, but for data that should be elided when dumped into text -// form and posted in a public forum (e.g. unique identifiers). -base::ListValue* AddSensitiveSection(base::ListValue* parent_list, - const std::string& title) { - auto section = std::make_unique<base::DictionaryValue>(); - section->SetString("title", title); - base::ListValue* section_contents = - section->SetList("data", std::make_unique<base::ListValue>()); - section->SetBoolean("is_sensitive", true); - // If the following |Append| results in a reallocation, pointers to - // |parent_list| and its members will be invalidated. This would result in - // use-after-free in |*SyncStat::SetValue|. This is why the following DCHECK - // is necessary to ensure no reallocation takes place. - DCHECK_LT(parent_list->GetSize(), parent_list->GetList().capacity()); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - parent_list->Append(std::move(section)); - return section_contents; -} - -// The following helper classes help manage the about:sync fields which will be -// populated in method in ConstructAboutInformation. -// -// Each instance of one of thse classes indicates a field in about:sync. Each -// field will be serialized to a DictionaryValue with entries for 'stat_name', -// 'stat_value' and 'is_valid'. - -class StringSyncStat { +// This class represents one field in about:sync. It gets serialized into a +// dictionary with entries for 'stat_name', 'stat_value' and 'is_valid'. +class StatBase { public: - StringSyncStat(base::ListValue* section, const std::string& key); - void SetValue(const std::string& value); - void SetValue(const base::string16& value); + base::Value ToValue() const { + base::Value result(base::Value::Type::DICTIONARY); + result.SetKey("stat_name", base::Value(key_)); + result.SetKey("stat_value", value_.Clone()); + result.SetKey("is_valid", base::Value(is_valid_)); + return result; + } + + protected: + StatBase(const std::string& key, base::Value default_value) + : key_(key), value_(std::move(default_value)) {} + + void SetFromValue(base::Value value) { + value_ = std::move(value); + is_valid_ = true; + } private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; + std::string key_; + base::Value value_; + bool is_valid_ = false; }; -StringSyncStat::StringSyncStat(base::ListValue* section, - const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetString("stat_value", "Uninitialized"); - stat_->SetBoolean("is_valid", false); - // |stat_| will be invalidated by |Append|, so it needs to be reset. - // Furthermore, if |Append| results in a reallocation, |stat_| members of - // other SyncStats will be invalidated. This is why the following dcheck is - // necessary, so that it is guaranteed that a reallocation will not happen. - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - DCHECK_LT(section->GetSize(), section->GetList().capacity()); - section->Append(base::WrapUnique(stat_)); - section->GetDictionary(section->GetSize() - 1, &stat_); -} - -void StringSyncStat::SetValue(const std::string& value) { - stat_->SetString("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -void StringSyncStat::SetValue(const base::string16& value) { - stat_->SetString("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -class BoolSyncStat { +template <typename T> +class Stat : public StatBase { public: - BoolSyncStat(base::ListValue* section, const std::string& key); - void SetValue(bool value); + Stat(const std::string& key, const T& default_value) + : StatBase(key, base::Value(default_value)) {} + + void Set(const T& value) { SetFromValue(base::Value(value)); } +}; + +// A section for display on about:sync, consisting of a title and a list of +// fields. +class Section { + public: + explicit Section(const std::string& title) : title_(title) {} + + void MarkSensitive() { is_sensitive_ = true; } + + Stat<bool>* AddBoolStat(const std::string& key) { + return AddStat(key, false); + } + Stat<int>* AddIntStat(const std::string& key) { return AddStat(key, 0); } + Stat<std::string>* AddStringStat(const std::string& key) { + return AddStat(key, std::string(kUninitialized)); + } + + base::Value ToValue() const { + base::Value result(base::Value::Type::DICTIONARY); + result.SetKey("title", base::Value(title_)); + base::Value stats(base::Value::Type::LIST); + for (const std::unique_ptr<StatBase>& stat : stats_) + stats.GetList().push_back(stat->ToValue()); + result.SetKey("data", std::move(stats)); + result.SetKey("is_sensitive", base::Value(is_sensitive_)); + return result; + } private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; + template <typename T> + Stat<T>* AddStat(const std::string& key, const T& default_value) { + auto stat = std::make_unique<Stat<T>>(key, default_value); + Stat<T>* result = stat.get(); + stats_.push_back(std::move(stat)); + return result; + } + + std::string title_; + std::vector<std::unique_ptr<StatBase>> stats_; + bool is_sensitive_ = false; }; -BoolSyncStat::BoolSyncStat(base::ListValue* section, const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetBoolean("stat_value", false); - stat_->SetBoolean("is_valid", false); - // |stat_| will be invalidated by |Append|, so it needs to be reset. - // Furthermore, if |Append| results in a reallocation, |stat_| members of - // other SyncStats will be invalidated. This is why the following dcheck is - // necessary, so that it is guaranteed that a reallocation will not happen. - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - DCHECK_LT(section->GetSize(), section->GetList().capacity()); - section->Append(base::WrapUnique(stat_)); - section->GetDictionary(section->GetSize() - 1, &stat_); -} - -void BoolSyncStat::SetValue(bool value) { - stat_->SetBoolean("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -class IntSyncStat { +class SectionList { public: - IntSyncStat(base::ListValue* section, const std::string& key); - void SetValue(int value); + SectionList() = default; + + Section* AddSection(const std::string& title) { + sections_.push_back(std::make_unique<Section>(title)); + return sections_.back().get(); + } + + base::Value ToValue() const { + base::Value result(base::Value::Type::LIST); + for (const std::unique_ptr<Section>& section : sections_) + result.GetList().push_back(section->ToValue()); + return result; + } private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; + std::vector<std::unique_ptr<Section>> sections_; }; -IntSyncStat::IntSyncStat(base::ListValue* section, const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetInteger("stat_value", 0); - stat_->SetBoolean("is_valid", false); - // |stat_| will be invalidated by |Append|, so it needs to be reset. - // Furthermore, if |Append| results in a reallocation, |stat_| members of - // other SyncStats will be invalidated. This is why the following dcheck is - // necessary, so that it is guaranteed that a reallocation will not happen. - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - DCHECK_LT(section->GetSize(), section->GetList().capacity()); - section->Append(base::WrapUnique(stat_)); - section->GetDictionary(section->GetSize() - 1, &stat_); -} - -void IntSyncStat::SetValue(int value) { - stat_->SetInteger("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - // Returns a string describing the chrome version environment. Version format: // <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel"> // If version information is unavailable, returns "invalid." -// TODO(zea): this approximately matches MakeUserAgentForSyncApi in -// sync_backend_host.cc. Unify the two if possible. +// TODO(zea): this approximately matches syncer::MakeUserAgentForSync in +// sync_util.h. Unify the two if possible. std::string GetVersionString(version_info::Channel channel) { - // Build a version string that matches MakeUserAgentForSyncApi with the + // Build a version string that matches syncer::MakeUserAgentForSync with the // addition of channel info and proper OS names. // chrome::GetChannelString() returns empty string for stable channel or // unofficial builds, the channel string otherwise. We want to have "-devel" @@ -253,45 +205,39 @@ return time_str; } -base::string16 GetLastSyncedTimeString(base::Time last_synced_time) { +std::string GetLastSyncedTimeString(base::Time last_synced_time) { if (last_synced_time.is_null()) - return l10n_util::GetStringUTF16(IDS_SYNC_TIME_NEVER); + return l10n_util::GetStringUTF8(IDS_SYNC_TIME_NEVER); base::TimeDelta time_since_last_sync = base::Time::Now() - last_synced_time; if (time_since_last_sync < base::TimeDelta::FromMinutes(1)) - return l10n_util::GetStringUTF16(IDS_SYNC_TIME_JUST_NOW); + return l10n_util::GetStringUTF8(IDS_SYNC_TIME_JUST_NOW); - return ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, - ui::TimeFormat::LENGTH_SHORT, - time_since_last_sync); + return base::UTF16ToUTF8(ui::TimeFormat::Simple( + ui::TimeFormat::FORMAT_ELAPSED, ui::TimeFormat::LENGTH_SHORT, + time_since_last_sync)); } std::string GetConnectionStatus(const SyncService::SyncTokenStatus& status) { - std::string message; switch (status.connection_status) { case CONNECTION_NOT_ATTEMPTED: - base::StringAppendF(&message, "not attempted"); - break; + return "not attempted"; case CONNECTION_OK: - base::StringAppendF( - &message, "OK since %s", + return base::StringPrintf( + "OK since %s", GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; case CONNECTION_AUTH_ERROR: - base::StringAppendF( - &message, "auth error since %s", + return base::StringPrintf( + "auth error since %s", GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; case CONNECTION_SERVER_ERROR: - base::StringAppendF( - &message, "server error since %s", + return base::StringPrintf( + "server error since %s", GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; - default: - NOTREACHED(); } - return message; + NOTREACHED(); + return std::string(); } } // namespace @@ -316,261 +262,258 @@ version_info::Channel channel) { auto about_info = std::make_unique<base::DictionaryValue>(); - // 'details': A list of sections. - auto stats_list = std::make_unique<base::ListValue>(); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - stats_list->Reserve(12); + SectionList section_list; - // The following lines define the sections and their fields. For each field, - // a class is instantiated, which allows us to reference the fields in - // 'setter' code later on in this function. - base::ListValue* section_summary = AddSection(stats_list.get(), "Summary"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_summary->Reserve(1); - StringSyncStat summary_string(section_summary, "Summary"); + Section* section_summary = section_list.AddSection("Summary"); + Stat<std::string>* summary_string = section_summary->AddStringStat("Summary"); - base::ListValue* section_version = - AddSection(stats_list.get(), "Version Info"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_version->Reserve(2); - StringSyncStat client_version(section_version, "Client Version"); - StringSyncStat server_url(section_version, "Server URL"); + Section* section_version = section_list.AddSection("Version Info"); + Stat<std::string>* client_version = + section_version->AddStringStat("Client Version"); + Stat<std::string>* server_url = section_version->AddStringStat("Server URL"); - base::ListValue* section_identity = - AddSensitiveSection(stats_list.get(), kIdentityTitle); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_identity->Reserve(3); - StringSyncStat sync_id(section_identity, "Sync Client ID"); - StringSyncStat invalidator_id(section_identity, "Invalidator Client ID"); - StringSyncStat username(section_identity, "Username"); + Section* section_identity = section_list.AddSection(kIdentityTitle); + section_identity->MarkSensitive(); + Stat<std::string>* sync_id = + section_identity->AddStringStat("Sync Client ID"); + Stat<std::string>* invalidator_id = + section_identity->AddStringStat("Invalidator Client ID"); + Stat<std::string>* username = section_identity->AddStringStat("Username"); - base::ListValue* section_credentials = - AddSection(stats_list.get(), "Credentials"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_credentials->Reserve(4); - StringSyncStat request_token_time(section_credentials, "Requested Token"); - StringSyncStat receive_token_time(section_credentials, "Received Token"); - StringSyncStat token_request_status(section_credentials, - "Token Request Status"); - StringSyncStat next_token_request(section_credentials, "Next Token Request"); + Section* section_credentials = section_list.AddSection("Credentials"); + Stat<std::string>* request_token_time = + section_credentials->AddStringStat("Requested Token"); + Stat<std::string>* receive_token_time = + section_credentials->AddStringStat("Received Token"); + Stat<std::string>* token_request_status = + section_credentials->AddStringStat("Token Request Status"); + Stat<std::string>* next_token_request = + section_credentials->AddStringStat("Next Token Request"); - base::ListValue* section_local = AddSection(stats_list.get(), "Local State"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_local->Reserve(7); - StringSyncStat server_connection(section_local, "Server Connection"); - StringSyncStat last_synced(section_local, "Last Synced"); - BoolSyncStat is_setup_complete(section_local, - "Sync First-Time Setup Complete"); - StringSyncStat backend_initialization(section_local, - "Sync Backend Initialization"); - BoolSyncStat is_syncing(section_local, "Syncing"); - BoolSyncStat is_local_sync_enabled(section_local, - "Local Sync Backend Enabled"); - StringSyncStat local_backend_path(section_local, "Local Backend Path"); + Section* section_local = section_list.AddSection("Local State"); + Stat<std::string>* server_connection = + section_local->AddStringStat("Server Connection"); + Stat<std::string>* last_synced = section_local->AddStringStat("Last Synced"); + Stat<bool>* is_setup_complete = + section_local->AddBoolStat("Sync First-Time Setup Complete"); + Stat<std::string>* backend_initialization = + section_local->AddStringStat("Sync Backend Initialization"); + Stat<bool>* is_syncing = section_local->AddBoolStat("Syncing"); + Stat<bool>* is_local_sync_enabled = + section_local->AddBoolStat("Local Sync Backend Enabled"); + Stat<std::string>* local_backend_path = + section_local->AddStringStat("Local Backend Path"); - base::ListValue* section_network = AddSection(stats_list.get(), "Network"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_network->Reserve(3); - BoolSyncStat is_any_throttled_or_backoff(section_network, - "Throttled or Backoff"); - StringSyncStat retry_time(section_network, "Retry Time"); - BoolSyncStat are_notifications_enabled(section_network, - "Notifications Enabled"); + Section* section_network = section_list.AddSection("Network"); + Stat<bool>* is_any_throttled_or_backoff = + section_network->AddBoolStat("Throttled or Backoff"); + Stat<std::string>* retry_time = section_network->AddStringStat("Retry Time"); + Stat<bool>* are_notifications_enabled = + section_network->AddBoolStat("Notifications Enabled"); - base::ListValue* section_encryption = - AddSection(stats_list.get(), "Encryption"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_encryption->Reserve(9); - BoolSyncStat is_using_explicit_passphrase(section_encryption, - "Explicit Passphrase"); - BoolSyncStat is_passphrase_required(section_encryption, - "Passphrase Required"); - BoolSyncStat is_cryptographer_ready(section_encryption, - "Cryptographer Ready"); - BoolSyncStat has_pending_keys(section_encryption, - "Cryptographer Has Pending Keys"); - StringSyncStat encrypted_types(section_encryption, "Encrypted Types"); - BoolSyncStat has_keystore_key(section_encryption, "Has Keystore Key"); - StringSyncStat keystore_migration_time(section_encryption, - "Keystore Migration Time"); - StringSyncStat passphrase_type(section_encryption, "Passphrase Type"); - StringSyncStat passphrase_time(section_encryption, "Passphrase Time"); + Section* section_encryption = section_list.AddSection("Encryption"); + Stat<bool>* is_using_explicit_passphrase = + section_encryption->AddBoolStat("Explicit Passphrase"); + Stat<bool>* is_passphrase_required = + section_encryption->AddBoolStat("Passphrase Required"); + Stat<bool>* is_cryptographer_ready = + section_encryption->AddBoolStat("Cryptographer Ready"); + Stat<bool>* has_pending_keys = + section_encryption->AddBoolStat("Cryptographer Has Pending Keys"); + Stat<std::string>* encrypted_types = + section_encryption->AddStringStat("Encrypted Types"); + Stat<bool>* has_keystore_key = + section_encryption->AddBoolStat("Has Keystore Key"); + Stat<std::string>* keystore_migration_time = + section_encryption->AddStringStat("Keystore Migration Time"); + Stat<std::string>* passphrase_type = + section_encryption->AddStringStat("Passphrase Type"); + Stat<std::string>* passphrase_time = + section_encryption->AddStringStat("Passphrase Time"); - base::ListValue* section_last_session = - AddSection(stats_list.get(), "Status from Last Completed Session"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_last_session->Reserve(4); - StringSyncStat session_source(section_last_session, "Sync Source"); - StringSyncStat get_key_result(section_last_session, "GetKey Step Result"); - StringSyncStat download_result(section_last_session, "Download Step Result"); - StringSyncStat commit_result(section_last_session, "Commit Step Result"); + Section* section_last_session = + section_list.AddSection("Status from Last Completed Session"); + Stat<std::string>* session_source = + section_last_session->AddStringStat("Sync Source"); + Stat<std::string>* get_key_result = + section_last_session->AddStringStat("GetKey Step Result"); + Stat<std::string>* download_result = + section_last_session->AddStringStat("Download Step Result"); + Stat<std::string>* commit_result = + section_last_session->AddStringStat("Commit Step Result"); - base::ListValue* section_counters = - AddSection(stats_list.get(), "Running Totals"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_counters->Reserve(7); - IntSyncStat notifications_received(section_counters, - "Notifications Received"); - IntSyncStat updates_received(section_counters, "Updates Downloaded"); - IntSyncStat tombstone_updates(section_counters, "Tombstone Updates"); - IntSyncStat reflected_updates(section_counters, "Reflected Updates"); - IntSyncStat successful_commits(section_counters, "Successful Commits"); - IntSyncStat conflicts_resolved_local_wins(section_counters, - "Conflicts Resolved: Client Wins"); - IntSyncStat conflicts_resolved_server_wins(section_counters, - "Conflicts Resolved: Server Wins"); + Section* section_counters = section_list.AddSection("Running Totals"); + Stat<int>* notifications_received = + section_counters->AddIntStat("Notifications Received"); + Stat<int>* updates_received = + section_counters->AddIntStat("Updates Downloaded"); + Stat<int>* tombstone_updates = + section_counters->AddIntStat("Tombstone Updates"); + Stat<int>* reflected_updates = + section_counters->AddIntStat("Reflected Updates"); + Stat<int>* successful_commits = + section_counters->AddIntStat("Successful Commits"); + Stat<int>* conflicts_resolved_local_wins = + section_counters->AddIntStat("Conflicts Resolved: Client Wins"); + Stat<int>* conflicts_resolved_server_wins = + section_counters->AddIntStat("Conflicts Resolved: Server Wins"); - base::ListValue* section_this_cycle = - AddSection(stats_list.get(), "Transient Counters (this cycle)"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_this_cycle->Reserve(4); - IntSyncStat encryption_conflicts(section_this_cycle, "Encryption Conflicts"); - IntSyncStat hierarchy_conflicts(section_this_cycle, "Hierarchy Conflicts"); - IntSyncStat server_conflicts(section_this_cycle, "Server Conflicts"); - IntSyncStat committed_items(section_this_cycle, "Committed Items"); + Section* section_this_cycle = + section_list.AddSection("Transient Counters (this cycle)"); + Stat<int>* encryption_conflicts = + section_this_cycle->AddIntStat("Encryption Conflicts"); + Stat<int>* hierarchy_conflicts = + section_this_cycle->AddIntStat("Hierarchy Conflicts"); + Stat<int>* server_conflicts = + section_this_cycle->AddIntStat("Server Conflicts"); + Stat<int>* committed_items = + section_this_cycle->AddIntStat("Committed Items"); - base::ListValue* section_that_cycle = - AddSection(stats_list.get(), - "Transient Counters (last cycle of last completed session)"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_that_cycle->Reserve(3); - IntSyncStat updates_downloaded(section_that_cycle, "Updates Downloaded"); - IntSyncStat committed_count(section_that_cycle, "Committed Count"); - IntSyncStat entries(section_that_cycle, "Entries"); + Section* section_that_cycle = section_list.AddSection( + "Transient Counters (last cycle of last completed session)"); + Stat<int>* updates_downloaded = + section_that_cycle->AddIntStat("Updates Downloaded"); + Stat<int>* committed_count = + section_that_cycle->AddIntStat("Committed Count"); + Stat<int>* entries = section_that_cycle->AddIntStat("Entries"); - base::ListValue* section_nudge_info = - AddSection(stats_list.get(), "Nudge Source Counters"); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - section_nudge_info->Reserve(3); - IntSyncStat nudge_source_notification(section_nudge_info, - "Server Invalidations"); - IntSyncStat nudge_source_local(section_nudge_info, "Local Changes"); - IntSyncStat nudge_source_local_refresh(section_nudge_info, "Local Refreshes"); - - // This list of sections belongs in the 'details' field of the returned - // message. - about_info->Set(kDetailsKey, std::move(stats_list)); + Section* section_nudge_info = + section_list.AddSection("Nudge Source Counters"); + Stat<int>* nudge_source_notification = + section_nudge_info->AddIntStat("Server Invalidations"); + Stat<int>* nudge_source_local = + section_nudge_info->AddIntStat("Local Changes"); + Stat<int>* nudge_source_local_refresh = + section_nudge_info->AddIntStat("Local Refreshes"); // Populate all the fields we declared above. - client_version.SetValue(GetVersionString(channel)); + client_version->Set(GetVersionString(channel)); if (!service) { - summary_string.SetValue("Sync service does not exist"); + summary_string->Set("Sync service does not exist"); + about_info->SetKey(kDetailsKey, section_list.ToValue()); return about_info; } SyncStatus full_status; bool is_status_valid = service->QueryDetailedSyncStatus(&full_status); - bool sync_active = service->IsSyncActive(); const SyncCycleSnapshot& snapshot = service->GetLastCycleSnapshot(); - - if (is_status_valid) - summary_string.SetValue(service->QuerySyncStatusSummaryString()); - - server_url.SetValue(service->sync_service_url().spec()); - - if (is_status_valid && !full_status.sync_id.empty()) - sync_id.SetValue(full_status.sync_id); - if (is_status_valid && !full_status.invalidator_client_id.empty()) - invalidator_id.SetValue(full_status.invalidator_client_id); - - username.SetValue(primary_account_info.email); - const SyncService::SyncTokenStatus& token_status = service->GetSyncTokenStatus(); - server_connection.SetValue(GetConnectionStatus(token_status)); - request_token_time.SetValue( - GetTimeStr(token_status.token_request_time, "n/a")); - receive_token_time.SetValue( - GetTimeStr(token_status.token_receive_time, "n/a")); + + // Summary. + if (is_status_valid) + summary_string->Set(service->QuerySyncStatusSummaryString()); + + // Version Info. + // |client_version| was already set above. + server_url->Set(service->sync_service_url().spec()); + + // Identity. + if (is_status_valid && !full_status.sync_id.empty()) + sync_id->Set(full_status.sync_id); + if (is_status_valid && !full_status.invalidator_client_id.empty()) + invalidator_id->Set(full_status.invalidator_client_id); + username->Set(primary_account_info.email); + + // Credentials. + request_token_time->Set(GetTimeStr(token_status.token_request_time, "n/a")); + receive_token_time->Set(GetTimeStr(token_status.token_receive_time, "n/a")); std::string err = token_status.last_get_token_error.error_message(); - token_request_status.SetValue(err.empty() ? "OK" : err); - next_token_request.SetValue( + token_request_status->Set(err.empty() ? "OK" : err); + next_token_request->Set( GetTimeStr(token_status.next_token_request_time, "not scheduled")); - last_synced.SetValue(GetLastSyncedTimeString(service->GetLastSyncedTime())); - is_setup_complete.SetValue(service->IsFirstSetupComplete()); - is_local_sync_enabled.SetValue(service->IsLocalSyncEnabled()); - if (service->IsLocalSyncEnabled() && is_status_valid) { - local_backend_path.SetValue(full_status.local_sync_folder); - } - backend_initialization.SetValue( - service->GetEngineInitializationStateString()); - if (is_status_valid) { - is_syncing.SetValue(full_status.syncing); - retry_time.SetValue(GetTimeStr(full_status.retry_time, - "Scheduler is not in backoff or throttled")); - } + // Local State. + server_connection->Set(GetConnectionStatus(token_status)); + last_synced->Set(GetLastSyncedTimeString(service->GetLastSyncedTime())); + is_setup_complete->Set(service->IsFirstSetupComplete()); + backend_initialization->Set(service->GetEngineInitializationStateString()); + if (is_status_valid) + is_syncing->Set(full_status.syncing); + is_local_sync_enabled->Set(service->IsLocalSyncEnabled()); + if (service->IsLocalSyncEnabled() && is_status_valid) + local_backend_path->Set(full_status.local_sync_folder); + // Network. if (snapshot.is_initialized()) - is_any_throttled_or_backoff.SetValue(snapshot.is_silenced()); + is_any_throttled_or_backoff->Set(snapshot.is_silenced()); if (is_status_valid) { - are_notifications_enabled.SetValue(full_status.notifications_enabled); + retry_time->Set(GetTimeStr(full_status.retry_time, + "Scheduler is not in backoff or throttled")); } + if (is_status_valid) + are_notifications_enabled->Set(full_status.notifications_enabled); - if (sync_active) { - is_using_explicit_passphrase.SetValue( - service->IsUsingSecondaryPassphrase()); - is_passphrase_required.SetValue(service->IsPassphraseRequired()); - passphrase_time.SetValue( + // Encryption. + if (service->IsSyncActive()) { + is_using_explicit_passphrase->Set(service->IsUsingSecondaryPassphrase()); + is_passphrase_required->Set(service->IsPassphraseRequired()); + passphrase_time->Set( GetTimeStr(service->GetExplicitPassphraseTime(), "No Passphrase Time")); } if (is_status_valid) { - is_cryptographer_ready.SetValue(full_status.cryptographer_ready); - has_pending_keys.SetValue(full_status.crypto_has_pending_keys); - encrypted_types.SetValue(ModelTypeSetToString(full_status.encrypted_types)); - has_keystore_key.SetValue(full_status.has_keystore_key); - keystore_migration_time.SetValue( + is_cryptographer_ready->Set(full_status.cryptographer_ready); + has_pending_keys->Set(full_status.crypto_has_pending_keys); + encrypted_types->Set(ModelTypeSetToString(full_status.encrypted_types)); + has_keystore_key->Set(full_status.has_keystore_key); + keystore_migration_time->Set( GetTimeStr(full_status.keystore_migration_time, "Not Migrated")); - passphrase_type.SetValue( - PassphraseTypeToString(full_status.passphrase_type)); + passphrase_type->Set(PassphraseTypeToString(full_status.passphrase_type)); } + // Status from Last Completed Session. if (snapshot.is_initialized()) { if (snapshot.get_updates_origin() != sync_pb::SyncEnums::UNKNOWN_ORIGIN) { - session_source.SetValue(ProtoEnumToString(snapshot.get_updates_origin())); + session_source->Set(ProtoEnumToString(snapshot.get_updates_origin())); } - get_key_result.SetValue(GetSyncerErrorString( + get_key_result->Set(GetSyncerErrorString( snapshot.model_neutral_state().last_get_key_result)); - download_result.SetValue(GetSyncerErrorString( + download_result->Set(GetSyncerErrorString( snapshot.model_neutral_state().last_download_updates_result)); - commit_result.SetValue( + commit_result->Set( GetSyncerErrorString(snapshot.model_neutral_state().commit_result)); } + // Running Totals. if (is_status_valid) { - notifications_received.SetValue(full_status.notifications_received); - updates_received.SetValue(full_status.updates_received); - tombstone_updates.SetValue(full_status.tombstone_updates_received); - reflected_updates.SetValue(full_status.reflected_updates_received); - successful_commits.SetValue(full_status.num_commits_total); - conflicts_resolved_local_wins.SetValue( - full_status.num_local_overwrites_total); - conflicts_resolved_server_wins.SetValue( + notifications_received->Set(full_status.notifications_received); + updates_received->Set(full_status.updates_received); + tombstone_updates->Set(full_status.tombstone_updates_received); + reflected_updates->Set(full_status.reflected_updates_received); + successful_commits->Set(full_status.num_commits_total); + conflicts_resolved_local_wins->Set(full_status.num_local_overwrites_total); + conflicts_resolved_server_wins->Set( full_status.num_server_overwrites_total); } + // Transient Counters (this cycle). if (is_status_valid) { - encryption_conflicts.SetValue(full_status.encryption_conflicts); - hierarchy_conflicts.SetValue(full_status.hierarchy_conflicts); - server_conflicts.SetValue(full_status.server_conflicts); - committed_items.SetValue(full_status.committed_count); + encryption_conflicts->Set(full_status.encryption_conflicts); + hierarchy_conflicts->Set(full_status.hierarchy_conflicts); + server_conflicts->Set(full_status.server_conflicts); + committed_items->Set(full_status.committed_count); } - if (is_status_valid) { - nudge_source_notification.SetValue(full_status.nudge_source_notification); - nudge_source_local.SetValue(full_status.nudge_source_local); - nudge_source_local_refresh.SetValue(full_status.nudge_source_local_refresh); - } - + // Transient Counters (last cycle of last completed session). if (snapshot.is_initialized()) { - updates_downloaded.SetValue( + updates_downloaded->Set( snapshot.model_neutral_state().num_updates_downloaded_total); - committed_count.SetValue( - snapshot.model_neutral_state().num_successful_commits); - entries.SetValue(snapshot.num_entries()); + committed_count->Set(snapshot.model_neutral_state().num_successful_commits); + entries->Set(static_cast<int>(snapshot.num_entries())); } + // Nudge Source Counters. + if (is_status_valid) { + nudge_source_notification->Set(full_status.nudge_source_notification); + nudge_source_local->Set(full_status.nudge_source_local); + nudge_source_local_refresh->Set(full_status.nudge_source_local_refresh); + } + + // This list of sections belongs in the 'details' field of the returned + // message. + about_info->SetKey(kDetailsKey, section_list.ToValue()); + // The values set from this point onwards do not belong in the // details list. @@ -581,44 +524,46 @@ full_status.sync_protocol_error.error_type != UNKNOWN_ERROR && full_status.sync_protocol_error.error_type != SYNC_SUCCESS; - about_info->SetBoolean("actionable_error_detected", - actionable_error_detected); + about_info->SetKey("actionable_error_detected", + base::Value(actionable_error_detected)); // NOTE: We won't bother showing any of the following values unless // actionable_error_detected is set. - auto actionable_error = std::make_unique<base::ListValue>(); - // TODO(crbug.com/702230): Remove the usages of raw pointers in this file. - actionable_error->Reserve(4); - - StringSyncStat error_type(actionable_error.get(), "Error Type"); - StringSyncStat action(actionable_error.get(), "Action"); - StringSyncStat url(actionable_error.get(), "URL"); - StringSyncStat description(actionable_error.get(), "Error Description"); - about_info->Set("actionable_error", std::move(actionable_error)); + base::Value actionable_error(base::Value::Type::LIST); + Stat<std::string> error_type("Error Type", kUninitialized); + Stat<std::string> action("Action", kUninitialized); + Stat<std::string> url("URL", kUninitialized); + Stat<std::string> description("Error Description", kUninitialized); if (actionable_error_detected) { - error_type.SetValue( + error_type.Set( GetSyncErrorTypeString(full_status.sync_protocol_error.error_type)); - action.SetValue( - GetClientActionString(full_status.sync_protocol_error.action)); - url.SetValue(full_status.sync_protocol_error.url); - description.SetValue(full_status.sync_protocol_error.error_description); + action.Set(GetClientActionString(full_status.sync_protocol_error.action)); + url.Set(full_status.sync_protocol_error.url); + description.Set(full_status.sync_protocol_error.error_description); } - about_info->SetBoolean("unrecoverable_error_detected", - service->HasUnrecoverableError()); + actionable_error.GetList().push_back(error_type.ToValue()); + actionable_error.GetList().push_back(action.ToValue()); + actionable_error.GetList().push_back(url.ToValue()); + actionable_error.GetList().push_back(description.ToValue()); + about_info->SetKey("actionable_error", std::move(actionable_error)); + + about_info->SetKey("unrecoverable_error_detected", + base::Value(service->HasUnrecoverableError())); if (service->HasUnrecoverableError()) { std::string unrecoverable_error_message = "Unrecoverable error detected at " + service->unrecoverable_error_location().ToString() + ": " + service->unrecoverable_error_message(); - about_info->SetString("unrecoverable_error_message", - unrecoverable_error_message); + about_info->SetKey("unrecoverable_error_message", + base::Value(unrecoverable_error_message)); } - about_info->Set("type_status", service->GetTypeStatusMap()); + about_info->SetKey("type_status", base::Value::FromUniquePtrValue( + service->GetTypeStatusMap())); return about_info; }
diff --git a/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java index 014298a..8f12285 100644 --- a/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java +++ b/components/test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsApplication.java
@@ -22,7 +22,7 @@ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } ContextUtils.initApplicationContext(this);
diff --git a/components/test/data/payments/bobpay.com/app1/app.js b/components/test/data/payments/bobpay.com/app1/app.js new file mode 100644 index 0000000..856a895 --- /dev/null +++ b/components/test/data/payments/bobpay.com/app1/app.js
@@ -0,0 +1,16 @@ +/* + * Copyright 2018 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +self.addEventListener('canmakepayment', (evt) => { + evt.respondWith(true); +}); + +self.addEventListener('paymentrequest', (evt) => { + evt.respondWith({ + methodName: evt.methodData[0].supportedMethods, + details: {transactionId: '123'}, + }); +});
diff --git a/components/test/data/payments/bobpay.com/app1/index.html b/components/test/data/payments/bobpay.com/app1/index.html new file mode 100644 index 0000000..d171174e --- /dev/null +++ b/components/test/data/payments/bobpay.com/app1/index.html
@@ -0,0 +1,16 @@ +<!doctype html> +<!-- +Copyright 2018 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Bob Pay 1</title> + </head> + <body> + <script src="index.js"></script> + </body> +</html>
diff --git a/components/test/data/payments/bobpay.com/app1/index.js b/components/test/data/payments/bobpay.com/app1/index.js new file mode 100644 index 0000000..10af3f9 --- /dev/null +++ b/components/test/data/payments/bobpay.com/app1/index.js
@@ -0,0 +1,74 @@ +/* + * Copyright 2018 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Prints output. + * @param {String} src - Where the message is coming from. + * @param {String} txt - The text to print. + */ +function output(src, txt) { + // Handle DOMException: + if (txt.message) { + txt = txt.message; + } + txt = src + ': ' + txt; + if (!domAutomationController) { + txt += ' window.domAutomationController not found.'; + } else { + domAutomationController.send(txt); + } + console.log(txt); +} + +/** + * Installs a payment app. + * @param {String} method - The payment method name that this app supports. + */ +function install(method) { // eslint-disable-line no-unused-vars + if (!navigator.serviceWorker) { + output('install()', 'ServiceWorker API not found.'); + return; + } + + navigator.serviceWorker.getRegistration('app.js') + .then((registration) => { + if (registration) { + output( + 'serviceWorker.getRegistration()', + 'The ServiceWorker is already installed.'); + return; + } + navigator.serviceWorker.register('app.js') + .then(() => { + return navigator.serviceWorker.ready; + }) + .then((registration) => { + if (!registration.paymentManager) { + output( + 'serviceWorker.register()', + 'PaymentManager API not found.'); + return; + } + + registration.paymentManager.instruments + .set('123456', {name: 'Bob Pay', enabledMethods: [method]}) + .then(() => { + output( + 'instruments.set()', + 'Payment app for "' + method + '" method installed.'); + }) + .catch((error) => { + output('instruments.set()', error); + }); + }) + .catch((error) => { + output('serviceWorker.register()', error); + }); + }) + .catch((error) => { + output('serviceWorker.getRegistration()', error); + }); +}
diff --git a/components/test/data/payments/bobpay_ui_skip.js b/components/test/data/payments/bobpay_ui_skip.js index 8bce925..4ade364 100644 --- a/components/test/data/payments/bobpay_ui_skip.js +++ b/components/test/data/payments/bobpay_ui_skip.js
@@ -29,6 +29,36 @@ }) .catch(function(error) { print('complete() rejected<br>' + error); + }); + }) + .catch(function(error) { + print('show() rejected<br>' + error); + }); + } catch (error) { + print('exception thrown<br>' + error); + } +} + +/** + * Launches the PaymentRequest UI with Bob Pay as the only payment method but + * requesting the payer's email as to disable skip ui. + */ +function buyWithRequestedEmail() { // eslint-disable-line no-unused-vars + try { + new PaymentRequest( + [{supportedMethods: ['https://bobpay.com']}], + {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}}, + {requestPayerEmail: true}) + .show() + .then(function(resp) { + resp.complete('success') + .then(function() { + print( + resp.methodName + '<br>' + + JSON.stringify(resp.details, undefined, 2)); + }) + .catch(function(error) { + print('complete() rejected<br>' + error); }); }) .catch(function(error) {
diff --git a/components/test/data/payments/payment_request_bobpay_ui_skip_test.html b/components/test/data/payments/payment_request_bobpay_ui_skip_test.html index 9dfed6d..d4bd9d3 100644 --- a/components/test/data/payments/payment_request_bobpay_ui_skip_test.html +++ b/components/test/data/payments/payment_request_bobpay_ui_skip_test.html
@@ -13,6 +13,7 @@ </head> <body> <div><button onclick="buy()" id="buy">Bob Pay Test</button></div> +<div><button onclick="buyWithRequestedEmail()" id="buyWithRequestedEmail">Bob Pay Test</button></div> <pre id="result"></pre> <script src="util.js"></script> <script src="bobpay_ui_skip.js"></script>
diff --git a/components/toolbar/vector_icons/find_in_page.icon b/components/toolbar/vector_icons/find_in_page.icon index 15ecfda..41f4dc9 100644 --- a/components/toolbar/vector_icons/find_in_page.icon +++ b/components/toolbar/vector_icons/find_in_page.icon
@@ -26,5 +26,4 @@ R_CUBIC_TO, 1.66f, 0, 3, -1.34f, 3, -3, R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/http.1x.icon b/components/toolbar/vector_icons/http.1x.icon index 636b4f6..de63149 100644 --- a/components/toolbar/vector_icons/http.1x.icon +++ b/components/toolbar/vector_icons/http.1x.icon
@@ -23,5 +23,4 @@ LINE_TO, 9, 4, LINE_TO, 7, 4, LINE_TO, 7, 6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/http.icon b/components/toolbar/vector_icons/http.icon index c8a6695..2ab6355 100644 --- a/components/toolbar/vector_icons/http.icon +++ b/components/toolbar/vector_icons/http.icon
@@ -23,5 +23,4 @@ LINE_TO, 18, 10, LINE_TO, 15, 10, LINE_TO, 15, 13, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_invalid.1x.icon b/components/toolbar/vector_icons/https_invalid.1x.icon index 9ccc1af9a..dabd65b8 100644 --- a/components/toolbar/vector_icons/https_invalid.1x.icon +++ b/components/toolbar/vector_icons/https_invalid.1x.icon
@@ -19,5 +19,4 @@ V_LINE_TO, 6, R_H_LINE_TO, 2, R_V_LINE_TO, 3, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_invalid.icon b/components/toolbar/vector_icons/https_invalid.icon index 880493c..9d17d46 100644 --- a/components/toolbar/vector_icons/https_invalid.icon +++ b/components/toolbar/vector_icons/https_invalid.icon
@@ -19,5 +19,4 @@ R_V_LINE_TO, -6, R_H_LINE_TO, 3, R_V_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_valid.1x.icon b/components/toolbar/vector_icons/https_valid.1x.icon index 6e2c372a..c6ba83a 100644 --- a/components/toolbar/vector_icons/https_valid.1x.icon +++ b/components/toolbar/vector_icons/https_valid.1x.icon
@@ -22,5 +22,4 @@ R_CUBIC_TO, 1.1f, 0, 2, 0.89f, 2, 2, V_LINE_TO, 6.01f, H_LINE_TO, 6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_valid.icon b/components/toolbar/vector_icons/https_valid.icon index e374e83..2c4612d 100644 --- a/components/toolbar/vector_icons/https_valid.icon +++ b/components/toolbar/vector_icons/https_valid.icon
@@ -24,5 +24,4 @@ R_CUBIC_TO, 1.66f, 0, 3, 1.34f, 3, 3, R_V_LINE_TO, 2.02f, R_H_LINE_TO, -6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_valid_in_chip.1x.icon b/components/toolbar/vector_icons/https_valid_in_chip.1x.icon index 60bad86..3c7a0e31 100644 --- a/components/toolbar/vector_icons/https_valid_in_chip.1x.icon +++ b/components/toolbar/vector_icons/https_valid_in_chip.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 8.33f, 4, 9, 4.67f, 9, 5.5f, LINE_TO, 9, 6, LINE_TO, 6, 6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/https_valid_in_chip.icon b/components/toolbar/vector_icons/https_valid_in_chip.icon index 49c00e64..0ecae4ec 100644 --- a/components/toolbar/vector_icons/https_valid_in_chip.icon +++ b/components/toolbar/vector_icons/https_valid_in_chip.icon
@@ -24,5 +24,4 @@ R_CUBIC_TO, 1.66f, 0, 3, 1.34f, 3, 3, R_V_LINE_TO, 2.02f, R_H_LINE_TO, -6, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/offline_pin.icon b/components/toolbar/vector_icons/offline_pin.icon index 935b7332..39813c0 100644 --- a/components/toolbar/vector_icons/offline_pin.icon +++ b/components/toolbar/vector_icons/offline_pin.icon
@@ -22,5 +22,4 @@ R_LINE_TO, 5.3f, -5.3f, LINE_TO, 17, 7.3f, LINE_TO, 10.3f, 14, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/open_in_new.icon b/components/toolbar/vector_icons/open_in_new.icon index f998ec7f..df7eee1 100644 --- a/components/toolbar/vector_icons/open_in_new.icon +++ b/components/toolbar/vector_icons/open_in_new.icon
@@ -27,5 +27,4 @@ R_H_LINE_TO, 4, V_LINE_TO, 6, H_LINE_TO, 28, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/product.1x.icon b/components/toolbar/vector_icons/product.1x.icon index 4997801..1565657 100644 --- a/components/toolbar/vector_icons/product.1x.icon +++ b/components/toolbar/vector_icons/product.1x.icon
@@ -34,5 +34,4 @@ CUBIC_TO, 10.1f, 6.84f, 9.16f, 5.9f, 8, 5.9f, CUBIC_TO, 6.84f, 5.9f, 5.9f, 6.84f, 5.9f, 8, CUBIC_TO, 5.9f, 9.16f, 6.84f, 10.1f, 8, 10.1f, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/product.icon b/components/toolbar/vector_icons/product.icon index 98ce8d51..9b741ca 100644 --- a/components/toolbar/vector_icons/product.icon +++ b/components/toolbar/vector_icons/product.icon
@@ -34,5 +34,4 @@ CUBIC_TO, 20.2f, 13.68f, 18.32f, 11.8f, 16, 11.8f, CUBIC_TO, 13.68f, 11.8f, 11.8f, 13.68f, 11.8f, 16, CUBIC_TO, 11.8f, 18.32f, 13.68f, 20.2f, 16, 20.2f, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/star.icon b/components/toolbar/vector_icons/star.icon index 1d471bcb..39a86741 100644 --- a/components/toolbar/vector_icons/star.icon +++ b/components/toolbar/vector_icons/star.icon
@@ -25,5 +25,4 @@ LINE_TO, 15.5f, 6.03f, LINE_TO, 10.11f, 5.56f, LINE_TO, 8, 0.5f, -CLOSE, -END +CLOSE
diff --git a/components/toolbar/vector_icons/star_active.icon b/components/toolbar/vector_icons/star_active.icon index 484e082..d7a9241c 100644 --- a/components/toolbar/vector_icons/star_active.icon +++ b/components/toolbar/vector_icons/star_active.icon
@@ -14,5 +14,4 @@ LINE_TO, 15.5f, 6.03f, LINE_TO, 10.11f, 5.56f, LINE_TO, 8, 0.5f, -CLOSE, -END +CLOSE
diff --git a/components/ui_devtools/views/ui_element.cc b/components/ui_devtools/views/ui_element.cc index 1a48248..e3f0239 100644 --- a/components/ui_devtools/views/ui_element.cc +++ b/components/ui_devtools/views/ui_element.cc
@@ -8,9 +8,6 @@ #include "components/ui_devtools/Protocol.h" #include "components/ui_devtools/views/ui_element_delegate.h" -#include "components/ui_devtools/views/view_element.h" -#include "components/ui_devtools/views/widget_element.h" -#include "components/ui_devtools/views/window_element.h" namespace ui_devtools { namespace { @@ -80,37 +77,6 @@ return 0; } -template <> -int UIElement::FindUIElementIdForBackendElement<aura::Window>( - aura::Window* element) const { - if (type_ == UIElementType::WINDOW && - UIElement::GetBackingElement<aura::Window, WindowElement>(this) == - element) { - return node_id_; - } - for (auto* child : children_) { - int ui_element_id = child->FindUIElementIdForBackendElement(element); - if (ui_element_id) - return ui_element_id; - } - return 0; -} - -template <> -int UIElement::FindUIElementIdForBackendElement<views::View>( - views::View* element) const { - if (type_ == UIElementType::VIEW && - UIElement::GetBackingElement<views::View, ViewElement>(this) == element) { - return node_id_; - } - for (auto* child : children_) { - int ui_element_id = child->FindUIElementIdForBackendElement(element); - if (ui_element_id) - return ui_element_id; - } - return 0; -} - UIElement::UIElement(const UIElementType type, UIElementDelegate* delegate, UIElement* parent)
diff --git a/components/ui_devtools/views/view_element.cc b/components/ui_devtools/views/view_element.cc index 33bae48..bdb42573 100644 --- a/components/ui_devtools/views/view_element.cc +++ b/components/ui_devtools/views/view_element.cc
@@ -105,4 +105,19 @@ return static_cast<const ViewElement*>(element)->view_; } +template <> +int UIElement::FindUIElementIdForBackendElement<views::View>( + views::View* element) const { + if (type_ == UIElementType::VIEW && + UIElement::GetBackingElement<views::View, ViewElement>(this) == element) { + return node_id_; + } + for (auto* child : children_) { + int ui_element_id = child->FindUIElementIdForBackendElement(element); + if (ui_element_id) + return ui_element_id; + } + return 0; +} + } // namespace ui_devtools
diff --git a/components/ui_devtools/views/window_element.cc b/components/ui_devtools/views/window_element.cc index bb5fabe..f6592de 100644 --- a/components/ui_devtools/views/window_element.cc +++ b/components/ui_devtools/views/window_element.cc
@@ -112,4 +112,20 @@ return static_cast<const WindowElement*>(element)->window_; } +template <> +int UIElement::FindUIElementIdForBackendElement<aura::Window>( + aura::Window* element) const { + if (type_ == UIElementType::WINDOW && + UIElement::GetBackingElement<aura::Window, WindowElement>(this) == + element) { + return node_id_; + } + for (auto* child : children_) { + int ui_element_id = child->FindUIElementIdForBackendElement(element); + if (ui_element_id) + return ui_element_id; + } + return 0; +} + } // namespace ui_devtools
diff --git a/components/vector_icons/accessibility.icon b/components/vector_icons/accessibility.icon index 62b8b71c..34b2ce37 100644 --- a/components/vector_icons/accessibility.icon +++ b/components/vector_icons/accessibility.icon
@@ -21,5 +21,4 @@ R_MOVE_TO, 0, -1.94f, R_ARC_TO, 2.5f, 2.5f, 0, 1, 0, 0, -5, R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/back_arrow.1x.icon b/components/vector_icons/back_arrow.1x.icon index 219193f..3b8ee7a 100644 --- a/components/vector_icons/back_arrow.1x.icon +++ b/components/vector_icons/back_arrow.1x.icon
@@ -22,5 +22,4 @@ CUBIC_TO, 7.72f, 14.97f, 7.86f, 15, 8, 15, CUBIC_TO, 8.55f, 15, 9, 14.55f, 9, 14, CUBIC_TO, 9, 13.86f, 8.97f, 13.72f, 8.91f, 13.59f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/back_arrow.icon b/components/vector_icons/back_arrow.icon index 4b76b7ed..4bc93db1 100644 --- a/components/vector_icons/back_arrow.icon +++ b/components/vector_icons/back_arrow.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 15.06f, 3, 14.66f, 3.2f, 14.39f, 3.5f, LINE_TO, 14.36f, 3.47f, LINE_TO, 4, 13.81f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/bluetooth_connected.icon b/components/vector_icons/bluetooth_connected.icon index ea01302..721b972e 100644 --- a/components/vector_icons/bluetooth_connected.icon +++ b/components/vector_icons/bluetooth_connected.icon
@@ -39,5 +39,4 @@ R_LINE_TO, 4, 4, R_LINE_TO, 4, -4, R_LINE_TO, -4, -4, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/business.icon b/components/vector_icons/business.icon index bfefb7b4..afab687 100644 --- a/components/vector_icons/business.icon +++ b/components/vector_icons/business.icon
@@ -83,5 +83,4 @@ R_V_LINE_TO, 4, R_H_LINE_TO, 4, R_V_LINE_TO, -4, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/check_circle.icon b/components/vector_icons/check_circle.icon index cd24bbd..8806a0c7 100644 --- a/components/vector_icons/check_circle.icon +++ b/components/vector_icons/check_circle.icon
@@ -9,5 +9,4 @@ LINE_TO, 20, 28.34f, R_LINE_TO, 15.17f, -15.17f, LINE_TO, 38, 16, -LINE_TO, 20, 34, -END +LINE_TO, 20, 34
diff --git a/components/vector_icons/close.1x.icon b/components/vector_icons/close.1x.icon index a7267fd..6033fcb 100644 --- a/components/vector_icons/close.1x.icon +++ b/components/vector_icons/close.1x.icon
@@ -9,5 +9,4 @@ MOVE_TO, 4, 4, R_LINE_TO, 8, 8, MOVE_TO, 4, 12, -R_LINE_TO, 8, -8, -END +R_LINE_TO, 8, -8
diff --git a/components/vector_icons/close.icon b/components/vector_icons/close.icon index 3a5801a..55c4b63 100644 --- a/components/vector_icons/close.icon +++ b/components/vector_icons/close.icon
@@ -15,5 +15,4 @@ LINE_TO, 17.59f, 19, LINE_TO, 19, 17.59f, LINE_TO, 13.41f, 12, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/close_16.1x.icon b/components/vector_icons/close_16.1x.icon index a7267fd..6033fcb 100644 --- a/components/vector_icons/close_16.1x.icon +++ b/components/vector_icons/close_16.1x.icon
@@ -9,5 +9,4 @@ MOVE_TO, 4, 4, R_LINE_TO, 8, 8, MOVE_TO, 4, 12, -R_LINE_TO, 8, -8, -END +R_LINE_TO, 8, -8
diff --git a/components/vector_icons/close_16.icon b/components/vector_icons/close_16.icon index cfbabc1..425aa3b 100644 --- a/components/vector_icons/close_16.icon +++ b/components/vector_icons/close_16.icon
@@ -8,5 +8,4 @@ MOVE_TO, 8.75f, 8.75f, R_LINE_TO, 14.5f, 14.5f, MOVE_TO, 8.75f, 23.25f, -R_LINE_TO, 14.5f, -14.5f, -END +R_LINE_TO, 14.5f, -14.5f
diff --git a/components/vector_icons/edit.icon b/components/vector_icons/edit.icon index 0cbb1f7..d915a7a 100644 --- a/components/vector_icons/edit.icon +++ b/components/vector_icons/edit.icon
@@ -17,5 +17,4 @@ LINE_TO, 30.26f, 10.25f, LINE_TO, 37.76f, 17.75f, LINE_TO, 41.42f, 14.09f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder.1x.icon b/components/vector_icons/folder.1x.icon index 6173e2f..d8057ec4 100644 --- a/components/vector_icons/folder.1x.icon +++ b/components/vector_icons/folder.1x.icon
@@ -14,5 +14,4 @@ LINE_TO, 9, 4, LINE_TO, 7, 2, LINE_TO, 2.5f, 2, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder.icon b/components/vector_icons/folder.icon index 7c56c7c..3d375b15 100644 --- a/components/vector_icons/folder.icon +++ b/components/vector_icons/folder.icon
@@ -14,5 +14,4 @@ LINE_TO, 16, 8, LINE_TO, 13.2f, 5, LINE_TO, 4.8f, 5, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder_managed.1x.icon b/components/vector_icons/folder_managed.1x.icon index f5dda5d..8786abf 100644 --- a/components/vector_icons/folder_managed.1x.icon +++ b/components/vector_icons/folder_managed.1x.icon
@@ -74,5 +74,4 @@ LINE_TO, 11, 10, LINE_TO, 11, 9, LINE_TO, 10, 9, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder_managed.icon b/components/vector_icons/folder_managed.icon index e8a6d8b4..9ffb4653 100644 --- a/components/vector_icons/folder_managed.icon +++ b/components/vector_icons/folder_managed.icon
@@ -77,5 +77,4 @@ LINE_TO, 23, 21, LINE_TO, 23, 19, LINE_TO, 21, 19, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder_managed_touch.icon b/components/vector_icons/folder_managed_touch.icon index 637009f..a31ffef 100644 --- a/components/vector_icons/folder_managed_touch.icon +++ b/components/vector_icons/folder_managed_touch.icon
@@ -68,5 +68,4 @@ R_V_LINE_TO, 1, R_H_LINE_TO, -1, R_V_LINE_TO, -1, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/folder_touch.icon b/components/vector_icons/folder_touch.icon index a1ad2a3..32c849f 100644 --- a/components/vector_icons/folder_touch.icon +++ b/components/vector_icons/folder_touch.icon
@@ -14,5 +14,4 @@ R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, R_H_LINE_TO, -8, R_LINE_TO, -2, -2, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/forward_arrow.1x.icon b/components/vector_icons/forward_arrow.1x.icon index 60b2c9c..1337e43 100644 --- a/components/vector_icons/forward_arrow.1x.icon +++ b/components/vector_icons/forward_arrow.1x.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 8.28f, 14.97f, 8.14f, 15, 8, 15, CUBIC_TO, 7.45f, 15, 7, 14.55f, 7, 14, CUBIC_TO, 7, 13.86f, 7.03f, 13.72f, 7.09f, 13.59f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/forward_arrow.icon b/components/vector_icons/forward_arrow.icon index 77363e01..aebc27f 100644 --- a/components/vector_icons/forward_arrow.icon +++ b/components/vector_icons/forward_arrow.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 16.94f, 3, 17.34f, 3.2f, 17.61f, 3.5f, LINE_TO, 17.64f, 3.47f, LINE_TO, 28, 13.81f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/help_outline.icon b/components/vector_icons/help_outline.icon index 9f07e95..a6148ffa 100644 --- a/components/vector_icons/help_outline.icon +++ b/components/vector_icons/help_outline.icon
@@ -30,5 +30,4 @@ R_H_LINE_TO, 2, R_CUBIC_TO, 0, -2.25f, 3, -2.5f, 3, -5, R_CUBIC_TO, 0, -2.21f, -1.79f, -4, -4, -4, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/info_outline.icon b/components/vector_icons/info_outline.icon index 049fba9b..052e290 100644 --- a/components/vector_icons/info_outline.icon +++ b/components/vector_icons/info_outline.icon
@@ -26,5 +26,4 @@ LINE_TO, 17.4f, 9, LINE_TO, 14.6f, 9, LINE_TO, 14.6f, 11.8f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/location_on.icon b/components/vector_icons/location_on.icon index 49f18a4..5e1228d 100644 --- a/components/vector_icons/location_on.icon +++ b/components/vector_icons/location_on.icon
@@ -8,5 +8,4 @@ R_CUBIC_TO, 0, 0, 14, -15.5f, 14, -26, R_CUBIC_TO, 0, -7.73f, -6.27f, -14, -14, -14, CLOSE, -CIRCLE, 24, 18, 5, -END +CIRCLE, 24, 18, 5
diff --git a/components/vector_icons/lock.icon b/components/vector_icons/lock.icon index df4b8eb..f12b6943 100644 --- a/components/vector_icons/lock.icon +++ b/components/vector_icons/lock.icon
@@ -29,5 +29,4 @@ R_CUBIC_TO, 0, -3.42f, 2.78f, -6.2f, 6.2f, -6.2f, R_CUBIC_TO, 3.42f, 0, 6.2f, 2.78f, 6.2f, 6.2f, R_V_LINE_TO, 4, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/media_router_active.icon b/components/vector_icons/media_router_active.icon index 74899b02..f8f11a9 100644 --- a/components/vector_icons/media_router_active.icon +++ b/components/vector_icons/media_router_active.icon
@@ -53,5 +53,4 @@ R_CUBIC_TO, 2.88f, 0.92f, 5.19f, 3.25f, 6.12f, 6.11f, R_LINE_TO, 4.13f, 0.01f, V_LINE_TO, 4.38f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/media_router_error.icon b/components/vector_icons/media_router_error.icon index eb1fccd..45fa96c 100644 --- a/components/vector_icons/media_router_error.icon +++ b/components/vector_icons/media_router_error.icon
@@ -59,5 +59,4 @@ R_LINE_TO, 1.06f, -1.06f, R_LINE_TO, -1.69f, -1.69f, R_LINE_TO, 1.69f, -1.69f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/media_router_idle.icon b/components/vector_icons/media_router_idle.icon index d320062e..7976ba8 100644 --- a/components/vector_icons/media_router_idle.icon +++ b/components/vector_icons/media_router_idle.icon
@@ -46,5 +46,4 @@ R_CUBIC_TO, 3.61f, 0, 6.5f, 2.91f, 6.5f, 6.5f, H_LINE_TO, 8, R_CUBIC_TO, 0, -4.39f, -3.59f, -7.94f, -8, -7.94f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/media_router_warning.icon b/components/vector_icons/media_router_warning.icon index 4cbd535b..b94dcd7 100644 --- a/components/vector_icons/media_router_warning.icon +++ b/components/vector_icons/media_router_warning.icon
@@ -56,5 +56,4 @@ R_H_LINE_TO, 1.38f, R_V_LINE_TO, 1.38f, R_H_LINE_TO, -1.38f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/mic.icon b/components/vector_icons/mic.icon index 9a5fecdc..fedd7fc 100644 --- a/components/vector_icons/mic.icon +++ b/components/vector_icons/mic.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, -6.56f, R_CUBIC_TO, 6.56f, -0.97f, 12, -6.61f, 12, -13.44f, R_H_LINE_TO, -3.4f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/midi.icon b/components/vector_icons/midi.icon index 10c73a8..970fd2c 100644 --- a/components/vector_icons/midi.icon +++ b/components/vector_icons/midi.icon
@@ -37,5 +37,4 @@ LINE_TO, 41, 41, LINE_TO, 7, 41, LINE_TO, 7, 7, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/notifications.icon b/components/vector_icons/notifications.icon index 8240b82..3bd7a8a 100644 --- a/components/vector_icons/notifications.icon +++ b/components/vector_icons/notifications.icon
@@ -20,5 +20,4 @@ R_V_LINE_TO, 2, R_H_LINE_TO, 32, R_V_LINE_TO, -2, -R_LINE_TO, -4, -4, -END +R_LINE_TO, -4, -4
diff --git a/components/vector_icons/protocol_handler.icon b/components/vector_icons/protocol_handler.icon index 3ded270d1e..6429320 100644 --- a/components/vector_icons/protocol_handler.icon +++ b/components/vector_icons/protocol_handler.icon
@@ -44,5 +44,4 @@ LINE_TO, 39.29f, 23.71f, LINE_TO, 28.59f, 34.46f, LINE_TO, 28.59f, 34.46f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/reload.1x.icon b/components/vector_icons/reload.1x.icon index 77d5c53..b3017e7 100644 --- a/components/vector_icons/reload.1x.icon +++ b/components/vector_icons/reload.1x.icon
@@ -19,5 +19,4 @@ CUBIC_TO, 4.15f, 15, 1, 11.87f, 1, 8, CUBIC_TO, 1, 4.13f, 4.15f, 1, 8.03f, 1, CUBIC_TO, 9.96f, 1, 11.7f, 1.77f, 12.97f, 3.03f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/reload.icon b/components/vector_icons/reload.icon index 3d72758..3292497 100644 --- a/components/vector_icons/reload.icon +++ b/components/vector_icons/reload.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 27.96f, 21.13f, 28.03f, 20.88f, 28.03f, 20.61f, CUBIC_TO, 28.03f, 19.78f, 27.36f, 19.11f, 26.53f, 19.11f, CUBIC_TO, 25.87f, 19.11f, 25.3f, 19.55f, 25.1f, 20.15f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/screen_share.icon b/components/vector_icons/screen_share.icon index 517fac6..32b8cfc 100644 --- a/components/vector_icons/screen_share.icon +++ b/components/vector_icons/screen_share.icon
@@ -26,5 +26,4 @@ R_LINE_TO, 5.5f, 4.5f, LINE_TO, 17, 20, R_V_LINE_TO, -3, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/search.icon b/components/vector_icons/search.icon index c1e5f08..715ab9f 100644 --- a/components/vector_icons/search.icon +++ b/components/vector_icons/search.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 16.64f, 6.56f, 19.54f, 9.43f, 19.54f, 12.96f, CUBIC_TO, 19.54f, 16.5f, 16.64f, 19.36f, 13.07f, 19.36f, LINE_TO, 13.07f, 19.36f, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/usb.icon b/components/vector_icons/usb.icon index 61d9679..6dd7a5c 100644 --- a/components/vector_icons/usb.icon +++ b/components/vector_icons/usb.icon
@@ -34,5 +34,4 @@ R_H_LINE_TO, 2, R_V_LINE_TO, -8, R_H_LINE_TO, -8, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/videocam.icon b/components/vector_icons/videocam.icon index 994e07ed..0ff8a27 100644 --- a/components/vector_icons/videocam.icon +++ b/components/vector_icons/videocam.icon
@@ -15,5 +15,4 @@ R_LINE_TO, 8, 8, V_LINE_TO, 13, R_LINE_TO, -8, 8, -CLOSE, -END +CLOSE
diff --git a/components/vector_icons/warning.icon b/components/vector_icons/warning.icon index 7a5f4256..ffb28b8 100644 --- a/components/vector_icons/warning.icon +++ b/components/vector_icons/warning.icon
@@ -21,5 +21,4 @@ R_V_LINE_TO, -8, R_H_LINE_TO, 4, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/components/visitedlink/test/visitedlink_perftest.cc b/components/visitedlink/test/visitedlink_perftest.cc index 82de5587..74d858a 100644 --- a/components/visitedlink/test/visitedlink_perftest.cc +++ b/components/visitedlink/test/visitedlink_perftest.cc
@@ -140,7 +140,8 @@ } // Tests how long it takes to write and read a large database to and from disk. -TEST_F(VisitedLink, TestLoad) { +// Flaky, see crbug.com/822308. +TEST_F(VisitedLink, DISABLED_TestLoad) { // create a big DB { TimeLogger table_initialization_timer("Table_initialization");
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc index e8b9673..d812980e 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.cc +++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -65,7 +65,9 @@ GpuDisplayProvider::GpuDisplayProvider( uint32_t restart_id, scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service, - gpu::GpuChannelManager* gpu_channel_manager) + gpu::GpuChannelManager* gpu_channel_manager, + bool headless, + bool wait_for_all_pipeline_stages_before_draw) : restart_id_(restart_id), gpu_service_(std::move(gpu_service)), gpu_channel_manager_delegate_(gpu_channel_manager->delegate()), @@ -73,7 +75,10 @@ std::make_unique<InProcessGpuMemoryBufferManager>( gpu_channel_manager)), image_factory_(GetImageFactory(gpu_channel_manager)), - task_runner_(base::ThreadTaskRunnerHandle::Get()) { + task_runner_(base::ThreadTaskRunnerHandle::Get()), + headless_(headless), + wait_for_all_pipeline_stages_before_draw_( + wait_for_all_pipeline_stages_before_draw) { DCHECK_NE(restart_id_, BeginFrameSource::kNotRestartableId); } @@ -153,7 +158,8 @@ DCHECK_GT(max_frames_pending, 0); auto scheduler = std::make_unique<DisplayScheduler>( - display_begin_frame_source, task_runner_.get(), max_frames_pending); + display_begin_frame_source, task_runner_.get(), max_frames_pending, + wait_for_all_pipeline_stages_before_draw_); // The ownership of the BeginFrameSource is transferred to the caller. *out_begin_frame_source = std::move(synthetic_begin_frame_source); @@ -166,6 +172,9 @@ std::unique_ptr<SoftwareOutputDevice> GpuDisplayProvider::CreateSoftwareOutputDeviceForPlatform( gpu::SurfaceHandle surface_handle) { + if (headless_) + return std::make_unique<SoftwareOutputDevice>(); + #if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW) gfx::AcceleratedWidget widget = surface_handle; #endif
diff --git a/components/viz/service/display_embedder/gpu_display_provider.h b/components/viz/service/display_embedder/gpu_display_provider.h index 728b21f..0a4c19bb 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.h +++ b/components/viz/service/display_embedder/gpu_display_provider.h
@@ -36,7 +36,9 @@ GpuDisplayProvider( uint32_t restart_id, scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service, - gpu::GpuChannelManager* gpu_channel_manager); + gpu::GpuChannelManager* gpu_channel_manager, + bool headless, + bool wait_for_all_pipeline_stages_before_draw); ~GpuDisplayProvider() override; // DisplayProvider implementation. @@ -66,6 +68,9 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const bool headless_; + const bool wait_for_all_pipeline_stages_before_draw_; + DISALLOW_COPY_AND_ASSIGN(GpuDisplayProvider); };
diff --git a/components/viz/service/main/DEPS b/components/viz/service/main/DEPS index 0b4f0cf..d3510c0 100644 --- a/components/viz/service/main/DEPS +++ b/components/viz/service/main/DEPS
@@ -2,6 +2,7 @@ include_rules = [ "+components/discardable_memory/client", + "+components/viz/common/switches.h", "+components/viz/service", "+gpu/command_buffer", "+gpu/config",
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index ced48bb1..45ea1ea 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -13,6 +13,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" +#include "components/viz/common/switches.h" #include "components/viz/service/display_embedder/gpu_display_provider.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/gl/gpu_service_impl.h" @@ -28,6 +29,7 @@ #include "services/metrics/public/cpp/mojo_ukm_recorder.h" #include "services/metrics/public/mojom/constants.mojom.h" #include "services/service_manager/public/cpp/connector.h" +#include "ui/gfx/switches.h" #if defined(OS_CHROMEOS) && BUILDFLAG(USE_VAAPI) #include "media/gpu/vaapi/vaapi_wrapper.h" @@ -274,9 +276,13 @@ mojom::FrameSinkManagerParamsPtr params) { DCHECK(!frame_sink_manager_); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + display_provider_ = std::make_unique<GpuDisplayProvider>( params->restart_id, gpu_command_service_, - gpu_service_->gpu_channel_manager()); + gpu_service_->gpu_channel_manager(), + command_line->HasSwitch(switches::kHeadless), + command_line->HasSwitch(switches::kRunAllCompositorStagesBeforeDraw)); mojom::FrameSinkManagerClientPtr client( std::move(params->frame_sink_manager_client));
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index 2ea2ea7b..d9d92126 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -57,13 +57,13 @@ active_frame_data_.reset(); } -bool Surface::InheritActivationDeadlineFrom(Surface* surface) { +void Surface::InheritActivationDeadlineFrom(Surface* surface) { TRACE_EVENT1("viz", "Surface::InheritActivationDeadlineFrom", "FrameSinkId", surface_id().frame_sink_id().ToString()); if (!deadline_ || !surface->deadline_) - return false; + return; - return deadline_->InheritFrom(*surface->deadline_); + deadline_->InheritFrom(*surface->deadline_); } void Surface::SetPreviousFrameSurface(Surface* surface) {
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index 13a37537..f3c6522 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -102,7 +102,12 @@ bool has_deadline() const { return deadline_ && deadline_->has_deadline(); } - bool InheritActivationDeadlineFrom(Surface* surface); + // Inherits the same deadline as the one specified by |surface|. A deadline + // may be set further out in order to avoid doing unnecessary work while a + // parent surface is blocked on dependencies. A deadline may be shortened + // in order to minimize guttering (by unblocking children blocked on their + // grandchildren sooner). + void InheritActivationDeadlineFrom(Surface* surface); void SetPreviousFrameSurface(Surface* surface);
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.cc b/components/viz/service/surfaces/surface_dependency_deadline.cc index bd28f50..14678e8 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.cc +++ b/components/viz/service/surfaces/surface_dependency_deadline.cc
@@ -42,20 +42,20 @@ return CancelInternal(false); } -bool SurfaceDependencyDeadline::InheritFrom( +void SurfaceDependencyDeadline::InheritFrom( const SurfaceDependencyDeadline& other) { if (*this == other) - return false; + return; - DCHECK(has_deadline()); - - CancelInternal(false); + base::Optional<base::TimeDelta> duration = CancelInternal(false); last_begin_frame_args_ = other.last_begin_frame_args_; begin_frame_source_ = other.begin_frame_source_; deadline_ = other.deadline_; - if (deadline_) + if (deadline_) { + if (!duration) + start_time_ = tick_clock_->NowTicks(); begin_frame_source_->AddObserver(this); - return true; + } } bool SurfaceDependencyDeadline::operator==(
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.h b/components/viz/service/surfaces/surface_dependency_deadline.h index a2be092..6bc6902 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.h +++ b/components/viz/service/surfaces/surface_dependency_deadline.h
@@ -38,9 +38,12 @@ bool has_deadline() const { return deadline_.has_value(); } - // Takes on the same BeginFrameSource and deadline as |other|. Returns - // false if they're already the same, and true otherwise. - bool InheritFrom(const SurfaceDependencyDeadline& other); + base::Optional<base::TimeTicks> deadline_for_testing() const { + return deadline_; + } + + // Takes on the same BeginFrameSource and deadline as |other|. + void InheritFrom(const SurfaceDependencyDeadline& other); bool operator==(const SurfaceDependencyDeadline& other); bool operator!=(const SurfaceDependencyDeadline& other) {
diff --git a/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc b/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc index ce631b2..98bb7b39 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc +++ b/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc
@@ -64,6 +64,8 @@ SurfaceDependencyDeadline* deadline() { return deadline_.get(); } + SurfaceDependencyDeadline* deadline2() { return deadline2_.get(); } + void SendLateBeginFrame(uint32_t frames_late) { // Creep the time forward so that any BeginFrameArgs is not equal to the // last one otherwise we violate the BeginFrameSource contract. @@ -83,9 +85,14 @@ deadline_ = std::make_unique<SurfaceDependencyDeadline>( &client_, begin_frame_source_.get(), now_src_.get()); + + deadline2_ = std::make_unique<SurfaceDependencyDeadline>( + &client_, begin_frame_source_.get(), now_src_.get()); } void TearDown() override { + deadline2_->Cancel(); + deadline2_.reset(); deadline_->Cancel(); deadline_.reset(); begin_frame_source_.reset(); @@ -97,6 +104,7 @@ std::unique_ptr<FakeSlowBeginFrameSource> begin_frame_source_; FakeSurfaceDeadlineClient client_; std::unique_ptr<SurfaceDependencyDeadline> deadline_; + std::unique_ptr<SurfaceDependencyDeadline> deadline2_; DISALLOW_COPY_AND_ASSIGN(SurfaceDependencyDeadlineTest); }; @@ -128,5 +136,65 @@ EXPECT_TRUE(deadline()->has_deadline()); } +// This test verifies that inheriting a deadline with no pre-existing deadline +// sets up the start time of the event to the time of inheritance. +TEST_F(SurfaceDependencyDeadlineTest, InheritDeadline) { + FrameDeadline frame_deadline = MakeDefaultDeadline(); + SendLateBeginFrame(1u); + EXPECT_TRUE(deadline()->Set(frame_deadline)); + EXPECT_TRUE(deadline()->has_deadline()); + + SendLateBeginFrame(1u); + EXPECT_FALSE(deadline2()->has_deadline()); + deadline2()->InheritFrom(*deadline()); + EXPECT_TRUE(deadline()->has_deadline()); + EXPECT_EQ(deadline()->deadline_for_testing(), + deadline2()->deadline_for_testing()); + + base::Optional<base::TimeDelta> duration1 = deadline()->Cancel(); + base::Optional<base::TimeDelta> duration2 = deadline2()->Cancel(); + ASSERT_TRUE(duration1.has_value()); + ASSERT_TRUE(duration2.has_value()); + + // We inject time on BeginFrameSource::AddObserver and in practice we cannot + // know the exact difference in duration between two events a priori so we + // just verify that the first event was longer than the second. + EXPECT_GT(duration1, duration2); +} + +// This test verifies that if an active deadline object inherits a deadline +// from another object, it does not inherit the start time of the event. +TEST_F(SurfaceDependencyDeadlineTest, InheritDeadlineWithActiveDeadline) { + { + FrameDeadline frame_deadline = MakeDefaultDeadline(); + SendLateBeginFrame(1u); + EXPECT_TRUE(deadline()->Set(frame_deadline)); + EXPECT_TRUE(deadline()->has_deadline()); + } + + { + FrameDeadline frame_deadline = MakeDefaultDeadline(); + SendLateBeginFrame(1u); + // deadline2's start time is later than deadline2. + EXPECT_TRUE(deadline2()->Set(frame_deadline)); + EXPECT_TRUE(deadline2()->has_deadline()); + } + + deadline()->InheritFrom(*deadline2()); + EXPECT_TRUE(deadline()->has_deadline()); + EXPECT_EQ(deadline()->deadline_for_testing(), + deadline2()->deadline_for_testing()); + + base::Optional<base::TimeDelta> duration1 = deadline()->Cancel(); + base::Optional<base::TimeDelta> duration2 = deadline2()->Cancel(); + ASSERT_TRUE(duration1.has_value()); + ASSERT_TRUE(duration2.has_value()); + + // We inject time on BeginFrameSource::AddObserver and in practice we cannot + // know the exact difference in duration between two events a priori so we + // just verify that the first event was longer than the second. + EXPECT_GT(duration1, duration2); +} + } // namespace test } // namespace viz
diff --git a/components/viz/service/surfaces/surface_dependency_tracker.cc b/components/viz/service/surfaces/surface_dependency_tracker.cc index a419397..74942f2 100644 --- a/components/viz/service/surfaces/surface_dependency_tracker.cc +++ b/components/viz/service/surfaces/surface_dependency_tracker.cc
@@ -121,9 +121,6 @@ const CompositorFrame& pending_frame = surface->GetPendingFrame(); - // Determine an activation deadline for the pending CompositorFrame. - bool deadline_changed = false; - // Inherit the deadline from the first parent blocked on this surface. auto it = blocked_surfaces_from_dependency_.find( surface->surface_id().frame_sink_id()); @@ -133,7 +130,7 @@ Surface* parent = surface_manager_->GetSurfaceForId(parent_id); if (parent && parent->has_deadline() && parent->activation_dependencies().count(surface->surface_id())) { - deadline_changed = surface->InheritActivationDeadlineFrom(parent); + surface->InheritActivationDeadlineFrom(parent); break; } }
diff --git a/content/browser/appcache/appcache_url_loader_job.cc b/content/browser/appcache/appcache_url_loader_job.cc index 109992c..7add0b0 100644 --- a/content/browser/appcache/appcache_url_loader_job.cc +++ b/content/browser/appcache/appcache_url_loader_job.cc
@@ -327,6 +327,10 @@ network::URLLoaderCompletionStatus status(error_code); if (!error_code) { + const net::HttpResponseInfo* http_info = + is_range_request() ? range_response_info_.get() + : (info_ ? info_->http_response_info() : nullptr); + status.exists_in_cache = http_info->was_cached; status.completion_time = base::TimeTicks::Now(); status.encoded_body_length = is_range_request() ? range_response_info_->headers->GetContentLength()
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index 52068e0..6e5f66d 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc
@@ -55,12 +55,12 @@ #include "content/browser/download/download_utils.h" #include "content/browser/download/parallel_download_utils.h" #include "content/browser/renderer_host/render_view_host_impl.h" +#include "content/browser/storage_partition_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/download_item_utils.h" -#include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" #include "content/public/common/referrer.h" #include "net/http/http_response_headers.h" @@ -2355,9 +2355,9 @@ received_slices_.clear(); } - StoragePartition* storage_partition = + StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>( BrowserContext::GetStoragePartitionForSite(GetBrowserContext(), - request_info_.site_url); + request_info_.site_url)); net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("download_manager_resume", R"( @@ -2429,7 +2429,8 @@ in_progress_entry->ukm_download_id, GetResumeMode(), time_since_start); } - delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); + delegate_->ResumeInterruptedDownload(std::move(download_params), GetId(), + storage_partition); if (job_) job_->Resume(false);
diff --git a/content/browser/download/download_item_impl_delegate.cc b/content/browser/download/download_item_impl_delegate.cc index 0c03780e..cb30d4c2 100644 --- a/content/browser/download/download_item_impl_delegate.cc +++ b/content/browser/download/download_item_impl_delegate.cc
@@ -64,7 +64,8 @@ void DownloadItemImplDelegate::ResumeInterruptedDownload( std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id) {} + uint32_t id, + StoragePartitionImpl* storage_partition) {} BrowserContext* DownloadItemImplDelegate::GetBrowserContext() const { return nullptr;
diff --git a/content/browser/download/download_item_impl_delegate.h b/content/browser/download/download_item_impl_delegate.h index f919d5d..ddc8b25 100644 --- a/content/browser/download/download_item_impl_delegate.h +++ b/content/browser/download/download_item_impl_delegate.h
@@ -16,8 +16,9 @@ #include "content/public/browser/download_manager_delegate.h" namespace content { -class DownloadItemImpl; class BrowserContext; +class DownloadItemImpl; +class StoragePartitionImpl; // Delegate for operations that a DownloadItemImpl can't do for itself. // The base implementation of this class does nothing (returning false @@ -73,7 +74,8 @@ // Called when an interrupted download is resumed. virtual void ResumeInterruptedDownload( std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id); + uint32_t id, + StoragePartitionImpl* storage_partition); // For contextual issues like language and prefs. virtual BrowserContext* GetBrowserContext() const;
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc index f593211..ca77584 100644 --- a/content/browser/download/download_item_impl_unittest.cc +++ b/content/browser/download/download_item_impl_unittest.cc
@@ -90,7 +90,8 @@ void ResumeInterruptedDownload( std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id) override { + uint32_t id, + StoragePartitionImpl* storage_partition) override { MockResumeInterruptedDownload(params.get(), id); } MOCK_METHOD2(MockResumeInterruptedDownload,
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 873d197f..13e5756 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -786,8 +786,9 @@ // download. void DownloadManagerImpl::ResumeInterruptedDownload( std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id) { - BeginDownloadInternal(std::move(params), nullptr, id); + uint32_t id, + StoragePartitionImpl* storage_partition) { + BeginDownloadInternal(std::move(params), nullptr, id, storage_partition); } @@ -951,8 +952,11 @@ download::RecordDownloadCountWithSource( download::DownloadCountTypes::DOWNLOAD_TRIGGERED_COUNT, params->download_source()); + StoragePartitionImpl* storage_partition = + GetStoragePartition(browser_context_, params->render_process_host_id(), + params->render_frame_host_routing_id()); BeginDownloadInternal(std::move(params), std::move(blob_data_handle), - download::DownloadItem::kInvalidId); + download::DownloadItem::kInvalidId, storage_partition); } void DownloadManagerImpl::AddObserver(Observer* observer) { @@ -1146,21 +1150,28 @@ int render_process_id = -1; int render_frame_id = -1; + GURL site_url, tab_url, tab_referrer_url; WebContents* web_contents = web_contents_getter.Run(); if (web_contents) { RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); if (render_frame_host) { render_process_id = render_frame_host->GetProcess()->GetID(); render_frame_id = render_frame_host->GetRoutingID(); + site_url = render_frame_host->GetSiteInstance()->GetSiteURL(); + } + NavigationEntry* entry = web_contents->GetController().GetVisibleEntry(); + if (entry) { + tab_url = entry->GetURL(); + tab_referrer_url = entry->GetReferrer().url; } } BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::BindOnce(&DownloadManagerImpl::CreateDownloadHandlerForNavigation, weak_factory_.GetWeakPtr(), std::move(resource_request), - render_process_id, render_frame_id, std::move(url_chain), - suggested_filename, std::move(response), - std::move(cert_status), + render_process_id, render_frame_id, site_url, tab_url, + tab_referrer_url, std::move(url_chain), suggested_filename, + std::move(response), std::move(cert_status), std::move(url_loader_client_endpoints), base::MessageLoop::current()->task_runner())); } @@ -1171,6 +1182,9 @@ std::unique_ptr<network::ResourceRequest> resource_request, int render_process_id, int render_frame_id, + const GURL& site_url, + const GURL& tab_url, + const GURL& tab_referrer_url, std::vector<GURL> url_chain, const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, @@ -1182,9 +1196,10 @@ std::unique_ptr<ResourceDownloader> resource_downloader = ResourceDownloader::InterceptNavigationResponse( download_manager, std::move(resource_request), render_process_id, - render_frame_id, std::move(url_chain), suggested_filename, - std::move(response), std::move(cert_status), - std::move(url_loader_client_endpoints), task_runner); + render_frame_id, site_url, tab_url, tab_referrer_url, + std::move(url_chain), suggested_filename, std::move(response), + std::move(cert_status), std::move(url_loader_client_endpoints), + task_runner); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -1197,14 +1212,11 @@ void DownloadManagerImpl::BeginDownloadInternal( std::unique_ptr<download::DownloadUrlParameters> params, std::unique_ptr<storage::BlobDataHandle> blob_data_handle, - uint32_t id) { + uint32_t id, + StoragePartitionImpl* storage_partition) { if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { std::unique_ptr<network::ResourceRequest> request = CreateResourceRequest(params.get()); - StoragePartitionImpl* storage_partition = - GetStoragePartition(browser_context_, params->render_process_host_id(), - params->render_frame_host_routing_id()); - GURL site_url, tab_url, tab_referrer_url; auto* rfh = RenderFrameHost::FromID(params->render_process_host_id(), params->render_frame_host_routing_id());
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index 9bc80c1..f6d1b61 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h
@@ -221,7 +221,8 @@ std::string GetApplicationClientIdForFileScanning() const override; void ResumeInterruptedDownload( std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id) override; + uint32_t id, + StoragePartitionImpl* storage_partition) override; void OpenDownload(DownloadItemImpl* download) override; bool IsMostRecentDownloadItemAtFilePath(DownloadItemImpl* download) override; void ShowDownloadInShell(DownloadItemImpl* download) override; @@ -233,7 +234,8 @@ void BeginDownloadInternal( std::unique_ptr<download::DownloadUrlParameters> params, std::unique_ptr<storage::BlobDataHandle> blob_data_handle, - uint32_t id); + uint32_t id, + StoragePartitionImpl* storage_partition); void InterceptNavigationOnChecksComplete( ResourceRequestInfo::WebContentsGetter web_contents_getter, @@ -253,6 +255,9 @@ std::unique_ptr<network::ResourceRequest> resource_request, int render_process_id, int render_frame_id, + const GURL& site_url, + const GURL& tab_url, + const GURL& tab_referrer_url, std::vector<GURL> url_chain, const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response,
diff --git a/content/browser/download/resource_downloader.cc b/content/browser/download/resource_downloader.cc index b2d4766..7f6ca04 100644 --- a/content/browser/download/resource_downloader.cc +++ b/content/browser/download/resource_downloader.cc
@@ -85,6 +85,9 @@ std::unique_ptr<network::ResourceRequest> resource_request, int render_process_id, int render_frame_id, + const GURL& site_url, + const GURL& tab_url, + const GURL& tab_referrer_url, std::vector<GURL> url_chain, const base::Optional<std::string>& suggested_filename, const scoped_refptr<network::ResourceResponse>& response, @@ -93,7 +96,8 @@ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { auto downloader = std::make_unique<ResourceDownloader>( delegate, std::move(resource_request), render_process_id, render_frame_id, - GURL(), GURL(), GURL(), download::DownloadItem::kInvalidId, task_runner); + site_url, tab_url, tab_referrer_url, download::DownloadItem::kInvalidId, + task_runner); downloader->InterceptResponse(std::move(response), std::move(url_chain), suggested_filename, cert_status, std::move(url_loader_client_endpoints));
diff --git a/content/browser/download/resource_downloader.h b/content/browser/download/resource_downloader.h index 633fe2e..a22250a 100644 --- a/content/browser/download/resource_downloader.h +++ b/content/browser/download/resource_downloader.h
@@ -43,6 +43,9 @@ std::unique_ptr<network::ResourceRequest> resource_request, int render_process_id, int render_frame_id, + const GURL& site_url, + const GURL& tab_url, + const GURL& tab_referrer_url, std::vector<GURL> url_chain, const base::Optional<std::string>& suggested_filename, const scoped_refptr<network::ResourceResponse>& response,
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 4ce79a4..cfddc12 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -570,11 +570,6 @@ request->RegisterSubresourceOverride(std::move(transferrable_loader)); } -void NavigationHandleImpl::SetOnDeferCallbackForTesting( - const base::Closure& on_defer_callback) { - on_defer_callback_for_testing_ = on_defer_callback; -} - const GlobalRequestID& NavigationHandleImpl::GetGlobalRequestID() { DCHECK(state_ >= WILL_PROCESS_RESPONSE); return request_id_; @@ -632,11 +627,8 @@ navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); // Notify each throttle of the request. - base::Closure on_defer_callback_copy = on_defer_callback_for_testing_; NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -709,11 +701,8 @@ } // Notify each throttle of the request. - base::Closure on_defer_callback_copy = on_defer_callback_for_testing_; NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -736,11 +725,8 @@ state_ = WILL_FAIL_REQUEST; // Notify each throttle of the request. - base::Closure on_defer_callback_copy = on_defer_callback_for_testing_; NavigationThrottle::ThrottleCheckResult result = CheckWillFailRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -779,11 +765,8 @@ complete_callback_ = callback; // Notify each throttle of the response. - base::Closure on_defer_callback_copy = on_defer_callback_for_testing_; NavigationThrottle::ThrottleCheckResult result = CheckWillProcessResponse(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -1131,12 +1114,9 @@ "Resume"); NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER; - base::Closure on_defer_callback_copy = on_defer_callback_for_testing_; if (state_ == DEFERRING_START) { result = CheckWillStartRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -1144,8 +1124,6 @@ } else if (state_ == DEFERRING_REDIRECT) { result = CheckWillRedirectRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -1153,8 +1131,6 @@ } else if (state_ == DEFERRING_FAILURE) { result = CheckWillFailRequest(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return; @@ -1162,8 +1138,6 @@ } else { result = CheckWillProcessResponse(); if (result.action() == NavigationThrottle::DEFER) { - if (!on_defer_callback_copy.is_null()) - on_defer_callback_copy.Run(); // DO NOT ADD CODE: the NavigationHandle might have been destroyed during // one of the NavigationThrottle checks. return;
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 90c11ed..63fc835b 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -173,7 +173,6 @@ // Used in tests. State state_for_testing() const { return state_; } - void SetOnDeferCallbackForTesting(const base::Closure& on_defer_callback); // The NavigatorDelegate to notify/query for various navigation events. // Normally this is the WebContents, except if this NavigationHandle was @@ -569,10 +568,6 @@ // in it. int expected_render_process_host_id_; - // Used in tests. Called when the navigation is deferred by one of the - // NavigationThrottles. - base::Closure on_defer_callback_for_testing_; - // If this navigation was triggered by an anchor element with a download // attribute, the |suggested_filename_| contains the attribute's (possibly // empty) value.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index d593d87d..f780c04 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -148,6 +148,7 @@ switches::kEnableLowEndDeviceMode, switches::kDisableLowEndDeviceMode, switches::kNoSandbox, + switches::kRunAllCompositorStagesBeforeDraw, switches::kTestGLLib, switches::kTraceConfigFile, switches::kTraceStartup,
diff --git a/content/browser/linux_ipc_browsertest.cc b/content/browser/linux_ipc_browsertest.cc index 8f917df..0654dff 100644 --- a/content/browser/linux_ipc_browsertest.cc +++ b/content/browser/linux_ipc_browsertest.cc
@@ -16,7 +16,6 @@ #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/test/fontconfig_util_linux.h" namespace content { @@ -25,7 +24,6 @@ public testing::WithParamInterface<std::string> { public: LinuxIPCBrowserTest() { - SetUpFontConfigForTest(); SandboxIPCHandler::SetObserverForTests(this); } ~LinuxIPCBrowserTest() override {} @@ -39,16 +37,6 @@ } } - // Override the system fontconfig configuration with a test configuration so - // that the tested font fallback will work the same across systems. - void SetUpFontConfigForTest() { - gfx::SetUpFontconfig(); - for (size_t i = 0; i < gfx::kNumSystemFontsForFontconfig; ++i) { - gfx::LoadFontIntoFontconfig( - base::FilePath(gfx::kSystemFontsForFontconfig[i])); - } - } - void OnFontOpen(int id) override { base::AutoLock lock(lock_); opened_fonts_.insert(font_names_[id]);
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc index 3be55fa6..8ad8f67a 100644 --- a/content/browser/loader/mojo_async_resource_handler.cc +++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -486,6 +486,7 @@ network::URLLoaderCompletionStatus loader_status; loader_status.error_code = error_code; + loader_status.exists_in_cache = request()->response_info().was_cached; loader_status.completion_time = base::TimeTicks::Now(); loader_status.encoded_data_length = request()->GetTotalReceivedBytes(); loader_status.encoded_body_length = request()->GetRawBodyBytes();
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index 56aa2f7..7ce141a 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -972,7 +972,6 @@ std::vector<std::unique_ptr<URLLoaderRequestHandler>> initial_handlers) : delegate_(delegate), allow_download_(request_info->common_params.allow_download), - response_was_cached_(false), weak_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); int frame_tree_node_id = request_info->frame_tree_node_id; @@ -1119,7 +1118,6 @@ net::SSLInfo ssl_info; if (maybe_ssl_info.has_value()) ssl_info = maybe_ssl_info.value(); - response_was_cached_ = response->head.was_cached; delegate_->OnResponseStarted( std::move(response), std::move(url_loader_client_endpoints), nullptr, @@ -1144,7 +1142,7 @@ "&NavigationURLLoaderNetworkService", this, "success", false); - delegate_->OnRequestFailed(response_was_cached_, status.error_code, + delegate_->OnRequestFailed(status.exists_in_cache, status.error_code, status.ssl_info); }
diff --git a/content/browser/loader/navigation_url_loader_network_service.h b/content/browser/loader/navigation_url_loader_network_service.h index 0b96b8a..4247377 100644 --- a/content/browser/loader/navigation_url_loader_network_service.h +++ b/content/browser/loader/navigation_url_loader_network_service.h
@@ -78,7 +78,6 @@ std::unique_ptr<URLLoaderRequestController> request_controller_; bool allow_download_; - bool response_was_cached_; // Factories to handle navigation requests for non-network resources. ContentBrowserClient::NonNetworkURLLoaderFactoryMap
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 54624e8..54b5b29 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -168,6 +168,7 @@ // Tell the renderer that this request was disallowed. network::URLLoaderCompletionStatus status; status.error_code = net::ERR_ABORTED; + status.exists_in_cache = false; // No security info needed, connection not established. status.completion_time = base::TimeTicks(); status.encoded_data_length = 0;
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 44a09aec..547488f 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -64,7 +64,6 @@ response->head.headers = request->response_headers(); request->GetCharset(&response->head.charset); response->head.content_length = request->GetExpectedContentSize(); - response->head.was_cached = request->was_cached(); request->GetMimeType(&response->head.mime_type); net::HttpResponseInfo response_info = request->response_info(); response->head.was_fetched_via_spdy = response_info.was_fetched_via_spdy;
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc index e286adb..a893ca2 100644 --- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc +++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -126,6 +126,8 @@ int SetDoNotFragment() override { return net::OK; } + void SetMsgConfirm(bool confirm) override {} + void ReceivePacket(const net::IPEndPoint& address, std::vector<char> data) { if (!recv_callback_.is_null()) { int size = std::min(recv_size_, static_cast<int>(data.size()));
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 0d2adec..6f4c8f2 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -523,40 +523,6 @@ EXPECT_TRUE(new_web_contents_observer.RenderViewCreatedCalled()); } -// Observer class to track subresource loads. -class SubresourceLoadObserver : public WebContentsObserver { - public: - explicit SubresourceLoadObserver(Shell* shell) - : WebContentsObserver(shell->web_contents()) {} - - void SubresourceResponseStarted( - const mojom::SubresourceLoadInfo& subresource_load_info) override { - last_subresource_load_info_ = subresource_load_info.Clone(); - } - - mojom::SubresourceLoadInfo* last_subresource_load_info() const { - return last_subresource_load_info_.get(); - } - - private: - mojom::SubresourceLoadInfoPtr last_subresource_load_info_; - - DISALLOW_COPY_AND_ASSIGN(SubresourceLoadObserver); -}; - -IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, - SubresourceLoadInfoReportsWasCached) { - SubresourceLoadObserver observer(shell()); - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url( - embedded_test_server()->GetURL("/page_with_cached_subresource.html")); - NavigateToURL(shell(), url); - EXPECT_FALSE(observer.last_subresource_load_info()->was_cached); - - NavigateToURL(shell(), url); - EXPECT_TRUE(observer.last_subresource_load_info()->was_cached); -} - struct LoadProgressDelegateAndObserver : public WebContentsDelegate, public WebContentsObserver { explicit LoadProgressDelegateAndObserver(Shell* shell)
diff --git a/content/common/manifest_share_target_util_unittest.cc b/content/common/manifest_share_target_util_unittest.cc new file mode 100644 index 0000000..ff256e1b --- /dev/null +++ b/content/common/manifest_share_target_util_unittest.cc
@@ -0,0 +1,258 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <map> +#include <utility> + +#include "content/public/common/manifest_share_target_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace content { +namespace { + +constexpr char kTitle[] = "My title"; +constexpr char kText[] = "My text"; +constexpr char kUrlSpec[] = "https://www.google.com/"; + +} // namespace + +TEST(ManifestShareTargetUtilTest, + ReplaceWebShareUrlPlaceholdersInvalidTemplate) { + const GURL kUrl(kUrlSpec); + GURL url_template_filled; + + // Badly nested placeholders. + GURL url_template = GURL("http://example.com/?q={"); + bool succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, + kUrl, &url_template_filled); + EXPECT_FALSE(succeeded); + + url_template = GURL("http://example.com/?q={title"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); + + url_template = GURL("http://example.com/?q={title{text}}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); + + url_template = GURL("http://example.com/?q={title{}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); + + url_template = GURL("http://example.com/?q={{title}}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); + + // Placeholder with non-identifier character. + url_template = GURL("http://example.com/?q={title?}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); + + // Invalid placeholder in URL fragment. + url_template = GURL("http://example.com/#{title?}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_FALSE(succeeded); +} + +TEST(ManifestShareTargetUtilTest, ReplaceWebShareUrlPlaceholders) { + const GURL kUrl(kUrlSpec); + + // No placeholders. + GURL url_template = GURL("http://example.com/?q=a#a"); + GURL url_template_filled; + bool succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, + kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ(url_template, url_template_filled); + + // Empty |url_template| + url_template = GURL(); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ(GURL(), url_template_filled); + + // One title placeholder. + url_template = GURL("http://example.com/#{title}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#My%20title", url_template_filled.spec()); + + // One text placeholder. + url_template = GURL("http://example.com/#{text}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#My%20text", url_template_filled.spec()); + + // One url placeholder. + url_template = GURL("http://example.com/#{url}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#https%3A%2F%2Fwww.google.com%2F", + url_template_filled.spec()); + + // One of each placeholder, in title, text, url order. + url_template = GURL("http://example.com/#{title}{text}{url}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://example.com/#My%20titleMy%20texthttps%3A%2F%2Fwww.google.com%2F", + url_template_filled.spec()); + + // One of each placeholder, in url, text, title order. + url_template = GURL("http://example.com/#{url}{text}{title}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://example.com/#https%3A%2F%2Fwww.google.com%2FMy%20textMy%20title", + url_template_filled.spec()); + + // Two of each placeholder, some next to each other, others not. + url_template = + GURL("http://example.com/#{title}{url}{text}{text}{title}{url}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://example.com/" + "#My%20titlehttps%3A%2F%2Fwww.google.com%2FMy%20textMy%20textMy%" + "20titlehttps%3A%2F%2Fwww.google.com%2F", + url_template_filled.spec()); + + // Placeholders are in a query string, as values. The expected use case. + // Two of each placeholder, some next to each other, others not. + url_template = GURL( + "http://example.com?title={title}&url={url}&text={text}&text={text}&" + "title={title}&url={url}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://" + "example.com/?title=My%20title&url=https%3A%2F%2Fwww.google.com%2F&" + "text=My%20text&" + "text=My%20text&title=My%20title&url=https%3A%2F%2Fwww.google.com%2F", + url_template_filled.spec()); + + // Placeholder with digit character. + url_template = GURL("http://example.com/#{title1}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#", url_template_filled.spec()); + + // Empty placeholder. + url_template = GURL("http://example.com/#{}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#", url_template_filled.spec()); + + // Unexpected placeholders. + url_template = GURL("http://example.com/#{nonexistentplaceholder}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#", url_template_filled.spec()); + + // Placeholders should only be replaced in query and fragment. + url_template = GURL("http://example.com/subpath{title}/?q={title}#{title}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/subpath%7Btitle%7D/?q=My%20title#My%20title", + url_template_filled.spec()); + + // Braces in the path, which would be invalid, but should parse fine as they + // are escaped. + url_template = GURL("http://example.com/subpath{/?q={title}"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/subpath%7B/?q=My%20title", + url_template_filled.spec()); + + // |url_template| with % escapes. + url_template = GURL("http://example.com#%20{title}%20"); + succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl, + &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#%20My%20title%20", url_template_filled.spec()); +} + +// Test URL escaping done by ReplaceWebShareUrlPlaceholders(). +TEST(ManifestShareTargetUtilTest, ReplaceWebShareUrlPlaceholders_Escaping) { + const GURL kUrl(kUrlSpec); + const GURL kUrlTemplate("http://example.com/#{title}"); + + // Share data that contains percent escapes. + GURL url_template_filled; + bool succeeded = ReplaceWebShareUrlPlaceholders( + kUrlTemplate, "My%20title", kText, kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#My%2520title", url_template_filled.spec()); + + // Share data that contains placeholders. These should not be replaced. + succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "{title}", kText, + kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#%7Btitle%7D", url_template_filled.spec()); + + // All characters that shouldn't be escaped. + succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, + "-_.!~*'()0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", + kText, kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://example.com/#-_.!~*'()0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", + url_template_filled.spec()); + + // All characters that should be escaped. + succeeded = + ReplaceWebShareUrlPlaceholders(kUrlTemplate, " \"#$%&+,/:;<=>?@[\\]^`{|}", + kText, kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ( + "http://example.com/" + "#%20%22%23%24%25%26%2B%2C%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%60%7B%7C%" + "7D", + url_template_filled.spec()); + + // Unicode chars. + // U+263B + succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xe2\x98\xbb", + kText, kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#%E2%98%BB", url_template_filled.spec()); + + // U+00E9 + succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xc3\xa9", kText, + kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#%C3%A9", url_template_filled.spec()); + + // U+1F4A9 + succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xf0\x9f\x92\xa9", + kText, kUrl, &url_template_filled); + EXPECT_TRUE(succeeded); + EXPECT_EQ("http://example.com/#%F0%9F%92%A9", url_template_filled.spec()); +} + +} // namespace content
diff --git a/content/common/page_state_serialization.cc b/content/common/page_state_serialization.cc index c6bb8f0..f4e8d254 100644 --- a/content/common/page_state_serialization.cc +++ b/content/common/page_state_serialization.cc
@@ -706,8 +706,10 @@ case network::DataElement::TYPE_BLOB: data_element->set_blob_uuid(element.blob_uuid()); break; - case network::DataElement::TYPE_RAW_FILE: case network::DataElement::TYPE_DATA_PIPE: + NOTIMPLEMENTED(); + break; + case network::DataElement::TYPE_RAW_FILE: case network::DataElement::TYPE_CHUNKED_DATA_PIPE: case network::DataElement::TYPE_UNKNOWN: NOTREACHED();
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 384255e..8b8f389 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -158,6 +158,8 @@ "main_function_params.h", "manifest.cc", "manifest.h", + "manifest_share_target_util.cc", + "manifest_share_target_util.h", "manifest_util.cc", "manifest_util.h", "media_metadata.cc",
diff --git a/content/public/common/manifest_share_target_util.cc b/content/public/common/manifest_share_target_util.cc new file mode 100644 index 0000000..5be23648 --- /dev/null +++ b/content/public/common/manifest_share_target_util.cc
@@ -0,0 +1,113 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/common/manifest_share_target_util.h" + +#include <map> + +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" +#include "net/base/escape.h" +#include "url/gurl.h" + +namespace content { +namespace { + +// Determines whether a character is allowed in a URL template placeholder. +bool IsIdentifier(char c) { + return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || c == '-' || c == '_'; +} + +// Returns to |out| the result of running the "replace placeholders" algorithm +// on |template_string|. The algorithm is specified at +// https://wicg.github.io/web-share-target/#dfn-replace-placeholders +bool ReplacePlaceholders(base::StringPiece template_string, + base::StringPiece title, + base::StringPiece text, + const GURL& share_url, + std::string* out) { + constexpr char kTitlePlaceholder[] = "title"; + constexpr char kTextPlaceholder[] = "text"; + constexpr char kUrlPlaceholder[] = "url"; + + std::map<base::StringPiece, std::string> placeholder_to_data; + placeholder_to_data[kTitlePlaceholder] = + net::EscapeQueryParamValue(title, false); + placeholder_to_data[kTextPlaceholder] = + net::EscapeQueryParamValue(text, false); + placeholder_to_data[kUrlPlaceholder] = + net::EscapeQueryParamValue(share_url.spec(), false); + + std::vector<base::StringPiece> split_template; + bool last_saw_open = false; + size_t start_index_to_copy = 0; + for (size_t i = 0; i < template_string.size(); ++i) { + if (last_saw_open) { + if (template_string[i] == '}') { + base::StringPiece placeholder = template_string.substr( + start_index_to_copy + 1, i - 1 - start_index_to_copy); + auto it = placeholder_to_data.find(placeholder); + if (it != placeholder_to_data.end()) { + // Replace the placeholder text with the parameter value. + split_template.push_back(it->second); + } + + last_saw_open = false; + start_index_to_copy = i + 1; + } else if (!IsIdentifier(template_string[i])) { + // Error: Non-identifier character seen after open. + return false; + } + } else { + if (template_string[i] == '}') { + // Error: Saw close, with no corresponding open. + return false; + } else if (template_string[i] == '{') { + split_template.push_back(template_string.substr( + start_index_to_copy, i - start_index_to_copy)); + + last_saw_open = true; + start_index_to_copy = i; + } + } + } + if (last_saw_open) { + // Error: Saw open that was never closed. + return false; + } + split_template.push_back(template_string.substr( + start_index_to_copy, template_string.size() - start_index_to_copy)); + + *out = base::StrCat(split_template); + return true; +} + +} // namespace + +bool ReplaceWebShareUrlPlaceholders(const GURL& url_template, + base::StringPiece title, + base::StringPiece text, + const GURL& share_url, + GURL* url_template_filled) { + std::string new_query; + std::string new_ref; + if (!ReplacePlaceholders(url_template.query_piece(), title, text, share_url, + &new_query) || + !ReplacePlaceholders(url_template.ref_piece(), title, text, share_url, + &new_ref)) { + return false; + } + + // Check whether |url_template| has a query in order to preserve the '?' in a + // URL with an empty query. e.g. http://www.google.com/? + GURL::Replacements url_replacements; + if (url_template.has_query()) + url_replacements.SetQueryStr(new_query); + if (url_template.has_ref()) + url_replacements.SetRefStr(new_ref); + *url_template_filled = url_template.ReplaceComponents(url_replacements); + return true; +} + +} // namespace content
diff --git a/content/public/common/manifest_share_target_util.h b/content/public/common/manifest_share_target_util.h new file mode 100644 index 0000000..dd7f441c --- /dev/null +++ b/content/public/common/manifest_share_target_util.h
@@ -0,0 +1,33 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_COMMON_MANIFEST_SHARE_TARGET_UTIL_H_ +#define CONTENT_PUBLIC_COMMON_MANIFEST_SHARE_TARGET_UTIL_H_ + +#include <string> + +#include "base/strings/string_piece.h" +#include "content/common/content_export.h" + +class GURL; + +namespace content { + +// Writes to |url_template_filled|, a copy of |url_template| with all +// instances of "{title}", "{text}", and "{url}" in the query and fragment +// parts of the URL replaced with |title|, |text|, and |url| respectively. +// Replaces instances of "{X}" where "X" is any string besides "title", +// "text", and "url", with an empty string, for forwards compatibility. +// Returns false, if there are badly nested placeholders. +// This includes any case in which two "{" occur before a "}", or a "}" +// occurs with no preceding "{". +CONTENT_EXPORT bool ReplaceWebShareUrlPlaceholders(const GURL& url_template, + base::StringPiece title, + base::StringPiece text, + const GURL& share_url, + GURL* url_template_filled); + +} // namespace content + +#endif // CONTENT_PUBLIC_COMMON_MANIFEST_SHARE_TARGET_UTIL_H_
diff --git a/content/public/common/subresource_load_info.mojom b/content/public/common/subresource_load_info.mojom index 7d2f6b2..4f45ddb9 100644 --- a/content/public/common/subresource_load_info.mojom +++ b/content/public/common/subresource_load_info.mojom
@@ -29,7 +29,4 @@ // Bitmask of status info of the SSL certificate. // See net/cert/cert_status_flags.h uint32 cert_status; - - // True if the response was fetched from the network cache. - bool was_cached; };
diff --git a/content/public/test/DEPS b/content/public/test/DEPS index 788418f..01cbc06a 100644 --- a/content/public/test/DEPS +++ b/content/public/test/DEPS
@@ -23,7 +23,4 @@ "+third_party/iaccessible2", "+ui/base/resource/resource_bundle.h", ], - "content_browser_test.cc": [ - "+ui/views/widget/desktop_aura/desktop_native_widget_aura.h" - ], }
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc index 1a04368f..8e4bd2f 100644 --- a/content/public/test/content_browser_test.cc +++ b/content/public/test/content_browser_test.cc
@@ -30,10 +30,6 @@ #include "ui/base/ime/input_method_initializer.h" #endif -#if defined(USE_AURA) -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" // nogncheck -#endif - namespace content { ContentBrowserTest::ContentBrowserTest() { @@ -85,13 +81,6 @@ subprocess_path); #endif -#if defined(USE_AURA) - // https://crbug.com/695054: Ignore window activation/deactivation to make - // the Chrome-internal focus unaffected by OS events caused by running tests - // in parallel. - views::DesktopNativeWidgetAura::DisableActivationChangeHandlingForTests(); -#endif - // LinuxInputMethodContextFactory has to be initialized. #if !defined(OS_CHROMEOS) && defined(OS_LINUX) ui::InitializeInputMethodForTesting();
diff --git a/content/public/test/navigation_simulator.cc b/content/public/test/navigation_simulator.cc index 298d64b0..206e595 100644 --- a/content/public/test/navigation_simulator.cc +++ b/content/public/test/navigation_simulator.cc
@@ -674,20 +674,6 @@ return request_id_; } -void NavigationSimulator::SetOnDeferCallback( - const base::Closure& on_defer_callback) { - CHECK_LT(state_, FINISHED) - << "The callback should not be set after the navigation has finished"; - if (handle_) { - handle_->SetOnDeferCallbackForTesting(on_defer_callback); - return; - } - - // If there is no NavigationHandle for the navigation yet, store the callback - // until one has been created. - on_defer_callback_ = on_defer_callback; -} - void NavigationSimulator::DidStartNavigation( NavigationHandle* navigation_handle) { // Check if this navigation is the one we're simulating. @@ -717,12 +703,6 @@ base::Bind(&NavigationSimulator::OnWillProcessResponse, weak_factory_.GetWeakPtr()))); - // Pass the |on_defer_callback_| if it was registered. - if (!on_defer_callback_.is_null()) { - handle->SetOnDeferCallbackForTesting(on_defer_callback_); - on_defer_callback_.Reset(); - } - PrepareCompleteCallbackOnHandle(); }
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index ec4fb53..77e745e 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -257,23 +257,6 @@ // callback. content::GlobalRequestID GetGlobalRequestID() const; - // Allows the user of the NavigationSimulator to specify a callback that will - // be called if the navigation is deferred by a NavigationThrottle. This is - // used for testing deferring NavigationThrottles. - // - // Example usage: - // void CheckThrottleStateAndResume() { - // // Do some testing here. - // deferring_navigation_throttle->Resume(); - // } - // unique_ptr<NavigationSimulator> simulator = - // NavigationSimulator::CreateRendererInitiated( - // original_url, render_frame_host); - // simulator->SetOnDeferCallback(base::Bind(&CheckThrottleStateAndResume)); - // simulator->Start(); - // simulator->Commit(); - void SetOnDeferCallback(const base::Closure& on_defer_callback); - private: NavigationSimulator(const GURL& original_url, bool browser_initiated, @@ -381,10 +364,6 @@ // Closure that is set when WaitForThrottleChecksComplete is called. base::Closure throttle_checks_wait_closure_; - // Temporarily holds a closure that will be called on navigation deferral - // until the NavigationHandle for this navigation has been created. - base::Closure on_defer_callback_; - base::WeakPtrFactory<NavigationSimulator> weak_factory_; };
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index 502355e..1cf9992 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -162,7 +162,6 @@ } } subresource_load_info->cert_status = response_head.cert_status; - subresource_load_info->was_cached = response_head.was_cached; NotifySubresourceStarted(RenderThreadImpl::DeprecatedGetMainTaskRunner(), request_info->render_frame_id, std::move(subresource_load_info));
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index 8312725..5f1a87e6 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -246,6 +246,7 @@ // peer at once. network::URLLoaderCompletionStatus status; status.error_code = net::OK; + status.exists_in_cache = false; status.encoded_data_length = strlen(kTestPageContents); client->OnComplete(status); @@ -291,6 +292,7 @@ // OnCompletedRequest, but it should not lead to crashes.) network::URLLoaderCompletionStatus status; status.error_code = net::OK; + status.exists_in_cache = false; status.encoded_data_length = strlen(kTestPageContents); client->OnComplete(status);
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index fc8d917..414a24f 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -462,7 +462,6 @@ enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA}; DeferState defers_loading_; int request_id_; - bool response_was_cached_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; }; @@ -542,7 +541,6 @@ : nullptr), defers_loading_(NOT_DEFERRING), request_id_(-1), - response_was_cached_(false), url_loader_factory_(std::move(url_loader_factory)) { DCHECK(url_loader_factory_ || !resource_dispatcher); } @@ -879,7 +877,6 @@ // TODO(yhirano): Support ftp listening and multipart return; } - response_was_cached_ = info.was_cached; client_->DidReceiveResponse(response); @@ -966,8 +963,8 @@ if (status.error_code != net::OK) { const WebURLError::HasCopyInCache has_copy_in_cache = - response_was_cached_ ? WebURLError::HasCopyInCache::kTrue - : WebURLError::HasCopyInCache::kFalse; + status.exists_in_cache ? WebURLError::HasCopyInCache::kTrue + : WebURLError::HasCopyInCache::kFalse; client_->DidFail( status.cors_error_status ? WebURLError(*status.cors_error_status, has_copy_in_cache, url_)
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc index 29659b7..1be22d6 100644 --- a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc +++ b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
@@ -162,7 +162,14 @@ EXPECT_TRUE(sender_->Track().IsNull()); } -TEST_F(RTCRtpSenderTest, ReplaceTrackCanFail) { +// This test is flaky on Android and Linux. +// See crbug.com/800465 for detail. +#if defined(OS_ANDROID) || defined(OS_LINUX) +#define MAYBE_ReplaceTrackCanFail DISABLED_ReplaceTrackCanFail +#else +#define MAYBE_ReplaceTrackCanFail ReplaceTrackCanFail +#endif +TEST_F(RTCRtpSenderTest, MAYBE_ReplaceTrackCanFail) { auto web_track = CreateWebTrack("track_id"); sender_ = CreateSender(web_track); ASSERT_FALSE(sender_->Track().IsNull()); @@ -177,7 +184,16 @@ EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId()); } -TEST_F(RTCRtpSenderTest, ReplaceTrackIsNotSetSynchronously) { +// This test is flaky on Android and Linux. +// See crbug.com/800465 for detail. +#if defined(OS_ANDROID) || defined(OS_LINUX) +#define MAYBE_ReplaceTrackIsNotSetSynchronously \ + DISABLED_ReplaceTrackIsNotSetSynchronously +#else +#define MAYBE_ReplaceTrackIsNotSetSynchronously \ + ReplaceTrackIsNotSetSynchronously +#endif +TEST_F(RTCRtpSenderTest, MAYBE_ReplaceTrackIsNotSetSynchronously) { auto web_track1 = CreateWebTrack("track1"); sender_ = CreateSender(web_track1);
diff --git a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java index 752627d9..7036686a 100644 --- a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java +++ b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java
@@ -22,7 +22,7 @@ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } ContextUtils.initApplicationContext(this); @@ -34,4 +34,4 @@ PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); ApplicationStatus.initialize(this); } -} \ No newline at end of file +}
diff --git a/content/shell/android/linker_test_apk/src/org/chromium/chromium_linker_test_apk/ChromiumLinkerTestApplication.java b/content/shell/android/linker_test_apk/src/org/chromium/chromium_linker_test_apk/ChromiumLinkerTestApplication.java index bf51d3e2..d6facb7 100644 --- a/content/shell/android/linker_test_apk/src/org/chromium/chromium_linker_test_apk/ChromiumLinkerTestApplication.java +++ b/content/shell/android/linker_test_apk/src/org/chromium/chromium_linker_test_apk/ChromiumLinkerTestApplication.java
@@ -21,7 +21,7 @@ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } ContextUtils.initApplicationContext(this);
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java index b41c605..54db34b 100644 --- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java +++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java
@@ -25,7 +25,7 @@ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } ContextUtils.initApplicationContext(this);
diff --git a/content/shell/app/blink_test_platform_support_linux.cc b/content/shell/app/blink_test_platform_support_linux.cc index 8317845..19d4c71 100644 --- a/content/shell/app/blink_test_platform_support_linux.cc +++ b/content/shell/app/blink_test_platform_support_linux.cc
@@ -11,7 +11,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/path_service.h" -#include "ui/gfx/test/fontconfig_util_linux.h" +#include "base/test/fontconfig_util_linux.h" namespace content { @@ -30,29 +30,12 @@ } bool BlinkTestPlatformInitialize() { - gfx::SetUpFontconfig(); + base::SetUpFontconfig(); base::FilePath base_path; PathService::Get(base::DIR_MODULE, &base_path); - if (!gfx::LoadConfigFileIntoFontconfig( - base_path.Append(FILE_PATH_LITERAL("fonts.conf")))) - return false; - - for (size_t i = 0; i < gfx::kNumSystemFontsForFontconfig; ++i) { - if (!gfx::LoadFontIntoFontconfig( - base::FilePath(gfx::kSystemFontsForFontconfig[i]))) { - return false; - } - } - - for (size_t i = 0; i < gfx::kNumCloudStorageSyncedFonts; ++i) { - if (!gfx::LoadCloudStorageSyncedFontIntoFontConfig( - gfx::kCloudStorageSyncedFonts[i])) - return false; - } - for (size_t i = 0; i < arraysize(kLocalFonts); ++i) { - if (!gfx::LoadFontIntoFontconfig(base_path.Append(kLocalFonts[i]))) + if (!base::LoadFontIntoFontconfig(base_path.Append(kLocalFonts[i]))) return false; }
diff --git a/content/shell/test_runner/BUILD.gn b/content/shell/test_runner/BUILD.gn index bbad433..6456890 100644 --- a/content/shell/test_runner/BUILD.gn +++ b/content/shell/test_runner/BUILD.gn
@@ -147,12 +147,11 @@ } if (use_x11) { copy("copy_x11_fonts") { - # TODO(sergeyu): Move these fonts to third_party/content_shell_fonts . + # TODO(sergeyu): Move these fonts to third_party/test_fonts . visibility = [ ":*" ] sources = [ "//third_party/gardiner_mod/GardinerModBug.ttf", "//third_party/gardiner_mod/GardinerModCat.ttf", - "resources/fonts/fonts.conf", ] outputs = [ "$root_out_dir/{{source_file_part}}", @@ -167,7 +166,7 @@ "resources/fonts/android_main_fonts.xml", ] outputs = [ - "$root_out_dir/content_shell_test_fonts/{{source_file_part}}", + "$root_out_dir/test_fonts/{{source_file_part}}", ] } } @@ -205,7 +204,7 @@ data_deps += [ ":copy_android_fonts_config" ] } if (is_android || is_linux || is_fuchsia) { - deps += [ "//third_party/content_shell_fonts" ] - data_deps += [ "//third_party/content_shell_fonts" ] + deps += [ "//third_party/test_fonts" ] + data_deps += [ "//third_party/test_fonts" ] } }
diff --git a/content/shell/test_runner/resources/fonts/fonts.conf b/content/shell/test_runner/resources/fonts/fonts.conf deleted file mode 100644 index 7ed6e12..0000000 --- a/content/shell/test_runner/resources/fonts/fonts.conf +++ /dev/null
@@ -1,277 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> -<!-- /etc/fonts/fonts.conf file to configure system font access --> -<fontconfig> - <match target="font"> - <edit name="embeddedbitmap" mode="assign"><bool>false</bool></edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>Times</string> - </test> - <edit name="family" mode="assign"> - <string>Times New Roman</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>sans</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>sans serif</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - </match> - - <!-- Some layout tests specify Helvetica as a family and we need to make sure - that we don't fallback to Times New Roman for them --> - <match target="pattern"> - <test qual="any" name="family"> - <string>Helvetica</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>sans-serif</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>serif</string> - </test> - <edit name="family" mode="assign"> - <string>Times New Roman</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>mono</string> - </test> - <edit name="family" mode="assign"> - <string>Courier New</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>monospace</string> - </test> - <edit name="family" mode="assign"> - <string>Courier New</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>Courier</string> - </test> - <edit name="family" mode="assign"> - <string>Courier New</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>cursive</string> - </test> - <edit name="family" mode="assign"> - <string>Comic Sans MS</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>fantasy</string> - </test> - <edit name="family" mode="assign"> - <string>Impact</string> - </edit> - </match> - - <match target="pattern"> - <test qual="any" name="family"> - <string>Monaco</string> - </test> - <edit name="family" mode="assign"> - <string>Times New Roman</string> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>NonAntiAliasedSans</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="antialias" mode="assign"> - <bool>false</bool> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>SlightHintedGeorgia</string> - </test> - <edit name="family" mode="assign"> - <string>Georgia</string> - </edit> - <edit name="hintstyle" mode="assign"> - <const>hintslight</const> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>NonHintedSans</string> - </test> - <edit name="family" mode="assign"> - <string>Verdana</string> - </edit> - <!-- These deliberately contradict each other. The 'hinting' preference - should take priority --> - <edit name="hintstyle" mode="assign"> - <const>hintfull</const> - </edit> - <edit name="hinting" mode="assign"> - <bool>false</bool> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>AutohintedSerif</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="autohint" mode="assign"> - <bool>true</bool> - </edit> - <edit name="hintstyle" mode="assign"> - <const>hintmedium</const> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>HintedSerif</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="autohint" mode="assign"> - <bool>false</bool> - </edit> - <edit name="hintstyle" mode="assign"> - <const>hintmedium</const> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>FullAndAutoHintedSerif</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="autohint" mode="assign"> - <bool>true</bool> - </edit> - <edit name="hintstyle" mode="assign"> - <const>hintfull</const> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>SubpixelEnabledArial</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="rgba" mode="assign"> - <const>rgb</const> - </edit> - </match> - - <match target="pattern"> - <test name="family" compare="eq"> - <string>SubpixelDisabledArial</string> - </test> - <edit name="family" mode="assign"> - <string>Arial</string> - </edit> - <edit name="rgba" mode="assign"> - <const>none</const> - </edit> - </match> - - <match target="pattern"> - <!-- FontConfig doesn't currently provide a well-defined way to turn on - subpixel positioning. This is just an arbitrary pattern to use after - turning subpixel positioning on globally to ensure that we don't have - issues with our style getting cached for other tests. --> - <test name="family" compare="eq"> - <string>SubpixelPositioning</string> - </test> - <edit name="family" mode="assign"> - <string>Times New Roman</string> - </edit> - </match> - - <match target="pattern"> - <!-- See comments above --> - <test name="family" compare="eq"> - <string>SubpixelPositioningAhem</string> - </test> - <edit name="family" mode="assign"> - <string>ahem</string> - </edit> - </match> - - <!-- When we encounter a character that the current font doesn't - support, gfx::GetFallbackFontForChar() returns the first font - that does have a glyph for the character. The list of fonts is - sorted by a pattern that includes the current locale, but doesn't - include a font family (which means that the fallback font depends - on the locale but not on the current font). - - DejaVu Sans is commonly the only font that supports some - characters, such as "⇧", and even when other candidates are - available, DejaVu Sans is commonly first among them, because of - the way Fontconfig is ordinarily configured. For example, the - configuration in the Fonconfig source lists DejaVu Sans under the - sans-serif generic family, and appends sans-serif to patterns - that don't already include a generic family (such as the pattern - in gfx::GetFallbackFontForChar()). - - To get the same fallback font in the layout tests, we could - duplicate this configuration here, or more directly, simply - append DejaVu Sans to all patterns. --> - <match target="pattern"> - <edit name="family" mode="append_last"> - <string>DejaVu Sans</string> - </edit> - </match> - -</fontconfig>
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 3c319a3..fac859d 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -538,10 +538,6 @@ deps += [ "//content/public/browser" ] } - if (use_aura) { - deps += [ "//ui/views" ] - } - configs += [ "//v8:external_startup_data" ] } @@ -1532,6 +1528,7 @@ "../common/input/touch_event_stream_validator_unittest.cc", "../common/inter_process_time_ticks_converter_unittest.cc", "../common/mac/attributed_string_coder_unittest.mm", + "../common/manifest_share_target_util_unittest.cc", "../common/manifest_util_unittest.cc", "../common/media/media_devices_unittest.cc", "../common/notifications/notification_struct_traits_unittest.cc",
diff --git a/content/test/data/accessibility/html/ins.html b/content/test/data/accessibility/html/ins.html index 6f6da3c..ea96fa9 100644 --- a/content/test/data/accessibility/html/ins.html +++ b/content/test/data/accessibility/html/ins.html
@@ -1,5 +1,11 @@ <!DOCTYPE html> <html> +<head> +<style> + /* Make the text small so that it doesn't line-wrap. */ + p { font-size: 8px; } +</style> +</head> <body> <p>My favorite browser is <del>ABC</del> <ins>Chrome</ins>!</p>
diff --git a/content/test/data/cross_site_iframe_factory.html b/content/test/data/cross_site_iframe_factory.html index 9d09bc3..1472a5e 100644 --- a/content/test/data/cross_site_iframe_factory.html +++ b/content/test/data/cross_site_iframe_factory.html
@@ -47,7 +47,7 @@ <title>Cross-site iframe factory</title> <style> body { - font-family: Sans-Serif; + font-family: "DejaVu Sans", Sans-Serif; text-align: center; } iframe {
diff --git a/content/test/data/page_with_cached_subresource.html b/content/test/data/page_with_cached_subresource.html deleted file mode 100644 index be5fc2d..0000000 --- a/content/test/data/page_with_cached_subresource.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head></head> -<body> - <img src="cachetime"/> -</body> -</html>
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn index 4e9d7fc..41e1741 100644 --- a/device/fido/BUILD.gn +++ b/device/fido/BUILD.gn
@@ -35,6 +35,8 @@ "ec_public_key.h", "fido_attestation_statement.cc", "fido_attestation_statement.h", + "fido_ble_uuids.cc", + "fido_ble_uuids.h", "fido_constants.cc", "fido_constants.h", "fido_hid_message.cc", @@ -67,9 +69,6 @@ "u2f_ble_frames.h", "u2f_ble_transaction.cc", "u2f_ble_transaction.h", - "u2f_ble_uuids.cc", - "u2f_ble_uuids.h", - "u2f_command_type.h", "u2f_device.cc", "u2f_device.h", "u2f_discovery.cc",
diff --git a/device/fido/fido_ble_uuids.cc b/device/fido/fido_ble_uuids.cc new file mode 100644 index 0000000..8fe32d09 --- /dev/null +++ b/device/fido/fido_ble_uuids.cc
@@ -0,0 +1,18 @@ +// 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 "device/fido/fido_ble_uuids.h" + +namespace device { + +const char kFidoServiceUUID[] = "0000fffd-0000-1000-8000-00805f9b34fb"; +const char kFidoControlPointUUID[] = "f1d0fff1-deaa-ecee-b42f-c9ba7ed623bb"; +const char kFidoStatusUUID[] = "f1d0fff2-deaa-ecee-b42f-c9ba7ed623bb"; +const char kFidoControlPointLengthUUID[] = + "f1d0fff3-deaa-ecee-b42f-c9ba7ed623bb"; +const char kFidoServiceRevisionUUID[] = "00002a28-0000-1000-8000-00805f9b34fb"; +const char kFidoServiceRevisionBitfieldUUID[] = + "f1d0fff4-deaa-ecee-b42f-c9ba7ed623bb"; + +} // namespace device
diff --git a/device/fido/fido_ble_uuids.h b/device/fido/fido_ble_uuids.h new file mode 100644 index 0000000..61c4a55 --- /dev/null +++ b/device/fido/fido_ble_uuids.h
@@ -0,0 +1,28 @@ +// 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 DEVICE_FIDO_FIDO_BLE_UUIDS_H_ +#define DEVICE_FIDO_FIDO_BLE_UUIDS_H_ + +#include "base/component_export.h" + +namespace device { + +// FIDO GATT Service's UUIDs as defined by the standard: +// https://fidoalliance.org/specs/fido-v2.0-rd-20161004/fido-client-to-authenticator-protocol-v2.0-rd-20161004.html#gatt-service-description +// +// For details on how the short UUIDs for FIDO Service (0xFFFD) and FIDO Service +// Revision (0x2A28) were converted to the long canonical ones, see +// https://www.bluetooth.com/specifications/assigned-numbers/service-discovery +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoServiceUUID[]; +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoControlPointUUID[]; +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoStatusUUID[]; +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoControlPointLengthUUID[]; +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoServiceRevisionUUID[]; +COMPONENT_EXPORT(DEVICE_FIDO) +extern const char kFidoServiceRevisionBitfieldUUID[]; + +} // namespace device + +#endif // DEVICE_FIDO_FIDO_BLE_UUIDS_H_
diff --git a/device/fido/fido_constants.cc b/device/fido/fido_constants.cc index 538134d..c48cffe 100644 --- a/device/fido/fido_constants.cc +++ b/device/fido/fido_constants.cc
@@ -43,4 +43,9 @@ const std::array<uint8_t, 2> kLegacyVersionSuffix = {0x00, 0x00}; +const std::array<uint8_t, 6> kU2fVersionResponse = {'U', '2', 'F', + '_', 'V', '2'}; + +const base::TimeDelta kDeviceTimeout = base::TimeDelta::FromSeconds(3); + } // namespace device
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h index 9fcdfab5..2b82355 100644 --- a/device/fido/fido_constants.h +++ b/device/fido/fido_constants.h
@@ -11,9 +11,16 @@ #include <vector> #include "base/component_export.h" +#include "base/time/time.h" namespace device { +enum class ProtocolVersion { + kCtap, + kU2f, + kUnknown, +}; + // CTAP protocol device response code, as specified in // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html#authenticator-api enum class CtapDeviceResponseCode : uint8_t { @@ -126,30 +133,37 @@ // Commands supported by CTAPHID device as specified in // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html#ctaphid-commands -enum class CtapHidDeviceCommand : uint8_t { - kCtapHidMsg = 0x03, - kCtapHidCBOR = 0x10, - kCtapHidInit = 0x06, - kCtapHidPing = 0x01, - kCtapHidCancel = 0x11, - kCtapHidError = 0x3F, - kCtapHidKeepAlive = 0x3B, - kCtapHidWink = 0x08, - kCtapHidLock = 0x04, +enum class FidoHidDeviceCommand : uint8_t { + kMsg = 0x03, + kCbor = 0x10, + kInit = 0x06, + kPing = 0x01, + kCancel = 0x11, + kError = 0x3F, + kKeepAlive = 0x3B, + kWink = 0x08, + kLock = 0x04, }; -constexpr std::array<CtapHidDeviceCommand, 9> GetCtapHidDeviceCommandList() { - return {CtapHidDeviceCommand::kCtapHidMsg, - CtapHidDeviceCommand::kCtapHidCBOR, - CtapHidDeviceCommand::kCtapHidInit, - CtapHidDeviceCommand::kCtapHidPing, - CtapHidDeviceCommand::kCtapHidCancel, - CtapHidDeviceCommand::kCtapHidError, - CtapHidDeviceCommand::kCtapHidKeepAlive, - CtapHidDeviceCommand::kCtapHidWink, - CtapHidDeviceCommand::kCtapHidLock}; +constexpr std::array<FidoHidDeviceCommand, 9> GetFidoHidDeviceCommandList() { + return {FidoHidDeviceCommand::kMsg, FidoHidDeviceCommand::kCbor, + FidoHidDeviceCommand::kInit, FidoHidDeviceCommand::kPing, + FidoHidDeviceCommand::kCancel, FidoHidDeviceCommand::kError, + FidoHidDeviceCommand::kKeepAlive, FidoHidDeviceCommand::kWink, + FidoHidDeviceCommand::kLock}; } +// BLE device command as specified in +// https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html#command-status-and-error-constants +// U2F BLE device does not support cancel command. +enum class FidoBleDeviceCommand : uint8_t { + kPing = 0x81, + kKeepAlive = 0x82, + kMsg = 0x83, + kCancel = 0xBE, + kError = 0xBF, +}; + // Authenticator API commands supported by CTAP devices, as specified in // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html#authenticator-api enum class CtapRequestCommand : uint8_t { @@ -225,6 +239,14 @@ COMPONENT_EXPORT(DEVICE_FIDO) extern const std::array<uint8_t, 2> kLegacyVersionSuffix; +// Expected response data for version request from U2F device. +// https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html#getversion-request-and-response---u2f_version +COMPONENT_EXPORT(DEVICE_FIDO) +extern const std::array<uint8_t, 6> kU2fVersionResponse; + +// Maximum wait time before client error outs on device. +COMPONENT_EXPORT(DEVICE_FIDO) extern const base::TimeDelta kDeviceTimeout; + } // namespace device #endif // DEVICE_FIDO_FIDO_CONSTANTS_H_
diff --git a/device/fido/fido_hid_message.cc b/device/fido/fido_hid_message.cc index 25db86c..e2f2581 100644 --- a/device/fido/fido_hid_message.cc +++ b/device/fido/fido_hid_message.cc
@@ -16,39 +16,39 @@ // static std::unique_ptr<FidoHidMessage> FidoHidMessage::Create( uint32_t channel_id, - CtapHidDeviceCommand type, + FidoHidDeviceCommand type, base::span<const uint8_t> data) { if (data.size() > kHidMaxMessageSize) return nullptr; switch (type) { - case CtapHidDeviceCommand::kCtapHidPing: + case FidoHidDeviceCommand::kPing: break; - case CtapHidDeviceCommand::kCtapHidMsg: - case CtapHidDeviceCommand::kCtapHidCBOR: { + case FidoHidDeviceCommand::kMsg: + case FidoHidDeviceCommand::kCbor: { if (data.empty()) return nullptr; break; } - case CtapHidDeviceCommand::kCtapHidCancel: - case CtapHidDeviceCommand::kCtapHidWink: { + case FidoHidDeviceCommand::kCancel: + case FidoHidDeviceCommand::kWink: { if (!data.empty()) return nullptr; break; } - case CtapHidDeviceCommand::kCtapHidLock: { + case FidoHidDeviceCommand::kLock: { if (data.size() != 1 || data[0] > kHidMaxLockSeconds) return nullptr; break; } - case CtapHidDeviceCommand::kCtapHidInit: { + case FidoHidDeviceCommand::kInit: { if (data.size() != 8) return nullptr; break; } - case CtapHidDeviceCommand::kCtapHidKeepAlive: - case CtapHidDeviceCommand::kCtapHidError: + case FidoHidDeviceCommand::kKeepAlive: + case FidoHidDeviceCommand::kError: if (data.size() != 1) return nullptr; } @@ -124,7 +124,7 @@ } FidoHidMessage::FidoHidMessage(uint32_t channel_id, - CtapHidDeviceCommand type, + FidoHidDeviceCommand type, base::span<const uint8_t> data) : channel_id_(channel_id) { uint8_t sequence = 0;
diff --git a/device/fido/fido_hid_message.h b/device/fido/fido_hid_message.h index 4e431cf..529aa00 100644 --- a/device/fido/fido_hid_message.h +++ b/device/fido/fido_hid_message.h
@@ -28,7 +28,7 @@ public: // Static functions to create CTAP/U2F HID commands. static std::unique_ptr<FidoHidMessage> Create(uint32_t channel_id, - CtapHidDeviceCommand cmd, + FidoHidDeviceCommand cmd, base::span<const uint8_t> data); // Reconstruct a message from serialized message data. @@ -47,7 +47,7 @@ size_t NumPackets() const; uint32_t channel_id() const { return channel_id_; } - CtapHidDeviceCommand cmd() const { return cmd_; } + FidoHidDeviceCommand cmd() const { return cmd_; } const base::circular_deque<std::unique_ptr<FidoHidPacket>>& GetPacketsForTesting() const { return packets_; @@ -55,12 +55,12 @@ private: FidoHidMessage(uint32_t channel_id, - CtapHidDeviceCommand type, + FidoHidDeviceCommand type, base::span<const uint8_t> data); FidoHidMessage(std::unique_ptr<FidoHidInitPacket> init_packet, size_t remaining_size); uint32_t channel_id_ = kHidBroadcastChannel; - CtapHidDeviceCommand cmd_ = CtapHidDeviceCommand::kCtapHidMsg; + FidoHidDeviceCommand cmd_ = FidoHidDeviceCommand::kMsg; base::circular_deque<std::unique_ptr<FidoHidPacket>> packets_; size_t remaining_size_ = 0;
diff --git a/device/fido/fido_hid_message_unittest.cc b/device/fido/fido_hid_message_unittest.cc index b47c23c..cc7ab4f 100644 --- a/device/fido/fido_hid_message_unittest.cc +++ b/device/fido/fido_hid_message_unittest.cc
@@ -19,7 +19,7 @@ std::vector<uint8_t> data; auto init_packet = std::make_unique<FidoHidInitPacket>( - channel_id, CtapHidDeviceCommand::kCtapHidInit, data, data.size()); + channel_id, FidoHidDeviceCommand::kInit, data, data.size()); EXPECT_EQ(64u, init_packet->GetSerializedData().size()); auto continuation_packet = @@ -40,7 +40,7 @@ TEST(FidoHidMessageTest, TestPacketData) { uint32_t channel_id = 0xF5060708; std::vector<uint8_t> data{10, 11}; - CtapHidDeviceCommand cmd = CtapHidDeviceCommand::kCtapHidWink; + FidoHidDeviceCommand cmd = FidoHidDeviceCommand::kWink; auto init_packet = std::make_unique<FidoHidInitPacket>(channel_id, cmd, data, data.size()); size_t index = 0; @@ -63,7 +63,7 @@ TEST(FidoHidMessageTest, TestPacketConstructors) { uint32_t channel_id = 0x05060708; std::vector<uint8_t> data{10, 11}; - CtapHidDeviceCommand cmd = CtapHidDeviceCommand::kCtapHidWink; + FidoHidDeviceCommand cmd = FidoHidDeviceCommand::kWink; auto orig_packet = std::make_unique<FidoHidInitPacket>(channel_id, cmd, data, data.size()); @@ -96,8 +96,8 @@ for (size_t i = 0; i < kHidMaxMessageSize; ++i) data.push_back(static_cast<uint8_t>(i % 0xff)); - auto orig_msg = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidMsg, data); + auto orig_msg = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kMsg, data); ASSERT_TRUE(orig_msg); const auto& original_msg_packets = orig_msg->GetPacketsForTesting(); @@ -137,20 +137,20 @@ TEST(FidoHidMessageTest, TestMessagePartitoning) { uint32_t channel_id = 0x01010203; std::vector<uint8_t> data(kHidInitPacketDataSize + 1); - auto two_packet_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto two_packet_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); ASSERT_TRUE(two_packet_message); EXPECT_EQ(2U, two_packet_message->NumPackets()); data.resize(kHidInitPacketDataSize); - auto one_packet_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto one_packet_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); ASSERT_TRUE(one_packet_message); EXPECT_EQ(1U, one_packet_message->NumPackets()); data.resize(kHidInitPacketDataSize + kHidContinuationPacketDataSize + 1); - auto three_packet_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto three_packet_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); ASSERT_TRUE(three_packet_message); EXPECT_EQ(3U, three_packet_message->NumPackets()); } @@ -158,16 +158,16 @@ TEST(FidoHidMessageTest, TestMaxSize) { uint32_t channel_id = 0x00010203; std::vector<uint8_t> data(kHidMaxMessageSize + 1); - auto oversize_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto oversize_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); EXPECT_EQ(nullptr, oversize_message); } TEST(FidoHidMessageTest, TestDeconstruct) { uint32_t channel_id = 0x0A0B0C0D; std::vector<uint8_t> data(kHidMaxMessageSize, 0x7F); - auto filled_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto filled_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); ASSERT_TRUE(filled_message); EXPECT_THAT(data, ::testing::ContainerEq(filled_message->GetMessagePayload())); @@ -177,8 +177,8 @@ uint32_t channel_id = 0x0A0B0C0D; std::vector<uint8_t> data(kHidMaxMessageSize); - auto orig_message = FidoHidMessage::Create( - channel_id, CtapHidDeviceCommand::kCtapHidPing, data); + auto orig_message = + FidoHidMessage::Create(channel_id, FidoHidDeviceCommand::kPing, data); ASSERT_TRUE(orig_message); base::circular_deque<std::vector<uint8_t>> orig_list;
diff --git a/device/fido/fido_hid_packet.cc b/device/fido/fido_hid_packet.cc index 82063ff..10a1cebb 100644 --- a/device/fido/fido_hid_packet.cc +++ b/device/fido/fido_hid_packet.cc
@@ -33,8 +33,8 @@ channel_id |= (serialized[index++] & 0xff) << 8; channel_id |= serialized[index++] & 0xff; - auto command = static_cast<CtapHidDeviceCommand>(serialized[index++] & 0x7f); - if (!base::ContainsValue(GetCtapHidDeviceCommandList(), command)) + auto command = static_cast<FidoHidDeviceCommand>(serialized[index++] & 0x7f); + if (!base::ContainsValue(GetFidoHidDeviceCommandList(), command)) return nullptr; uint16_t payload_size = serialized[index++] << 8; @@ -62,7 +62,7 @@ // 6 1 Low order packet payload size // 7 (s-7) Payload data FidoHidInitPacket::FidoHidInitPacket(uint32_t channel_id, - CtapHidDeviceCommand cmd, + FidoHidDeviceCommand cmd, std::vector<uint8_t> data, uint16_t payload_length) : FidoHidPacket(std::move(data), channel_id),
diff --git a/device/fido/fido_hid_packet.h b/device/fido/fido_hid_packet.h index 4a24865..128f1ed 100644 --- a/device/fido/fido_hid_packet.h +++ b/device/fido/fido_hid_packet.h
@@ -62,17 +62,17 @@ size_t* remaining_size); FidoHidInitPacket(uint32_t channel_id, - CtapHidDeviceCommand cmd, + FidoHidDeviceCommand cmd, std::vector<uint8_t> data, uint16_t payload_length); ~FidoHidInitPacket() final; std::vector<uint8_t> GetSerializedData() const final; - CtapHidDeviceCommand command() const { return command_; } + FidoHidDeviceCommand command() const { return command_; } uint16_t payload_length() const { return payload_length_; } private: - CtapHidDeviceCommand command_; + FidoHidDeviceCommand command_; uint16_t payload_length_; DISALLOW_COPY_AND_ASSIGN(FidoHidInitPacket);
diff --git a/device/fido/mock_u2f_device.cc b/device/fido/mock_u2f_device.cc index 03279a1..77fac1ce 100644 --- a/device/fido/mock_u2f_device.cc +++ b/device/fido/mock_u2f_device.cc
@@ -7,12 +7,12 @@ #include <utility> #include "components/apdu/apdu_response.h" +#include "device/fido/fido_constants.h" #include "device/fido/u2f_response_test_data.h" namespace device { MockU2fDevice::MockU2fDevice() : weak_factory_(this) {} - MockU2fDevice::~MockU2fDevice() = default; void MockU2fDevice::TryWink(WinkCallback cb) { @@ -21,56 +21,70 @@ void MockU2fDevice::DeviceTransact(std::vector<uint8_t> command, DeviceCallback cb) { - DeviceTransactPtr(std::move(command), cb); + DeviceTransactPtr(command, cb); } // static -void MockU2fDevice::NotSatisfied(const std::vector<uint8_t>& cmd, +void MockU2fDevice::NotSatisfied(const std::vector<uint8_t>& command, DeviceCallback& cb) { - std::move(cb).Run( - true, apdu::ApduResponse( - std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED)); + std::move(cb).Run(apdu::ApduResponse( + std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED) + .GetEncodedResponse()); } // static -void MockU2fDevice::WrongData(const std::vector<uint8_t>& cmd, +void MockU2fDevice::WrongData(const std::vector<uint8_t>& command, DeviceCallback& cb) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_DATA)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_DATA) + .GetEncodedResponse()); } // static -void MockU2fDevice::NoErrorSign(const std::vector<uint8_t>& cmd, +void MockU2fDevice::NoErrorSign(const std::vector<uint8_t>& command, DeviceCallback& cb) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>( - std::begin(test_data::kTestU2fSignResponse), - std::end(test_data::kTestU2fSignResponse)), - apdu::ApduResponse::Status::SW_NO_ERROR)); + apdu::ApduResponse( + std::vector<uint8_t>(std::begin(test_data::kTestU2fSignResponse), + std::end(test_data::kTestU2fSignResponse)), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); } // static -void MockU2fDevice::NoErrorRegister(const std::vector<uint8_t>& cmd, +void MockU2fDevice::NoErrorRegister(const std::vector<uint8_t>& command, DeviceCallback& cb) { std::move(cb).Run( - true, apdu::ApduResponse( std::vector<uint8_t>(std::begin(test_data::kTestU2fRegisterResponse), std::end(test_data::kTestU2fRegisterResponse)), - apdu::ApduResponse::Status::SW_NO_ERROR)); + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); } // static -void MockU2fDevice::SignWithCorruptedResponse(const std::vector<uint8_t>& cmd, - DeviceCallback& cb) { +void MockU2fDevice::NoErrorVersion(const std::vector<uint8_t>& command, + DeviceCallback& cb) { std::move(cb).Run( - true, apdu::ApduResponse( - std::vector<uint8_t>( - std::begin(test_data::kTestCorruptedU2fSignResponse), - std::end(test_data::kTestCorruptedU2fSignResponse)), - apdu::ApduResponse::Status::SW_NO_ERROR)); + apdu::ApduResponse(std::vector<uint8_t>(kU2fVersionResponse.cbegin(), + kU2fVersionResponse.cend()), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); +} + +// static +void MockU2fDevice::SignWithCorruptedResponse( + const std::vector<uint8_t>& command, + DeviceCallback& cb) { + std::move(cb).Run( + apdu::ApduResponse( + std::vector<uint8_t>( + std::begin(test_data::kTestCorruptedU2fSignResponse), + std::end(test_data::kTestCorruptedU2fSignResponse)), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); } // static
diff --git a/device/fido/mock_u2f_device.h b/device/fido/mock_u2f_device.h index cf7ffa8..0302b37 100644 --- a/device/fido/mock_u2f_device.h +++ b/device/fido/mock_u2f_device.h
@@ -33,11 +33,10 @@ // TODO(crbug.com/729950): Remove these workarounds once support for move-only // types is added to GMock. MOCK_METHOD2(DeviceTransactPtr, - void(std::vector<uint8_t> command, DeviceCallback& cb)); + void(const std::vector<uint8_t>& command, DeviceCallback& cb)); void DeviceTransact(std::vector<uint8_t> command, DeviceCallback cb) override; + base::WeakPtr<U2fDevice> GetWeakPtr() override; - static void TransactNoError(const std::vector<uint8_t>& command, - DeviceCallback cb); static void NotSatisfied(const std::vector<uint8_t>& command, DeviceCallback& cb); static void WrongData(const std::vector<uint8_t>& command, @@ -46,6 +45,8 @@ DeviceCallback& cb); static void NoErrorRegister(const std::vector<uint8_t>& command, DeviceCallback& cb); + static void NoErrorVersion(const std::vector<uint8_t>& command, + DeviceCallback& cb); static void SignWithCorruptedResponse(const std::vector<uint8_t>& command, DeviceCallback& cb); static void WinkDoNothing(WinkCallback& cb);
diff --git a/device/fido/u2f_ble_connection.cc b/device/fido/u2f_ble_connection.cc index 0e8a13a..d0f500c1 100644 --- a/device/fido/u2f_ble_connection.cc +++ b/device/fido/u2f_ble_connection.cc
@@ -16,7 +16,7 @@ #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" #include "device/bluetooth/bluetooth_remote_gatt_service.h" #include "device/bluetooth/bluetooth_uuid.h" -#include "device/fido/u2f_ble_uuids.h" +#include "device/fido/fido_ble_uuids.h" namespace device { @@ -317,7 +317,7 @@ device->GetGattServices(); auto found = std::find_if(services.begin(), services.end(), [](const auto* service) { - return service->GetUUID().canonical_value() == kU2fServiceUUID; + return service->GetUUID().canonical_value() == kFidoServiceUUID; }); if (found == services.end()) { @@ -334,19 +334,19 @@ // NOTE: Since GetUUID() returns a temporary |uuid| can't be a reference, // even though canonical_value() returns a const reference. const std::string uuid = characteristic->GetUUID().canonical_value(); - if (uuid == kU2fControlPointLengthUUID) { + if (uuid == kFidoControlPointLengthUUID) { control_point_length_id_ = characteristic->GetIdentifier(); DVLOG(2) << "Got U2F Control Point Length: " << *control_point_length_id_; - } else if (uuid == kU2fControlPointUUID) { + } else if (uuid == kFidoControlPointUUID) { control_point_id_ = characteristic->GetIdentifier(); DVLOG(2) << "Got U2F Control Point: " << *control_point_id_; - } else if (uuid == kU2fStatusUUID) { + } else if (uuid == kFidoStatusUUID) { status_id_ = characteristic->GetIdentifier(); DVLOG(2) << "Got U2F Status: " << *status_id_; - } else if (uuid == kU2fServiceRevisionUUID) { + } else if (uuid == kFidoServiceRevisionUUID) { service_revision_id_ = characteristic->GetIdentifier(); DVLOG(2) << "Got U2F Service Revision: " << *service_revision_id_; - } else if (uuid == kU2fServiceRevisionBitfieldUUID) { + } else if (uuid == kFidoServiceRevisionBitfieldUUID) { service_revision_bitfield_id_ = characteristic->GetIdentifier(); DVLOG(2) << "Got U2F Service Revision Bitfield: " << *service_revision_bitfield_id_;
diff --git a/device/fido/u2f_ble_connection_unittest.cc b/device/fido/u2f_ble_connection_unittest.cc index 7b28877..2de3665 100644 --- a/device/fido/u2f_ble_connection_unittest.cc +++ b/device/fido/u2f_ble_connection_unittest.cc
@@ -19,7 +19,7 @@ #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h" #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h" #include "device/bluetooth/test/mock_bluetooth_gatt_service.h" -#include "device/fido/u2f_ble_uuids.h" +#include "device/fido/fido_ble_uuids.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -332,7 +332,7 @@ void AddU2fService() { auto u2f_service = std::make_unique<NiceMockBluetoothGattService>( - u2f_device_, "u2f_service", BluetoothUUID(kU2fServiceUUID), + u2f_device_, "u2f_service", BluetoothUUID(kFidoServiceUUID), /* is_primary */ true, /* is_local */ false); u2f_service_ = u2f_service.get(); u2f_device_->AddMockService(std::move(u2f_service)); @@ -353,7 +353,7 @@ auto u2f_control_point = std::make_unique<NiceMockBluetoothGattCharacteristic>( u2f_service_, "u2f_control_point", - BluetoothUUID(kU2fControlPointUUID), is_local, + BluetoothUUID(kFidoControlPointUUID), is_local, BluetoothGattCharacteristic::PROPERTY_WRITE, BluetoothGattCharacteristic::PERMISSION_NONE); u2f_control_point_ = u2f_control_point.get(); @@ -362,7 +362,7 @@ { auto u2f_status = std::make_unique<NiceMockBluetoothGattCharacteristic>( - u2f_service_, "u2f_status", BluetoothUUID(kU2fStatusUUID), is_local, + u2f_service_, "u2f_status", BluetoothUUID(kFidoStatusUUID), is_local, BluetoothGattCharacteristic::PROPERTY_NOTIFY, BluetoothGattCharacteristic::PERMISSION_NONE); u2f_status_ = u2f_status.get(); @@ -373,7 +373,7 @@ auto u2f_control_point_length = std::make_unique<NiceMockBluetoothGattCharacteristic>( u2f_service_, "u2f_control_point_length", - BluetoothUUID(kU2fControlPointLengthUUID), is_local, + BluetoothUUID(kFidoControlPointLengthUUID), is_local, BluetoothGattCharacteristic::PROPERTY_READ, BluetoothGattCharacteristic::PERMISSION_NONE); u2f_control_point_length_ = u2f_control_point_length.get(); @@ -384,7 +384,7 @@ auto u2f_service_revision = std::make_unique<NiceMockBluetoothGattCharacteristic>( u2f_service_, "u2f_service_revision", - BluetoothUUID(kU2fServiceRevisionUUID), is_local, + BluetoothUUID(kFidoServiceRevisionUUID), is_local, BluetoothGattCharacteristic::PROPERTY_READ, BluetoothGattCharacteristic::PERMISSION_NONE); u2f_service_revision_ = u2f_service_revision.get(); @@ -395,7 +395,7 @@ auto u2f_service_revision_bitfield = std::make_unique<NiceMockBluetoothGattCharacteristic>( u2f_service_, "u2f_service_revision_bitfield", - BluetoothUUID(kU2fServiceRevisionBitfieldUUID), is_local, + BluetoothUUID(kFidoServiceRevisionBitfieldUUID), is_local, BluetoothGattCharacteristic::PROPERTY_READ | BluetoothGattCharacteristic::PROPERTY_WRITE, BluetoothGattCharacteristic::PERMISSION_NONE);
diff --git a/device/fido/u2f_ble_device.cc b/device/fido/u2f_ble_device.cc index 468843e..0dc9a38 100644 --- a/device/fido/u2f_ble_device.cc +++ b/device/fido/u2f_ble_device.cc
@@ -27,23 +27,22 @@ U2fBleDevice::~U2fBleDevice() = default; void U2fBleDevice::Connect() { - if (state_ != State::INIT) + if (state_ != State::kInit) return; StartTimeout(); - state_ = State::BUSY; + state_ = State::kBusy; connection_->Connect(); } void U2fBleDevice::SendPing(std::vector<uint8_t> data, - MessageCallback callback) { + DeviceCallback callback) { pending_frames_.emplace( - U2fBleFrame(U2fCommandType::CMD_PING, std::move(data)), + U2fBleFrame(FidoBleDeviceCommand::kPing, std::move(data)), base::BindOnce( - [](MessageCallback callback, base::Optional<U2fBleFrame> frame) { - std::move(callback).Run( - frame ? U2fReturnCode::SUCCESS : U2fReturnCode::FAILURE, - frame ? frame->data() : std::vector<uint8_t>()); + [](DeviceCallback callback, base::Optional<U2fBleFrame> frame) { + std::move(callback).Run(frame ? base::make_optional(frame->data()) + : base::nullopt); }, std::move(callback))); Transition(); @@ -77,13 +76,11 @@ void U2fBleDevice::DeviceTransact(std::vector<uint8_t> command, DeviceCallback callback) { pending_frames_.emplace( - U2fBleFrame(U2fCommandType::CMD_MSG, std::move(command)), + U2fBleFrame(FidoBleDeviceCommand::kMsg, std::move(command)), base::BindOnce( [](DeviceCallback callback, base::Optional<U2fBleFrame> frame) { - std::move(callback).Run( - frame.has_value(), - frame ? apdu::ApduResponse::CreateFromMessage(frame->data()) - : base::nullopt); + std::move(callback).Run(frame ? base::make_optional(frame->data()) + : base::nullopt); }, std::move(callback))); Transition(); @@ -95,16 +92,16 @@ void U2fBleDevice::Transition() { switch (state_) { - case State::INIT: + case State::kInit: Connect(); break; - case State::CONNECTED: + case State::kConnected: StartTimeout(); - state_ = State::BUSY; + state_ = State::kBusy; connection_->ReadControlPointLength(base::BindOnce( &U2fBleDevice::OnReadControlPointLength, base::Unretained(this))); break; - case State::READY: + case State::kReady: if (!pending_frames_.empty()) { U2fBleFrame frame; FrameCallback callback; @@ -113,9 +110,9 @@ SendRequestFrame(std::move(frame), std::move(callback)); } break; - case State::BUSY: + case State::kBusy: break; - case State::DEVICE_ERROR: + case State::kDeviceError: auto self = GetWeakPtr(); // Executing callbacks may free |this|. Check |self| first. while (self && !pending_frames_.empty()) { @@ -130,7 +127,7 @@ void U2fBleDevice::OnConnectionStatus(bool success) { StopTimeout(); - state_ = success ? State::CONNECTED : State::DEVICE_ERROR; + state_ = success ? State::kConnected : State::kDeviceError; Transition(); } @@ -138,9 +135,9 @@ StopTimeout(); if (length) { transaction_.emplace(connection_.get(), *length); - state_ = State::READY; + state_ = State::kReady; } else { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; } Transition(); } @@ -151,7 +148,7 @@ } void U2fBleDevice::SendRequestFrame(U2fBleFrame frame, FrameCallback callback) { - state_ = State::BUSY; + state_ = State::kBusy; transaction_->WriteRequestFrame( std::move(frame), base::BindOnce(&U2fBleDevice::OnResponseFrame, base::Unretained(this), @@ -160,7 +157,7 @@ void U2fBleDevice::OnResponseFrame(FrameCallback callback, base::Optional<U2fBleFrame> frame) { - state_ = frame ? State::READY : State::DEVICE_ERROR; + state_ = frame ? State::kReady : State::kDeviceError; auto self = GetWeakPtr(); std::move(callback).Run(std::move(frame)); // Executing callbacks may free |this|. Check |self| first. @@ -169,8 +166,7 @@ } void U2fBleDevice::StartTimeout() { - timer_.Start(FROM_HERE, U2fDevice::kDeviceTimeout, this, - &U2fBleDevice::OnTimeout); + timer_.Start(FROM_HERE, kDeviceTimeout, this, &U2fBleDevice::OnTimeout); } void U2fBleDevice::StopTimeout() { @@ -178,7 +174,7 @@ } void U2fBleDevice::OnTimeout() { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; } } // namespace device
diff --git a/device/fido/u2f_ble_device.h b/device/fido/u2f_ble_device.h index a9409fc9..06ada63 100644 --- a/device/fido/u2f_ble_device.h +++ b/device/fido/u2f_ble_device.h
@@ -17,6 +17,7 @@ #include "base/optional.h" #include "base/strings/string_piece.h" #include "base/timer/timer.h" +#include "device/fido/fido_constants.h" #include "device/fido/u2f_ble_connection.h" #include "device/fido/u2f_ble_transaction.h" #include "device/fido/u2f_device.h" @@ -33,7 +34,7 @@ ~U2fBleDevice() override; void Connect(); - void SendPing(std::vector<uint8_t> data, MessageCallback callback); + void SendPing(std::vector<uint8_t> data, DeviceCallback callback); static std::string GetId(base::StringPiece address); // U2fDevice: @@ -51,10 +52,6 @@ base::WeakPtr<U2fDevice> GetWeakPtr() override; private: - // INIT --> BUSY --> CONNECTED --> BUSY <--> READY. - // DEVICE_ERROR persists. - enum class State { INIT, CONNECTED, READY, BUSY, DEVICE_ERROR }; - void Transition(); void OnConnectionStatus(bool success); @@ -72,7 +69,7 @@ void StopTimeout(); void OnTimeout(); - State state_ = State::INIT; + State state_ = State::kInit; base::OneShotTimer timer_; std::unique_ptr<U2fBleConnection> connection_;
diff --git a/device/fido/u2f_ble_device_unittest.cc b/device/fido/u2f_ble_device_unittest.cc index 94a62c9..f89a7fe 100644 --- a/device/fido/u2f_ble_device_unittest.cc +++ b/device/fido/u2f_ble_device_unittest.cc
@@ -18,9 +18,8 @@ using ::testing::_; using ::testing::Invoke; using ::testing::Test; -using TestMessageCallbackReceiver = - test::StatusAndValueCallbackReceiver<U2fReturnCode, - const std::vector<uint8_t>&>; +using TestDeviceCallbackReceiver = + test::TestCallbackReceiver<base::Optional<std::vector<uint8_t>>>; } // namespace @@ -73,12 +72,11 @@ .WillOnce(Invoke( [this](const auto& data, auto* cb) { std::move(*cb).Run(false); })); - TestMessageCallbackReceiver callback_receiver; + TestDeviceCallbackReceiver callback_receiver; device()->SendPing({'T', 'E', 'S', 'T'}, callback_receiver.callback()); callback_receiver.WaitForCallback(); - EXPECT_EQ(U2fReturnCode::FAILURE, callback_receiver.status()); - EXPECT_EQ(std::vector<uint8_t>(), callback_receiver.value()); + EXPECT_FALSE(std::get<0>(*callback_receiver.result())); } TEST_F(U2fBleDeviceTest, SendPingTest_Failure_Timeout) { @@ -86,15 +84,14 @@ EXPECT_CALL(*connection(), WriteControlPointPtr(_, _)) .WillOnce(Invoke([this](const auto& data, auto* cb) { - scoped_task_environment_.FastForwardBy(U2fDevice::kDeviceTimeout); + scoped_task_environment_.FastForwardBy(kDeviceTimeout); })); - TestMessageCallbackReceiver callback_receiver; + TestDeviceCallbackReceiver callback_receiver; device()->SendPing({'T', 'E', 'S', 'T'}, callback_receiver.callback()); callback_receiver.WaitForCallback(); - EXPECT_EQ(U2fReturnCode::FAILURE, callback_receiver.status()); - EXPECT_EQ(std::vector<uint8_t>(), callback_receiver.value()); + EXPECT_FALSE(std::get<0>(*callback_receiver.result())); } TEST_F(U2fBleDeviceTest, SendPingTest) { @@ -104,18 +101,19 @@ EXPECT_CALL(*connection(), WriteControlPointPtr(_, _)) .WillOnce(Invoke([this](const auto& data, auto* cb) { auto almost_time_out = - U2fDevice::kDeviceTimeout - base::TimeDelta::FromMicroseconds(1); + kDeviceTimeout - base::TimeDelta::FromMicroseconds(1); scoped_task_environment_.FastForwardBy(almost_time_out); connection()->read_callback().Run(data); std::move(*cb).Run(true); })); - TestMessageCallbackReceiver callback_receiver; + TestDeviceCallbackReceiver callback_receiver; device()->SendPing(ping_data, callback_receiver.callback()); callback_receiver.WaitForCallback(); - EXPECT_EQ(U2fReturnCode::SUCCESS, callback_receiver.status()); - EXPECT_EQ(ping_data, callback_receiver.value()); + const auto& result = std::get<0>(*callback_receiver.result()); + ASSERT_TRUE(result); + EXPECT_EQ(ping_data, *result); } TEST_F(U2fBleDeviceTest, StaticGetIdTest) {
diff --git a/device/fido/u2f_ble_discovery.cc b/device/fido/u2f_ble_discovery.cc index c8fc158..67d3b0a 100644 --- a/device/fido/u2f_ble_discovery.cc +++ b/device/fido/u2f_ble_discovery.cc
@@ -15,8 +15,8 @@ #include "device/bluetooth/bluetooth_discovery_filter.h" #include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/fido/fido_ble_uuids.h" #include "device/fido/u2f_ble_device.h" -#include "device/fido/u2f_ble_uuids.h" namespace device { @@ -55,7 +55,7 @@ // static const BluetoothUUID& U2fBleDiscovery::U2fServiceUUID() { - static const BluetoothUUID service_uuid(kU2fServiceUUID); + static const BluetoothUUID service_uuid(kFidoServiceUUID); return service_uuid; }
diff --git a/device/fido/u2f_ble_frames.cc b/device/fido/u2f_ble_frames.cc index c36135138..9720acf 100644 --- a/device/fido/u2f_ble_frames.cc +++ b/device/fido/u2f_ble_frames.cc
@@ -9,12 +9,14 @@ #include "base/logging.h" #include "base/numerics/safe_conversions.h" +#include "device/fido/fido_constants.h" namespace device { U2fBleFrame::U2fBleFrame() = default; -U2fBleFrame::U2fBleFrame(U2fCommandType command, std::vector<uint8_t> data) +U2fBleFrame::U2fBleFrame(FidoBleDeviceCommand command, + std::vector<uint8_t> data) : command_(command), data_(std::move(data)) {} U2fBleFrame::U2fBleFrame(U2fBleFrame&&) = default; @@ -24,26 +26,26 @@ bool U2fBleFrame::IsValid() const { switch (command_) { - case U2fCommandType::CMD_PING: - case U2fCommandType::CMD_MSG: + case FidoBleDeviceCommand::kPing: + case FidoBleDeviceCommand::kMsg: + case FidoBleDeviceCommand::kCancel: return true; - case U2fCommandType::CMD_KEEPALIVE: - case U2fCommandType::CMD_ERROR: + case FidoBleDeviceCommand::kKeepAlive: + case FidoBleDeviceCommand::kError: return data_.size() == 1; - case U2fCommandType::UNDEFINED: - default: - return false; } + NOTREACHED(); + return false; } U2fBleFrame::KeepaliveCode U2fBleFrame::GetKeepaliveCode() const { - DCHECK_EQ(command_, U2fCommandType::CMD_KEEPALIVE); + DCHECK_EQ(command_, FidoBleDeviceCommand::kKeepAlive); DCHECK_EQ(data_.size(), 1u); return static_cast<KeepaliveCode>(data_[0]); } U2fBleFrame::ErrorCode U2fBleFrame::GetErrorCode() const { - DCHECK_EQ(command_, U2fCommandType::CMD_ERROR); + DCHECK_EQ(command_, FidoBleDeviceCommand::kError); DCHECK_EQ(data_.size(), 1u); return static_cast<ErrorCode>(data_[0]); } @@ -97,7 +99,7 @@ if (data.size() < 3) return false; - const auto command = static_cast<U2fCommandType>(data[0]); + const auto command = static_cast<FidoBleDeviceCommand>(data[0]); const uint16_t data_length = (static_cast<uint16_t>(data[1]) << 8) + data[2]; if (static_cast<size_t>(data_length) + 3 < data.size()) return false;
diff --git a/device/fido/u2f_ble_frames.h b/device/fido/u2f_ble_frames.h index 5667942..0b744647 100644 --- a/device/fido/u2f_ble_frames.h +++ b/device/fido/u2f_ble_frames.h
@@ -14,7 +14,7 @@ #include "base/containers/queue.h" #include "base/containers/span.h" #include "base/macros.h" -#include "device/fido/u2f_command_type.h" +#include "device/fido/fido_constants.h" namespace device { @@ -56,14 +56,14 @@ }; U2fBleFrame(); - U2fBleFrame(U2fCommandType command, std::vector<uint8_t> data); + U2fBleFrame(FidoBleDeviceCommand command, std::vector<uint8_t> data); U2fBleFrame(U2fBleFrame&&); U2fBleFrame& operator=(U2fBleFrame&&); ~U2fBleFrame(); - U2fCommandType command() const { return command_; } + FidoBleDeviceCommand command() const { return command_; } bool IsValid() const; KeepaliveCode GetKeepaliveCode() const; @@ -83,7 +83,7 @@ ToFragments(size_t max_fragment_size) const; private: - U2fCommandType command_ = U2fCommandType::UNDEFINED; + FidoBleDeviceCommand command_ = FidoBleDeviceCommand::kMsg; std::vector<uint8_t> data_; DISALLOW_COPY_AND_ASSIGN(U2fBleFrame); @@ -121,20 +121,20 @@ U2fBleFrameInitializationFragment* fragment); U2fBleFrameInitializationFragment() = default; - U2fBleFrameInitializationFragment(U2fCommandType command, + U2fBleFrameInitializationFragment(FidoBleDeviceCommand command, uint16_t data_length, base::span<const uint8_t> fragment) : U2fBleFrameFragment(fragment), command_(command), data_length_(data_length) {} - U2fCommandType command() const { return command_; } + FidoBleDeviceCommand command() const { return command_; } uint16_t data_length() const { return data_length_; } size_t Serialize(std::vector<uint8_t>* buffer) const override; private: - U2fCommandType command_ = U2fCommandType::UNDEFINED; + FidoBleDeviceCommand command_ = FidoBleDeviceCommand::kMsg; uint16_t data_length_ = 0; };
diff --git a/device/fido/u2f_ble_frames_fuzzer.cc b/device/fido/u2f_ble_frames_fuzzer.cc index 772a7e6..adb5e08 100644 --- a/device/fido/u2f_ble_frames_fuzzer.cc +++ b/device/fido/u2f_ble_frames_fuzzer.cc
@@ -7,8 +7,8 @@ #include <vector> +#include "device/fido/fido_constants.h" #include "device/fido/u2f_ble_frames.h" -#include "device/fido/u2f_command_type.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* raw_data, size_t size) { auto data_span = base::make_span(raw_data, size); @@ -16,7 +16,7 @@ { device::U2fBleFrameInitializationFragment fragment( - device::U2fCommandType::CMD_MSG, 21123, data_span); + device::FidoBleDeviceCommand::kMsg, 21123, data_span); std::vector<uint8_t> buffer; fragment.Serialize(&buffer); @@ -42,7 +42,7 @@ } { - device::U2fBleFrame frame(device::U2fCommandType::CMD_PING, data); + device::U2fBleFrame frame(device::FidoBleDeviceCommand::kPing, data); auto fragments = frame.ToFragments(20); device::U2fBleFrameAssembler assembler(fragments.first);
diff --git a/device/fido/u2f_ble_frames_unittest.cc b/device/fido/u2f_ble_frames_unittest.cc index 5b2757c..4ee467e 100644 --- a/device/fido/u2f_ble_frames_unittest.cc +++ b/device/fido/u2f_ble_frames_unittest.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "device/fido/u2f_command_type.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -27,7 +26,7 @@ constexpr uint16_t kDataLength = 21123; U2fBleFrameInitializationFragment fragment( - U2fCommandType::CMD_MSG, kDataLength, base::make_span(data)); + FidoBleDeviceCommand::kMsg, kDataLength, base::make_span(data)); std::vector<uint8_t> buffer; const size_t binary_size = fragment.Serialize(&buffer); @@ -41,7 +40,7 @@ EXPECT_EQ(kDataLength, parsed_fragment.data_length()); EXPECT_EQ(base::make_span(data), parsed_fragment.fragment()); - EXPECT_EQ(U2fCommandType::CMD_MSG, parsed_fragment.command()); + EXPECT_EQ(FidoBleDeviceCommand::kMsg, parsed_fragment.command()); } TEST(U2fBleFramesTest, ContinuationFragment) { @@ -68,7 +67,7 @@ 37, 39, 40, 41, 54, 55, 56, 60, 100, 65535}) { SCOPED_TRACE(size); - U2fBleFrame frame(U2fCommandType::CMD_PING, GetSomeData(size)); + U2fBleFrame frame(FidoBleDeviceCommand::kPing, GetSomeData(size)); auto fragments = frame.ToFragments(20); @@ -92,7 +91,7 @@ } TEST(U2fBleFramesTest, FrameAssemblerError) { - U2fBleFrame frame(U2fCommandType::CMD_PING, GetSomeData(30)); + U2fBleFrame frame(FidoBleDeviceCommand::kPing, GetSomeData(30)); auto fragments = frame.ToFragments(20); ASSERT_EQ(1u, fragments.second.size()); @@ -110,17 +109,18 @@ TEST(U2fBleFramesTest, FrameGettersAndValidity) { { - U2fBleFrame frame(U2fCommandType::CMD_KEEPALIVE, std::vector<uint8_t>(2)); + U2fBleFrame frame(FidoBleDeviceCommand::kKeepAlive, + std::vector<uint8_t>(2)); EXPECT_FALSE(frame.IsValid()); } { - U2fBleFrame frame(U2fCommandType::CMD_ERROR, {}); + U2fBleFrame frame(FidoBleDeviceCommand::kError, {}); EXPECT_FALSE(frame.IsValid()); } for (auto code : {U2fBleFrame::KeepaliveCode::TUP_NEEDED, U2fBleFrame::KeepaliveCode::PROCESSING}) { - U2fBleFrame frame(U2fCommandType::CMD_KEEPALIVE, + U2fBleFrame frame(FidoBleDeviceCommand::kKeepAlive, std::vector<uint8_t>(1, static_cast<uint8_t>(code))); EXPECT_TRUE(frame.IsValid()); EXPECT_EQ(code, frame.GetKeepaliveCode()); @@ -134,7 +134,8 @@ U2fBleFrame::ErrorCode::REQ_TIMEOUT, U2fBleFrame::ErrorCode::NA_1, U2fBleFrame::ErrorCode::NA_2, U2fBleFrame::ErrorCode::NA_3, }) { - U2fBleFrame frame(U2fCommandType::CMD_ERROR, {static_cast<uint8_t>(code)}); + U2fBleFrame frame(FidoBleDeviceCommand::kError, + {static_cast<uint8_t>(code)}); EXPECT_TRUE(frame.IsValid()); EXPECT_EQ(code, frame.GetErrorCode()); }
diff --git a/device/fido/u2f_ble_transaction.cc b/device/fido/u2f_ble_transaction.cc index 0c8b1d5..aa12b94 100644 --- a/device/fido/u2f_ble_transaction.cc +++ b/device/fido/u2f_ble_transaction.cc
@@ -106,7 +106,7 @@ return; } - if (response_frame.command() == U2fCommandType::CMD_KEEPALIVE) { + if (response_frame.command() == FidoBleDeviceCommand::kKeepAlive) { DVLOG(2) << "CMD_KEEPALIVE: " << static_cast<uint8_t>(response_frame.GetKeepaliveCode()); // Expect another reponse frame soon. @@ -114,15 +114,14 @@ return; } - DCHECK_EQ(response_frame.command(), U2fCommandType::CMD_ERROR); + DCHECK_EQ(response_frame.command(), FidoBleDeviceCommand::kError); DLOG(ERROR) << "CMD_ERROR: " << static_cast<uint8_t>(response_frame.GetErrorCode()); OnError(); } void U2fBleTransaction::StartTimeout() { - timer_.Start(FROM_HERE, U2fDevice::kDeviceTimeout, this, - &U2fBleTransaction::OnError); + timer_.Start(FROM_HERE, kDeviceTimeout, this, &U2fBleTransaction::OnError); } void U2fBleTransaction::StopTimeout() {
diff --git a/device/fido/u2f_ble_uuids.cc b/device/fido/u2f_ble_uuids.cc deleted file mode 100644 index d8188a8..0000000 --- a/device/fido/u2f_ble_uuids.cc +++ /dev/null
@@ -1,18 +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 "device/fido/u2f_ble_uuids.h" - -namespace device { - -const char kU2fServiceUUID[] = "0000fffd-0000-1000-8000-00805f9b34fb"; -const char kU2fControlPointUUID[] = "f1d0fff1-deaa-ecee-b42f-c9ba7ed623bb"; -const char kU2fStatusUUID[] = "f1d0fff2-deaa-ecee-b42f-c9ba7ed623bb"; -const char kU2fControlPointLengthUUID[] = - "f1d0fff3-deaa-ecee-b42f-c9ba7ed623bb"; -const char kU2fServiceRevisionUUID[] = "00002a28-0000-1000-8000-00805f9b34fb"; -const char kU2fServiceRevisionBitfieldUUID[] = - "f1d0fff4-deaa-ecee-b42f-c9ba7ed623bb"; - -} // namespace device
diff --git a/device/fido/u2f_ble_uuids.h b/device/fido/u2f_ble_uuids.h deleted file mode 100644 index 919d617..0000000 --- a/device/fido/u2f_ble_uuids.h +++ /dev/null
@@ -1,28 +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. - -#ifndef DEVICE_FIDO_U2F_BLE_UUIDS_H_ -#define DEVICE_FIDO_U2F_BLE_UUIDS_H_ - -#include "base/component_export.h" - -namespace device { - -// U2F GATT Service's UUIDs as defined by the standard: -// https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-bt-protocol-v1.2-ps-20170411.html#h3_u2f-service -// -// For details on how the short UUIDs for U2F Service (0xFFFD) and U2F Service -// Revision (0x2A28) were converted to the long canonical ones, see -// https://www.bluetooth.com/specifications/assigned-numbers/service-discovery -COMPONENT_EXPORT(DEVICE_FIDO) extern const char kU2fServiceUUID[]; -COMPONENT_EXPORT(DEVICE_FIDO) extern const char kU2fControlPointUUID[]; -COMPONENT_EXPORT(DEVICE_FIDO) extern const char kU2fStatusUUID[]; -COMPONENT_EXPORT(DEVICE_FIDO) extern const char kU2fControlPointLengthUUID[]; -COMPONENT_EXPORT(DEVICE_FIDO) extern const char kU2fServiceRevisionUUID[]; -COMPONENT_EXPORT(DEVICE_FIDO) -extern const char kU2fServiceRevisionBitfieldUUID[]; - -} // namespace device - -#endif // DEVICE_FIDO_U2F_BLE_UUIDS_H_
diff --git a/device/fido/u2f_command_type.h b/device/fido/u2f_command_type.h deleted file mode 100644 index 26811e6..0000000 --- a/device/fido/u2f_command_type.h +++ /dev/null
@@ -1,44 +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. - -#ifndef DEVICE_FIDO_U2F_COMMAND_TYPE_H_ -#define DEVICE_FIDO_U2F_COMMAND_TYPE_H_ - -#include <stdint.h> - -namespace device { - -// The type of a command that can be sent either to or from a U2F authenticator, -// i.e. a request or a response. -// -// Each request sent to a device results in a response of *the same* type sent -// back, unless there was an error in which case a CMD_ERROR is returned. -enum class U2fCommandType : uint8_t { - UNDEFINED = 0x00, - - // Sends arbitrary data to the device which echoes the same data back. - CMD_PING = 0x81, - - // Authenticator sends this in response to requests that it could not process - // within a time limit. The client should take action appropriate to the - // message reason (e.g., notify the user to perform a test-of-user-presence), - // and wait for the next message. - CMD_KEEPALIVE = 0x82, - - // Encapsulates a U2F protocol raw message. - CMD_MSG = 0x83, - - // Requests a unique channel from a USB/HID device. - CMD_INIT = 0x86, - - // Instructs a USB/HID authenticator to show the user that it is active. - CMD_WINK = 0x88, - - // Used as a response in case an error occurs during a request. - CMD_ERROR = 0xBF, -}; - -} // namespace device - -#endif // DEVICE_FIDO_U2F_COMMAND_TYPE_H_
diff --git a/device/fido/u2f_device.cc b/device/fido/u2f_device.cc index afafc571..eb75a59 100644 --- a/device/fido/u2f_device.cc +++ b/device/fido/u2f_device.cc
@@ -4,120 +4,9 @@ #include "device/fido/u2f_device.h" -#include <utility> - -#include "base/bind.h" -#include "components/apdu/apdu_command.h" -#include "device/fido/u2f_request.h" - namespace device { -constexpr base::TimeDelta U2fDevice::kDeviceTimeout; - U2fDevice::U2fDevice() = default; - U2fDevice::~U2fDevice() = default; -void U2fDevice::Register(base::Optional<std::vector<uint8_t>> register_cmd, - MessageCallback callback) { - if (!register_cmd) { - std::move(callback).Run(U2fReturnCode::INVALID_PARAMS, - std::vector<uint8_t>()); - return; - } - DeviceTransact(std::move(*register_cmd), - base::BindOnce(&U2fDevice::OnRegisterComplete, GetWeakPtr(), - std::move(callback))); -} - -void U2fDevice::Sign(base::Optional<std::vector<uint8_t>> sign_cmd, - MessageCallback callback) { - if (!sign_cmd) { - std::move(callback).Run(U2fReturnCode::INVALID_PARAMS, - std::vector<uint8_t>()); - return; - } - DeviceTransact(std::move(*sign_cmd), - base::BindOnce(&U2fDevice::OnSignComplete, GetWeakPtr(), - std::move(callback))); -} - -void U2fDevice::Version(VersionCallback callback) { - DeviceTransact(U2fRequest::GetU2fVersionApduCommand(), - base::BindOnce(&U2fDevice::OnVersionComplete, GetWeakPtr(), - std::move(callback), false /* legacy */)); -} - -void U2fDevice::OnRegisterComplete( - MessageCallback callback, - bool success, - base::Optional<apdu::ApduResponse> register_response) { - if (!success || !register_response) { - std::move(callback).Run(U2fReturnCode::FAILURE, std::vector<uint8_t>()); - return; - } - switch (register_response->status()) { - case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: - std::move(callback).Run(U2fReturnCode::CONDITIONS_NOT_SATISFIED, - std::vector<uint8_t>()); - break; - case apdu::ApduResponse::Status::SW_NO_ERROR: - std::move(callback).Run(U2fReturnCode::SUCCESS, - register_response->data()); - break; - case apdu::ApduResponse::Status::SW_WRONG_DATA: - std::move(callback).Run(U2fReturnCode::INVALID_PARAMS, - std::vector<uint8_t>()); - break; - default: - std::move(callback).Run(U2fReturnCode::FAILURE, std::vector<uint8_t>()); - break; - } -} - -void U2fDevice::OnSignComplete( - MessageCallback callback, - bool success, - base::Optional<apdu::ApduResponse> sign_response) { - if (!success || !sign_response) { - std::move(callback).Run(U2fReturnCode::FAILURE, std::vector<uint8_t>()); - return; - } - switch (sign_response->status()) { - case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: - std::move(callback).Run(U2fReturnCode::CONDITIONS_NOT_SATISFIED, - std::vector<uint8_t>()); - break; - case apdu::ApduResponse::Status::SW_NO_ERROR: - std::move(callback).Run(U2fReturnCode::SUCCESS, sign_response->data()); - break; - case apdu::ApduResponse::Status::SW_WRONG_DATA: - case apdu::ApduResponse::Status::SW_WRONG_LENGTH: - default: - std::move(callback).Run(U2fReturnCode::INVALID_PARAMS, - std::vector<uint8_t>()); - break; - } -} - -void U2fDevice::OnVersionComplete( - VersionCallback callback, - bool legacy, - bool success, - base::Optional<apdu::ApduResponse> version_response) { - if (success && version_response && - version_response->status() == apdu::ApduResponse::Status::SW_NO_ERROR && - version_response->data() == - std::vector<uint8_t>({'U', '2', 'F', '_', 'V', '2'})) { - std::move(callback).Run(success, ProtocolVersion::U2F_V2); - } else if (!legacy) { - // Standard GetVersion failed, attempt legacy GetVersion command. - DeviceTransact(U2fRequest::GetU2fVersionApduCommand(true /* legacy */), - base::BindOnce(&U2fDevice::OnVersionComplete, GetWeakPtr(), - std::move(callback), true /* legacy */)); - } else { - std::move(callback).Run(success, ProtocolVersion::UNKNOWN); - } -} - } // namespace device
diff --git a/device/fido/u2f_device.h b/device/fido/u2f_device.h index 25c386f..6065e05 100644 --- a/device/fido/u2f_device.h +++ b/device/fido/u2f_device.h
@@ -5,7 +5,8 @@ #ifndef DEVICE_FIDO_U2F_DEVICE_H_ #define DEVICE_FIDO_U2F_DEVICE_H_ -#include <memory> +#include <stdint.h> + #include <string> #include <vector> @@ -14,8 +15,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "components/apdu/apdu_response.h" -#include "device/fido/u2f_return_code.h" +#include "base/time/time.h" namespace device { @@ -23,56 +23,24 @@ // standardized Register, Sign, and GetVersion methods. class COMPONENT_EXPORT(DEVICE_FIDO) U2fDevice { public: - enum class ProtocolVersion { - U2F_V2, - UNKNOWN, - }; - - using MessageCallback = - base::OnceCallback<void(U2fReturnCode, const std::vector<uint8_t>&)>; - using VersionCallback = - base::OnceCallback<void(bool success, ProtocolVersion version)>; + using WinkCallback = base::OnceClosure; using DeviceCallback = - base::OnceCallback<void(bool success, - base::Optional<apdu::ApduResponse> response)>; - using WinkCallback = base::OnceCallback<void()>; + base::OnceCallback<void(base::Optional<std::vector<uint8_t>> response)>; - static constexpr auto kDeviceTimeout = base::TimeDelta::FromSeconds(3); + // Internal state machine states. + enum class State { kInit, kConnected, kBusy, kReady, kDeviceError }; U2fDevice(); virtual ~U2fDevice(); - - // TODO(hongjunchoi): https://crbug.com/810229 Move all encoding logic from - // U2fDevice to U2fRequest. - // Raw messages parameters are defined by the specification at - // https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-raw-message-formats.html - void Register(base::Optional<std::vector<uint8_t>> register_cmd, - MessageCallback callback); - void Sign(base::Optional<std::vector<uint8_t>> sign_cmd, - MessageCallback callback); - void Version(VersionCallback callback); - - virtual void TryWink(WinkCallback callback) = 0; - virtual std::string GetId() const = 0; - - protected: // Pure virtual function defined by each device type, implementing // the device communication transaction. virtual void DeviceTransact(std::vector<uint8_t> command, DeviceCallback callback) = 0; - virtual base::WeakPtr<U2fDevice> GetWeakPtr() = 0; + virtual void TryWink(WinkCallback callback) = 0; + virtual std::string GetId() const = 0; - private: - void OnRegisterComplete(MessageCallback callback, - bool success, - base::Optional<apdu::ApduResponse> register_response); - void OnSignComplete(MessageCallback callback, - bool success, - base::Optional<apdu::ApduResponse> sign_response); - void OnVersionComplete(VersionCallback callback, - bool legacy, - bool success, - base::Optional<apdu::ApduResponse> version_response); + protected: + virtual base::WeakPtr<U2fDevice> GetWeakPtr() = 0; DISALLOW_COPY_AND_ASSIGN(U2fDevice); };
diff --git a/device/fido/u2f_hid_device.cc b/device/fido/u2f_hid_device.cc index d705858..88df56b 100644 --- a/device/fido/u2f_hid_device.cc +++ b/device/fido/u2f_hid_device.cc
@@ -26,7 +26,7 @@ U2fHidDevice::U2fHidDevice(device::mojom::HidDeviceInfoPtr device_info, device::mojom::HidManager* hid_manager) : U2fDevice(), - state_(State::INIT), + state_(State::kInit), hid_manager_(hid_manager), device_info_(std::move(device_info)), weak_factory_(this) {} @@ -45,45 +45,44 @@ auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); switch (state_) { - case State::INIT: - state_ = State::BUSY; + case State::kInit: + state_ = State::kBusy; ArmTimeout(repeating_callback); Connect(base::BindOnce(&U2fHidDevice::OnConnect, weak_factory_.GetWeakPtr(), std::move(command), repeating_callback)); break; - case State::CONNECTED: - state_ = State::BUSY; + case State::kConnected: + state_ = State::kBusy; ArmTimeout(repeating_callback); AllocateChannel(std::move(command), repeating_callback); break; - case State::IDLE: { - state_ = State::BUSY; + case State::kReady: { + state_ = State::kBusy; ArmTimeout(repeating_callback); - // Write message to the device + // Write message to the device. WriteMessage( - FidoHidMessage::Create(channel_id_, CtapHidDeviceCommand::kCtapHidMsg, + FidoHidMessage::Create(channel_id_, FidoHidDeviceCommand::kMsg, std::move(command)), true, base::BindOnce(&U2fHidDevice::MessageReceived, weak_factory_.GetWeakPtr(), repeating_callback)); break; } - case State::BUSY: + case State::kBusy: pending_transactions_.emplace(std::move(command), repeating_callback); break; - case State::DEVICE_ERROR: + case State::kDeviceError: default: base::WeakPtr<U2fHidDevice> self = weak_factory_.GetWeakPtr(); - repeating_callback.Run(false, base::nullopt); - + repeating_callback.Run(base::nullopt); // Executing callbacks may free |this|. Check |self| first. while (self && !pending_transactions_.empty()) { - // Respond to any pending requests + // Respond to any pending requests. DeviceCallback pending_cb = std::move(pending_transactions_.front().second); pending_transactions_.pop(); - std::move(pending_cb).Run(false, base::nullopt); + std::move(pending_cb).Run(base::nullopt); } break; } @@ -97,30 +96,30 @@ void U2fHidDevice::OnConnect(std::vector<uint8_t> command, DeviceCallback callback, device::mojom::HidConnectionPtr connection) { - if (state_ == State::DEVICE_ERROR) + if (state_ == State::kDeviceError) return; timeout_callback_.Cancel(); if (connection) { connection_ = std::move(connection); - state_ = State::CONNECTED; + state_ = State::kConnected; } else { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; } Transition(std::move(command), std::move(callback)); } void U2fHidDevice::AllocateChannel(std::vector<uint8_t> command, DeviceCallback callback) { - // Send random nonce to device to verify received message + // Send random nonce to device to verify received message. std::vector<uint8_t> nonce(8); crypto::RandBytes(nonce.data(), nonce.size()); - WriteMessage(FidoHidMessage::Create( - channel_id_, CtapHidDeviceCommand::kCtapHidInit, nonce), - true, - base::BindOnce(&U2fHidDevice::OnAllocateChannel, - weak_factory_.GetWeakPtr(), nonce, - std::move(command), std::move(callback))); + WriteMessage( + FidoHidMessage::Create(channel_id_, FidoHidDeviceCommand::kInit, nonce), + true, + base::BindOnce(&U2fHidDevice::OnAllocateChannel, + weak_factory_.GetWeakPtr(), nonce, std::move(command), + std::move(callback))); } void U2fHidDevice::OnAllocateChannel(std::vector<uint8_t> nonce, @@ -128,12 +127,12 @@ DeviceCallback callback, bool success, std::unique_ptr<FidoHidMessage> message) { - if (state_ == State::DEVICE_ERROR) + if (state_ == State::kDeviceError) return; timeout_callback_.Cancel(); if (!success || !message) { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; Transition(std::vector<uint8_t>(), std::move(callback)); return; } @@ -148,7 +147,7 @@ // 16: Capabilities std::vector<uint8_t> payload = message->GetMessagePayload(); if (payload.size() != 17) { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; Transition(std::vector<uint8_t>(), std::move(callback)); return; } @@ -172,7 +171,7 @@ channel_id_ |= payload[index++] << 8; channel_id_ |= payload[index++]; capabilities_ = payload[16]; - state_ = State::IDLE; + state_ = State::kReady; Transition(std::move(command), std::move(callback)); } @@ -228,7 +227,7 @@ return; } - // Received a message from a different channel, so try again + // Received a message from a different channel, so try again. if (channel_id_ != read_message->channel_id()) { connection_->Read(base::BindOnce(&U2fHidDevice::OnRead, weak_factory_.GetWeakPtr(), @@ -241,7 +240,7 @@ return; } - // Continue reading additional packets + // Continue reading additional packets. connection_->Read(base::BindOnce( &U2fHidDevice::OnReadContinuation, weak_factory_.GetWeakPtr(), std::move(read_message), std::move(callback))); @@ -272,27 +271,24 @@ void U2fHidDevice::MessageReceived(DeviceCallback callback, bool success, std::unique_ptr<FidoHidMessage> message) { - if (state_ == State::DEVICE_ERROR) + if (state_ == State::kDeviceError) return; timeout_callback_.Cancel(); if (!success) { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; Transition(std::vector<uint8_t>(), std::move(callback)); return; } - auto response = - message - ? apdu::ApduResponse::CreateFromMessage(message->GetMessagePayload()) - : base::nullopt; - - state_ = State::IDLE; + state_ = State::kReady; base::WeakPtr<U2fHidDevice> self = weak_factory_.GetWeakPtr(); - std::move(callback).Run(success, std::move(response)); + std::move(callback).Run( + (success && message) ? base::make_optional(message->GetMessagePayload()) + : base::nullopt); // Executing |callback| may have freed |this|. Check |self| first. if (self && !pending_transactions_.empty()) { - // If any transactions were queued, process the first one + // If any transactions were queued, process the first one. auto pending_cmd = std::move(pending_transactions_.front().first); auto pending_cb = std::move(pending_transactions_.front().second); pending_transactions_.pop(); @@ -301,18 +297,17 @@ } void U2fHidDevice::TryWink(WinkCallback callback) { - // Only try to wink if device claims support - if (!(capabilities_ & kWinkCapability) || state_ != State::IDLE) { + // Only try to wink if device claims support. + if (!(capabilities_ & kWinkCapability) || state_ != State::kReady) { std::move(callback).Run(); return; } - WriteMessage( - FidoHidMessage::Create(channel_id_, CtapHidDeviceCommand::kCtapHidWink, - std::vector<uint8_t>()), - true, - base::BindOnce(&U2fHidDevice::OnWink, weak_factory_.GetWeakPtr(), - std::move(callback))); + WriteMessage(FidoHidMessage::Create(channel_id_, FidoHidDeviceCommand::kWink, + std::vector<uint8_t>()), + true, + base::BindOnce(&U2fHidDevice::OnWink, weak_factory_.GetWeakPtr(), + std::move(callback))); } void U2fHidDevice::OnWink(WinkCallback callback, @@ -326,13 +321,13 @@ timeout_callback_.Reset(base::BindOnce(&U2fHidDevice::OnTimeout, weak_factory_.GetWeakPtr(), std::move(callback))); - // Setup timeout task for 3 seconds + // Setup timeout task for 3 seconds. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, timeout_callback_.callback(), kDeviceTimeout); } void U2fHidDevice::OnTimeout(DeviceCallback callback) { - state_ = State::DEVICE_ERROR; + state_ = State::kDeviceError; Transition(std::vector<uint8_t>(), std::move(callback)); }
diff --git a/device/fido/u2f_hid_device.h b/device/fido/u2f_hid_device.h index 4ee250329..a42e6a6 100644 --- a/device/fido/u2f_hid_device.h +++ b/device/fido/u2f_hid_device.h
@@ -11,9 +11,12 @@ #include <utility> #include <vector> +#include "base/callback.h" #include "base/cancelable_callback.h" #include "base/component_export.h" #include "base/macros.h" +#include "components/apdu/apdu_command.h" +#include "components/apdu/apdu_response.h" #include "device/fido/u2f_device.h" #include "services/device/public/mojom/hid.mojom.h" @@ -27,40 +30,39 @@ device::mojom::HidManager* hid_manager); ~U2fHidDevice() final; - // Send a U2f command to this device + // Send a command to this device. void DeviceTransact(std::vector<uint8_t> command, DeviceCallback callback) final; - // Send a wink command if supported + // Send a wink command if supported. void TryWink(WinkCallback callback) final; - // Use a string identifier to compare to other devices + // Use a string identifier to compare to other devices. std::string GetId() const final; - // Get a string identifier for a given device info + + // Get a string identifier for a given device info. static std::string GetIdForDevice( const device::mojom::HidDeviceInfo& device_info); - // Command line flag to enable tests on actual U2f HID hardware + // Command line flag to enable tests on actual HID hardware. static bool IsTestEnabled(); private: FRIEND_TEST_ALL_PREFIXES(U2fHidDeviceTest, TestConnectionFailure); FRIEND_TEST_ALL_PREFIXES(U2fHidDeviceTest, TestDeviceError); + FRIEND_TEST_ALL_PREFIXES(U2fHidDeviceTest, TestRetryChannelAllocation); static constexpr uint8_t kWinkCapability = 0x01; static constexpr uint8_t kLockCapability = 0x02; static constexpr uint32_t kBroadcastChannel = 0xffffffff; - // Internal state machine states - enum class State { INIT, CONNECTED, BUSY, IDLE, DEVICE_ERROR }; - using U2fHidMessageCallback = base::OnceCallback<void(bool, std::unique_ptr<FidoHidMessage>)>; using ConnectCallback = device::mojom::HidManager::ConnectCallback; - // Open a connection to this device + // Open a connection to this device. void Connect(ConnectCallback callback); void OnConnect(std::vector<uint8_t> command, DeviceCallback callback, device::mojom::HidConnectionPtr connection); - // Ask device to allocate a unique channel id for this connection + // Ask device to allocate a unique channel id for this connection. void AllocateChannel(std::vector<uint8_t> command, DeviceCallback callback); void OnAllocateChannel(std::vector<uint8_t> nonce, std::vector<uint8_t> command, @@ -68,7 +70,7 @@ bool success, std::unique_ptr<FidoHidMessage> message); void Transition(std::vector<uint8_t> command, DeviceCallback callback); - // Write all message packets to device, and read response if expected + // Write all message packets to device, and read response if expected. void WriteMessage(std::unique_ptr<FidoHidMessage> message, bool response_expected, U2fHidMessageCallback callback); @@ -76,7 +78,7 @@ bool response_expected, U2fHidMessageCallback callback, bool success); - // Read all response message packets from device + // Read all response message packets from device. void ReadMessage(U2fHidMessageCallback callback); void MessageReceived(DeviceCallback callback, bool success, @@ -95,13 +97,11 @@ std::unique_ptr<FidoHidMessage> response); void ArmTimeout(DeviceCallback callback); void OnTimeout(DeviceCallback callback); - void OnDeviceTransact(bool success, - base::Optional<apdu::ApduResponse> response); base::WeakPtr<U2fDevice> GetWeakPtr() override; uint32_t channel_id_ = kBroadcastChannel; uint8_t capabilities_ = 0; - State state_ = State::INIT; + State state_ = State::kInit; base::CancelableOnceClosure timeout_callback_; std::queue<std::pair<std::vector<uint8_t>, DeviceCallback>>
diff --git a/device/fido/u2f_hid_device_unittest.cc b/device/fido/u2f_hid_device_unittest.cc index eb6e155..4e2d5f3 100644 --- a/device/fido/u2f_hid_device_unittest.cc +++ b/device/fido/u2f_hid_device_unittest.cc
@@ -9,13 +9,12 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" -#include "base/test/scoped_mock_time_message_loop_task_runner.h" #include "base/test/scoped_task_environment.h" #include "components/apdu/apdu_command.h" #include "components/apdu/apdu_response.h" #include "device/fido/fake_hid_impl_for_testing.h" +#include "device/fido/fido_constants.h" #include "device/fido/test_callback_receiver.h" -#include "device/fido/u2f_command_type.h" #include "device/fido/u2f_hid_device.h" #include "device/fido/u2f_request.h" #include "mojo/public/cpp/bindings/binding.h" @@ -54,11 +53,10 @@ } // Returns HID_INIT request to send to device with mock connection. -std::vector<uint8_t> CreateMockHidInitResponse( - std::vector<uint8_t> nonce, - std::vector<uint8_t> channel_id) { +std::vector<uint8_t> CreateMockInitResponse(std::vector<uint8_t> nonce, + std::vector<uint8_t> channel_id) { // 4 bytes of broadcast channel identifier(ffffffff), followed by - // HID_INIT command(86) and 2 byte payload length(11) + // HID_INIT command(86) and 2 byte payload length(11). return MakePacket("ffffffff860011" + HexEncode(nonce) + HexEncode(channel_id)); } @@ -71,12 +69,12 @@ return MakePacket(HexEncode(channel_id) + "8300085532465f56329000"); } -// Returns a failure mock response to version request with given channel id. -std::vector<uint8_t> CreateFailureMockVersionResponse( - std::vector<uint8_t> channel_id) { - // HID_MSG command(83), followed by payload length(0002), followed by - // an invalid class response code (6E00). - return MakePacket(HexEncode(channel_id) + "8300026E00"); +// Returns U2F_V2 version response formatted in APDU response encoding. +std::vector<uint8_t> GetValidU2fVersionResponse() { + return apdu::ApduResponse(std::vector<uint8_t>(kU2fVersionResponse.begin(), + kU2fVersionResponse.end()), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse(); } device::mojom::HidDeviceInfoPtr TestHidDevice() { @@ -122,10 +120,8 @@ DISALLOW_COPY_AND_ASSIGN(U2fDeviceEnumerateCallbackReceiver); }; -using TestVersionCallbackReceiver = - test::StatusAndValueCallbackReceiver<bool, U2fDevice::ProtocolVersion>; -using TestDeviceCallbackReceiver = ::device::test:: - StatusAndValueCallbackReceiver<bool, base::Optional<apdu::ApduResponse>>; +using TestDeviceCallbackReceiver = + ::device::test::TestCallbackReceiver<base::Optional<std::vector<uint8_t>>>; } // namespace @@ -146,43 +142,6 @@ base::test::ScopedTaskEnvironment scoped_task_environment_; }; -TEST_F(U2fHidDeviceTest, TestHidDeviceVersion) { - if (!U2fHidDevice::IsTestEnabled()) - return; - - U2fDeviceEnumerateCallbackReceiver receiver(hid_manager_.get()); - hid_manager_->GetDevices(receiver.callback()); - receiver.WaitForCallback(); - - for (auto& device : receiver.TakeReturnedDevicesFiltered()) { - TestVersionCallbackReceiver vc; - device->Version(vc.callback()); - vc.WaitForCallback(); - EXPECT_EQ(U2fDevice::ProtocolVersion::U2F_V2, vc.value()); - } -} - -TEST_F(U2fHidDeviceTest, TestMultipleRequests) { - if (!U2fHidDevice::IsTestEnabled()) - return; - - U2fDeviceEnumerateCallbackReceiver receiver(hid_manager_.get()); - hid_manager_->GetDevices(receiver.callback()); - receiver.WaitForCallback(); - - for (auto& device : receiver.TakeReturnedDevicesFiltered()) { - TestVersionCallbackReceiver vc; - TestVersionCallbackReceiver vc2; - // Call version twice to check message queueing. - device->Version(vc.callback()); - device->Version(vc2.callback()); - vc.WaitForCallback(); - EXPECT_EQ(U2fDevice::ProtocolVersion::U2F_V2, vc.value()); - vc2.WaitForCallback(); - EXPECT_EQ(U2fDevice::ProtocolVersion::U2F_V2, vc2.value()); - } -} - TEST_F(U2fHidDeviceTest, TestConnectionFailure) { // Setup and enumerate mock device. U2fDeviceEnumerateCallbackReceiver receiver(hid_manager_.get()); @@ -197,7 +156,7 @@ ASSERT_EQ(static_cast<size_t>(1), u2f_devices.size()); auto& device = u2f_devices.front(); // Put device in IDLE state. - device->state_ = U2fHidDevice::State::IDLE; + device->state_ = U2fDevice::State::kReady; // Manually delete connection. device->connection_ = nullptr; @@ -213,10 +172,11 @@ device->DeviceTransact(U2fRequest::GetU2fVersionApduCommand(), receiver_3.callback()); - EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_); - EXPECT_EQ(base::nullopt, receiver_1.value()); - EXPECT_EQ(base::nullopt, receiver_2.value()); - EXPECT_EQ(base::nullopt, receiver_3.value()); + EXPECT_EQ(U2fDevice::State::kDeviceError, device->state_); + + EXPECT_FALSE(std::get<0>(*receiver_1.result())); + EXPECT_FALSE(std::get<0>(*receiver_2.result())); + EXPECT_FALSE(std::get<0>(*receiver_3.result())); } TEST_F(U2fHidDeviceTest, TestDeviceError) { @@ -236,13 +196,13 @@ // Mock connection where writes always fail. FakeHidConnection::mock_connection_error_ = true; - device->state_ = U2fHidDevice::State::IDLE; + device->state_ = U2fDevice::State::kReady; TestDeviceCallbackReceiver receiver_0; device->DeviceTransact(U2fRequest::GetU2fVersionApduCommand(), receiver_0.callback()); - EXPECT_EQ(base::nullopt, receiver_0.value()); - EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_); + EXPECT_FALSE(std::get<0>(*receiver_0.result())); + EXPECT_EQ(U2fDevice::State::kDeviceError, device->state_); // Add pending transactions manually and ensure they are processed. // Add pending transactions manually and ensure they are processed. @@ -257,85 +217,10 @@ receiver_3.callback()); FakeHidConnection::mock_connection_error_ = false; - EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_); - EXPECT_EQ(base::nullopt, receiver_1.value()); - EXPECT_EQ(base::nullopt, receiver_2.value()); - EXPECT_EQ(base::nullopt, receiver_3.value()); -} - -TEST_F(U2fHidDeviceTest, TestLegacyVersion) { - const std::vector<uint8_t> kChannelId = {0x01, 0x02, 0x03, 0x04}; - - auto hid_device = TestHidDevice(); - - // Replace device HID connection with custom client connection bound to mock - // server-side mojo connection. - device::mojom::HidConnectionPtr connection_client; - MockHidConnection mock_connection( - hid_device.Clone(), mojo::MakeRequest(&connection_client), kChannelId); - - // Delegate custom functions to be invoked for mock hid connection. - EXPECT_CALL(mock_connection, WritePtr(_, _, _)) - // HID_INIT request to authenticator for channel allocation. - .WillOnce(WithArgs<1, 2>( - Invoke([&](const std::vector<uint8_t>& buffer, - device::mojom::HidConnection::WriteCallback* cb) { - mock_connection.SetNonce(base::make_span(buffer).subspan(7, 8)); - std::move(*cb).Run(true); - }))) - - // HID_MSG request to authenticator for version request. - .WillOnce(WithArgs<2>( - Invoke([](device::mojom::HidConnection::WriteCallback* cb) { - std::move(*cb).Run(true); - }))) - - .WillOnce(WithArgs<2>( - Invoke([](device::mojom::HidConnection::WriteCallback* cb) { - std::move(*cb).Run(true); - }))); - - EXPECT_CALL(mock_connection, ReadPtr(_)) - // Response to HID_INIT request with correct nonce. - .WillOnce(WithArg<0>(Invoke( - [&mock_connection](device::mojom::HidConnection::ReadCallback* cb) { - std::move(*cb).Run(true, 0, - CreateMockHidInitResponse( - mock_connection.nonce(), - mock_connection.connection_channel_id())); - }))) - // Invalid version response from the authenticator. - .WillOnce(WithArg<0>(Invoke( - [&mock_connection](device::mojom::HidConnection::ReadCallback* cb) { - std::move(*cb).Run(true, 0, - CreateFailureMockVersionResponse( - mock_connection.connection_channel_id())); - }))) - // Legacy version response from the authenticator. - .WillOnce(WithArg<0>(Invoke( - [&mock_connection](device::mojom::HidConnection::ReadCallback* cb) { - std::move(*cb).Run(true, 0, - CreateMockVersionResponse( - mock_connection.connection_channel_id())); - }))); - - // Add device and set mock connection to fake hid manager. - fake_hid_manager_->AddDeviceAndSetConnection(std::move(hid_device), - std::move(connection_client)); - - U2fDeviceEnumerateCallbackReceiver receiver(hid_manager_.get()); - hid_manager_->GetDevices(receiver.callback()); - receiver.WaitForCallback(); - - std::vector<std::unique_ptr<U2fHidDevice>> u2f_devices = - receiver.TakeReturnedDevicesFiltered(); - - ASSERT_EQ(1u, u2f_devices.size()); - auto& device = u2f_devices.front(); - TestVersionCallbackReceiver vc; - device->Version(vc.callback()); - vc.WaitForCallback(); - EXPECT_EQ(U2fDevice::ProtocolVersion::U2F_V2, vc.value()); + EXPECT_EQ(U2fDevice::State::kDeviceError, device->state_); + EXPECT_FALSE(std::get<0>(*receiver_1.result())); + EXPECT_FALSE(std::get<0>(*receiver_2.result())); + EXPECT_FALSE(std::get<0>(*receiver_3.result())); } TEST_F(U2fHidDeviceTest, TestRetryChannelAllocation) { @@ -375,14 +260,14 @@ device::mojom::HidConnection::ReadCallback* cb) { std::move(*cb).Run( true, 0, - CreateMockHidInitResponse( + CreateMockInitResponse( kIncorrectNonce, mock_connection.connection_channel_id())); }))) // Second response to HID_INIT request with correct nonce. .WillOnce(WithArg<0>(Invoke( [&mock_connection](device::mojom::HidConnection::ReadCallback* cb) { std::move(*cb).Run(true, 0, - CreateMockHidInitResponse( + CreateMockInitResponse( mock_connection.nonce(), mock_connection.connection_channel_id())); }))) @@ -407,10 +292,15 @@ ASSERT_EQ(1u, u2f_devices.size()); auto& device = u2f_devices.front(); - TestVersionCallbackReceiver vc; - device->Version(vc.callback()); - vc.WaitForCallback(); - EXPECT_EQ(U2fDevice::ProtocolVersion::U2F_V2, vc.value()); + + TestDeviceCallbackReceiver cb; + device->DeviceTransact(U2fRequest::GetU2fVersionApduCommand(false), + cb.callback()); + cb.WaitForCallback(); + + const auto& result = std::get<0>(*cb.result()); + ASSERT_TRUE(result); + EXPECT_THAT(*result, testing::ElementsAreArray(GetValidU2fVersionResponse())); } } // namespace device
diff --git a/device/fido/u2f_register.cc b/device/fido/u2f_register.cc index 3081737c..e743fbf 100644 --- a/device/fido/u2f_register.cc +++ b/device/fido/u2f_register.cc
@@ -7,6 +7,8 @@ #include <utility> #include "base/stl_util.h" +#include "components/apdu/apdu_command.h" +#include "components/apdu/apdu_response.h" #include "device/fido/register_response_data.h" #include "services/service_manager/public/cpp/connector.h" @@ -51,12 +53,13 @@ DCHECK(current_device_); if (!registered_keys_.empty() && !CheckedForDuplicateRegistration()) { auto it = registered_keys_.cbegin(); - current_device_->Sign(GetU2fSignApduCommand(application_parameter_, *it, - true /* check_only */), - base::BindOnce(&U2fRegister::OnTryCheckRegistration, - weak_factory_.GetWeakPtr(), it)); + InitiateDeviceTransaction( + GetU2fSignApduCommand(application_parameter_, *it, + true /* check_only */), + base::BindOnce(&U2fRegister::OnTryCheckRegistration, + weak_factory_.GetWeakPtr(), it)); } else { - current_device_->Register( + InitiateDeviceTransaction( GetU2fRegisterApduCommand(individual_attestation_ok_), base::BindOnce(&U2fRegister::OnTryDevice, weak_factory_.GetWeakPtr(), false /* is_duplicate_registration */)); @@ -65,24 +68,30 @@ void U2fRegister::OnTryCheckRegistration( std::vector<std::vector<uint8_t>>::const_iterator it, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data) { + base::Optional<std::vector<uint8_t>> response) { + const auto apdu_response = + response ? apdu::ApduResponse::CreateFromMessage(std::move(*response)) + : base::nullopt; + auto return_code = apdu_response ? apdu_response->status() + : apdu::ApduResponse::Status::SW_WRONG_DATA; + switch (return_code) { - case U2fReturnCode::SUCCESS: - case U2fReturnCode::CONDITIONS_NOT_SATISFIED: + case apdu::ApduResponse::Status::SW_NO_ERROR: + case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: { // Duplicate registration found. Call bogus registration to check for // user presence (touch) and terminate the registration process. - current_device_->Register( + InitiateDeviceTransaction( U2fRequest::GetBogusRegisterCommand(), base::BindOnce(&U2fRegister::OnTryDevice, weak_factory_.GetWeakPtr(), true /* is_duplicate_registration */)); break; + } - case U2fReturnCode::INVALID_PARAMS: + case apdu::ApduResponse::Status::SW_WRONG_DATA: // Continue to iterate through the provided key handles in the exclude // list and check for already registered keys. if (++it != registered_keys_.end()) { - current_device_->Sign( + InitiateDeviceTransaction( GetU2fSignApduCommand(application_parameter_, *it, true /* check_only */), base::BindOnce(&U2fRegister::OnTryCheckRegistration, @@ -122,10 +131,14 @@ } void U2fRegister::OnTryDevice(bool is_duplicate_registration, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data) { + base::Optional<std::vector<uint8_t>> response) { + const auto apdu_response = + response ? apdu::ApduResponse::CreateFromMessage(std::move(*response)) + : base::nullopt; + auto return_code = apdu_response ? apdu_response->status() + : apdu::ApduResponse::Status::SW_WRONG_DATA; switch (return_code) { - case U2fReturnCode::SUCCESS: { + case apdu::ApduResponse::Status::SW_NO_ERROR: { state_ = State::COMPLETE; if (is_duplicate_registration) { std::move(completion_callback_) @@ -133,7 +146,7 @@ break; } auto response = RegisterResponseData::CreateFromU2fRegisterResponse( - application_parameter_, std::move(response_data)); + application_parameter_, apdu_response->data()); if (!response) { // The response data was corrupted / didn't parse properly. std::move(completion_callback_) @@ -144,7 +157,7 @@ .Run(U2fReturnCode::SUCCESS, std::move(response)); break; } - case U2fReturnCode::CONDITIONS_NOT_SATISFIED: + case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: // Waiting for user touch, move on and try this device later. state_ = State::IDLE; Transition();
diff --git a/device/fido/u2f_register.h b/device/fido/u2f_register.h index 3d7262e1..f04a94a 100644 --- a/device/fido/u2f_register.h +++ b/device/fido/u2f_register.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/optional.h" #include "device/fido/u2f_request.h" +#include "device/fido/u2f_return_code.h" #include "device/fido/u2f_transport_protocol.h" namespace service_manager { @@ -50,20 +51,16 @@ ~U2fRegister() override; private: - FRIEND_TEST_ALL_PREFIXES(U2fRegisterTest, TestCreateU2fRegisterCommand); - void TryDevice() override; void OnTryDevice(bool is_duplicate_registration, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data); + base::Optional<std::vector<uint8_t>> response); // Callback function called when non-empty exclude list was provided. This // function iterates through all key handles in |registered_keys_| for all // devices and checks for already registered keys. void OnTryCheckRegistration( std::vector<std::vector<uint8_t>>::const_iterator it, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data); + base::Optional<std::vector<uint8_t>> response); // Function handling registration flow after all devices were checked for // already registered keys. void CompleteNewDeviceRegistration();
diff --git a/device/fido/u2f_register_unittest.cc b/device/fido/u2f_register_unittest.cc index e0246ae..de346f6 100644 --- a/device/fido/u2f_register_unittest.cc +++ b/device/fido/u2f_register_unittest.cc
@@ -439,6 +439,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), register_callback_receiver().value()->raw_id()); } @@ -455,6 +456,7 @@ EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); // We don't verify the response from the fake, but do a quick sanity check. + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(32ul, register_callback_receiver().value()->raw_id().size()); } @@ -476,6 +478,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), register_callback_receiver().value()->raw_id()); } @@ -506,6 +509,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), register_callback_receiver().value()->raw_id()); } @@ -544,6 +548,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), register_callback_receiver().value()->raw_id()); } @@ -596,6 +601,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, register_callback_receiver().status()); + ASSERT_TRUE(register_callback_receiver().value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), register_callback_receiver().value()->raw_id()); } @@ -637,7 +643,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::CONDITIONS_NOT_SATISFIED, register_callback_receiver().status()); - EXPECT_EQ(base::nullopt, register_callback_receiver().value()); + EXPECT_FALSE(register_callback_receiver().value()); } // Tests a scenario where one (device1) of the two devices connected has created @@ -689,7 +695,7 @@ register_callback_receiver().WaitForCallback(); EXPECT_EQ(U2fReturnCode::CONDITIONS_NOT_SATISFIED, register_callback_receiver().status()); - EXPECT_EQ(base::nullopt, register_callback_receiver().value()); + EXPECT_FALSE(register_callback_receiver().value()); } // These test the parsing of the U2F raw bytes of the registration response. @@ -825,6 +831,7 @@ cb.WaitForCallback(); EXPECT_EQ(U2fReturnCode::SUCCESS, cb.status()); + ASSERT_TRUE(cb.value()); EXPECT_EQ(GetTestCredentialRawIdBytes(), cb.value()->raw_id()); } }
diff --git a/device/fido/u2f_request.cc b/device/fido/u2f_request.cc index 3f7581d..817eb8c 100644 --- a/device/fido/u2f_request.cc +++ b/device/fido/u2f_request.cc
@@ -13,6 +13,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "components/apdu/apdu_command.h" +#include "components/apdu/apdu_response.h" #include "services/service_manager/public/cpp/connector.h" namespace device { @@ -119,7 +120,7 @@ case State::IDLE: IterateDevice(); if (!current_device_) { - // No devices available + // No devices available. state_ = State::OFF; break; } @@ -136,6 +137,41 @@ } } +void U2fRequest::InitiateDeviceTransaction( + base::Optional<std::vector<uint8_t>> cmd, + U2fDevice::DeviceCallback callback) { + if (!cmd) { + std::move(callback).Run(base::nullopt); + return; + } + current_device_->DeviceTransact(std::move(*cmd), std::move(callback)); +} + +void U2fRequest::OnDeviceVersionRequest( + VersionCallback callback, + base::WeakPtr<U2fDevice> device, + bool legacy, + base::Optional<std::vector<uint8_t>> response) { + const auto apdu_response = + response ? apdu::ApduResponse::CreateFromMessage(std::move(*response)) + : base::nullopt; + if (apdu_response && + apdu_response->status() == apdu::ApduResponse::Status::SW_NO_ERROR && + std::equal(apdu_response->data().cbegin(), apdu_response->data().cend(), + kU2fVersionResponse.cbegin(), kU2fVersionResponse.cend())) { + std::move(callback).Run(ProtocolVersion::kU2f); + } else if (!legacy) { + // Standard GetVersion failed, attempt legacy GetVersion command. + device->DeviceTransact( + GetU2fVersionApduCommand(true), + base::BindOnce(&U2fRequest::OnDeviceVersionRequest, + weak_factory_.GetWeakPtr(), std::move(callback), device, + true /* legacy */)); + } else { + std::move(callback).Run(ProtocolVersion::kUnknown); + } +} + void U2fRequest::DiscoveryStarted(U2fDiscovery* discovery, bool success) { if (success) { // The discovery might know about devices that have already been added to @@ -215,7 +251,7 @@ devices_.pop_front(); } else if (attempted_devices_.size() > 0) { devices_ = std::move(attempted_devices_); - // After trying every device, wait 200ms before trying again + // After trying every device, wait 200ms before trying again. delay_callback_.Reset( base::Bind(&U2fRequest::OnWaitComplete, weak_factory_.GetWeakPtr())); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
diff --git a/device/fido/u2f_request.h b/device/fido/u2f_request.h index 696e8c0..88e4f99 100644 --- a/device/fido/u2f_request.h +++ b/device/fido/u2f_request.h
@@ -5,6 +5,8 @@ #ifndef DEVICE_FIDO_U2F_REQUEST_H_ #define DEVICE_FIDO_U2F_REQUEST_H_ +#include <stdint.h> + #include <list> #include <memory> #include <string> @@ -28,6 +30,8 @@ class COMPONENT_EXPORT(DEVICE_FIDO) U2fRequest : public U2fDiscovery::Observer { public: + using VersionCallback = base::OnceCallback<void(ProtocolVersion version)>; + // U2fRequest will create a discovery instance and register itself as an // observer for each passed in transport protocol. // TODO(https://crbug.com/769631): Remove the dependency on Connector once U2F @@ -68,6 +72,17 @@ void Transition(); + // Starts sign, register, and version request transaction on + // |current_device_|. + void InitiateDeviceTransaction(base::Optional<std::vector<uint8_t>> cmd, + U2fDevice::DeviceCallback callback); + // Callback function to U2F version request. If non-legacy version request + // fails, retry with legacy version request. + void OnDeviceVersionRequest(VersionCallback callback, + base::WeakPtr<U2fDevice> device, + bool legacy, + base::Optional<std::vector<uint8_t>> response); + virtual void TryDevice() = 0; // Hold handles to the devices known to the system. Known devices are @@ -94,6 +109,7 @@ FRIEND_TEST_ALL_PREFIXES(U2fRequestTest, TestMultipleDiscoveries); FRIEND_TEST_ALL_PREFIXES(U2fRequestTest, TestSlowDiscovery); FRIEND_TEST_ALL_PREFIXES(U2fRequestTest, TestMultipleDiscoveriesWithFailures); + FRIEND_TEST_ALL_PREFIXES(U2fRequestTest, TestLegacyVersionRequest); // U2fDiscovery::Observer void DiscoveryStarted(U2fDiscovery* discovery, bool success) override;
diff --git a/device/fido/u2f_request_unittest.cc b/device/fido/u2f_request_unittest.cc index 57b4422..f57a9c09 100644 --- a/device/fido/u2f_request_unittest.cc +++ b/device/fido/u2f_request_unittest.cc
@@ -9,6 +9,7 @@ #include "base/test/scoped_task_environment.h" #include "device/fido/fake_u2f_discovery.h" #include "device/fido/mock_u2f_device.h" +#include "device/fido/test_callback_receiver.h" #include "device/fido/u2f_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,6 +35,9 @@ } }; +using TestVersionCallback = + ::device::test::TestCallbackReceiver<ProtocolVersion>; + } // namespace class U2fRequestTest : public ::testing::Test { @@ -46,10 +50,15 @@ return discovery_factory_; } + TestVersionCallback& version_callback_receiver() { + return version_callback_receiver_; + } + private: base::test::ScopedTaskEnvironment scoped_task_environment_{ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME}; test::ScopedFakeU2fDiscoveryFactory discovery_factory_; + TestVersionCallback version_callback_receiver_; }; TEST_F(U2fRequestTest, TestIterateDevice) { @@ -336,4 +345,34 @@ ::testing::ElementsAreArray(kEncodedU2fLegacyVersionRequest)); } +// Test a scenario when version request is sent to legacy U2F token. +// After non-legacy version requests fails, legacy version request should be +// sent to device as a retry. +TEST_F(U2fRequestTest, TestLegacyVersionRequest) { + auto* discovery = discovery_factory().ForgeNextHidDiscovery(); + FakeU2fRequest request({U2fTransportProtocol::kUsbHumanInterfaceDevice}); + request.Start(); + + auto device0 = std::make_unique<MockU2fDevice>(); + EXPECT_CALL(*device0, GetId()).WillRepeatedly(::testing::Return("device0")); + EXPECT_CALL(*device0, + DeviceTransactPtr(U2fRequest::GetU2fVersionApduCommand(true), _)) + // Success response for legacy version request after retry. + .WillOnce(testing::Invoke(MockU2fDevice::NoErrorVersion)); + + auto* device_ptr = device0.get(); + discovery->AddDevice(std::move(device0)); + + // Represents version callback received from legacy U2F token on initial + // version request. Device responses with invalid protocol version (in this + // case, empty byte array). Retry version request with legacy bit is expected + // to be issued afterwards. + request.OnDeviceVersionRequest(version_callback_receiver().callback(), + device_ptr->GetWeakPtr(), false /* legacy */, + std::vector<uint8_t>()); + + EXPECT_EQ(ProtocolVersion::kU2f, + std::get<0>(*version_callback_receiver().result())); +} + } // namespace device
diff --git a/device/fido/u2f_sign.cc b/device/fido/u2f_sign.cc index bb5b681a..c4d5f298 100644 --- a/device/fido/u2f_sign.cc +++ b/device/fido/u2f_sign.cc
@@ -6,6 +6,8 @@ #include <utility> +#include "components/apdu/apdu_command.h" +#include "components/apdu/apdu_response.h" #include "services/service_manager/public/cpp/connector.h" namespace device { @@ -65,7 +67,7 @@ // https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html if (registered_keys_.size() == 0) { // Send registration (Fake enroll) if no keys were provided. - current_device_->Register( + InitiateDeviceTransaction( U2fRequest::GetBogusRegisterCommand(), base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), registered_keys_.cend(), @@ -74,18 +76,26 @@ } // Try signing current device with the first registered key. auto it = registered_keys_.cbegin(); - current_device_->Sign( + InitiateDeviceTransaction( GetU2fSignApduCommand(application_parameter_, *it), - base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it, - ApplicationParameterType::kPrimary)); + base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it, + ApplicationParameterType::kPrimary)); } void U2fSign::OnTryDevice(std::vector<std::vector<uint8_t>>::const_iterator it, ApplicationParameterType application_parameter_type, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data) { + base::Optional<std::vector<uint8_t>> response) { + const auto apdu_response = + response ? apdu::ApduResponse::CreateFromMessage(std::move(*response)) + : base::nullopt; + auto return_code = apdu_response ? apdu_response->status() + : apdu::ApduResponse::Status::SW_WRONG_DATA; + auto response_data = return_code == apdu::ApduResponse::Status::SW_WRONG_DATA + ? std::vector<uint8_t>() + : apdu_response->data(); + switch (return_code) { - case U2fReturnCode::SUCCESS: { + case apdu::ApduResponse::Status::SW_NO_ERROR: { state_ = State::COMPLETE; if (it == registered_keys_.cend()) { // This was a response to a fake enrollment. Return an empty key handle. @@ -108,33 +118,34 @@ } break; } - case U2fReturnCode::CONDITIONS_NOT_SATISFIED: { + case apdu::ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED: { // Key handle is accepted by this device, but waiting on user touch. Move // on and try this device again later. state_ = State::IDLE; Transition(); break; } - case U2fReturnCode::INVALID_PARAMS: { + case apdu::ApduResponse::Status::SW_WRONG_DATA: + case apdu::ApduResponse::Status::SW_WRONG_LENGTH: { if (application_parameter_type == ApplicationParameterType::kPrimary && alt_application_parameter_) { // |application_parameter_| failed, but there is also // |alt_application_parameter_| to try. - current_device_->Sign( + InitiateDeviceTransaction( GetU2fSignApduCommand(*alt_application_parameter_, *it), base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it, ApplicationParameterType::kAlternative)); } else if (++it != registered_keys_.end()) { // Key is not for this device. Try signing with the next key. - current_device_->Sign( + InitiateDeviceTransaction( GetU2fSignApduCommand(application_parameter_, *it), base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it, ApplicationParameterType::kPrimary)); } else { // No provided key was accepted by this device. Send registration // (Fake enroll) request to device. - current_device_->Register( - GetBogusRegisterCommand(), + InitiateDeviceTransaction( + U2fRequest::GetBogusRegisterCommand(), base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), registered_keys_.cend(), ApplicationParameterType::kPrimary));
diff --git a/device/fido/u2f_sign.h b/device/fido/u2f_sign.h index 8d8a67d..9c6d21fe 100644 --- a/device/fido/u2f_sign.h +++ b/device/fido/u2f_sign.h
@@ -15,6 +15,7 @@ #include "base/optional.h" #include "device/fido/sign_response_data.h" #include "device/fido/u2f_request.h" +#include "device/fido/u2f_return_code.h" #include "device/fido/u2f_transport_protocol.h" namespace service_manager { @@ -48,8 +49,6 @@ ~U2fSign() override; private: - FRIEND_TEST_ALL_PREFIXES(U2fSignTest, TestCreateSignApduCommand); - // Enumerates the two types of |application_parameter| values used: the // "primary" value is the hash of the relying party ID[1] and is always // provided. The "alternative" value is the hash of a U2F AppID, specified in @@ -66,8 +65,7 @@ void TryDevice() override; void OnTryDevice(std::vector<std::vector<uint8_t>>::const_iterator it, ApplicationParameterType application_parameter_type, - U2fReturnCode return_code, - const std::vector<uint8_t>& response_data); + base::Optional<std::vector<uint8_t>> response); base::Optional<std::vector<uint8_t>> alt_application_parameter_; SignResponseCallback completion_callback_;
diff --git a/device/fido/virtual_u2f_device.cc b/device/fido/virtual_u2f_device.cc index 4eb7308..1607914 100644 --- a/device/fido/virtual_u2f_device.cc +++ b/device/fido/virtual_u2f_device.cc
@@ -99,14 +99,7 @@ operator=(RegistrationData&& other) = default; VirtualU2fDevice::RegistrationData::~RegistrationData() = default; -VirtualU2fDevice::VirtualU2fDevice() - : attestation_private_key_( - crypto::ECPrivateKey::CreateFromPrivateKeyInfo(GetAttestationKey())), - attestation_cert_(std::begin(kAttestationCert), - std::end(kAttestationCert)), - weak_factory_(this) { - DCHECK(attestation_private_key_); -} +VirtualU2fDevice::VirtualU2fDevice() : weak_factory_(this) {} VirtualU2fDevice::~VirtualU2fDevice() = default; @@ -145,9 +138,9 @@ break; default: std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_INS_NOT_SUPPORTED)); + apdu::ApduResponse::Status::SW_INS_NOT_SUPPORTED) + .GetEncodedResponse()); } } @@ -162,8 +155,9 @@ DeviceCallback cb) { if (data.size() != 64) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_LENGTH)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_LENGTH) + .GetEncodedResponse()); return; } @@ -202,20 +196,22 @@ // Note: Non-deterministic, you need to mock this out if you rely on // deterministic behavior. std::vector<uint8_t> sig; + std::unique_ptr<crypto::ECPrivateKey> attestation_private_key = + crypto::ECPrivateKey::CreateFromPrivateKeyInfo(GetAttestationKey()); auto signer = - crypto::ECSignatureCreator::Create(attestation_private_key_.get()); + crypto::ECSignatureCreator::Create(attestation_private_key.get()); status = signer->Sign(sign_buffer.data(), sign_buffer.size(), &sig); DCHECK(status); // U2F response data. std::vector<uint8_t> response; response.reserve(1 + public_key.size() + 1 + key_handle.size() + - attestation_cert_.size() + sig.size()); + sizeof(kAttestationCert) + sig.size()); response.push_back(kU2fRegistrationResponseHeader); AppendTo(&response, public_key); response.push_back(key_handle.size()); AppendTo(&response, key_handle); - AppendTo(&response, attestation_cert_); + AppendTo(&response, kAttestationCert); AppendTo(&response, sig); // Store the registration. @@ -223,9 +219,9 @@ std::vector<uint8_t>(app_id_hash.begin(), app_id_hash.end()), 1); - std::move(cb).Run( - true, apdu::ApduResponse(std::move(response), - apdu::ApduResponse::Status::SW_NO_ERROR)); + std::move(cb).Run(apdu::ApduResponse(std::move(response), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); } void VirtualU2fDevice::DoSign(uint8_t ins, @@ -237,8 +233,9 @@ p1 == kP1IndividualAttestation) || p2 != 0) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_DATA)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_DATA) + .GetEncodedResponse()); return; } @@ -249,14 +246,16 @@ // Our own keyhandles are always 32 bytes long, if the request has something // else then we already know it is not ours. std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_DATA)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_DATA) + .GetEncodedResponse()); return; } if (data.size() != 32 + 32 + 1 + key_handle_length) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_LENGTH)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_LENGTH) + .GetEncodedResponse()); return; } auto key_handle = data.last(key_handle_length); @@ -267,8 +266,9 @@ if (it == registrations_.end()) { std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_DATA)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_DATA) + .GetEncodedResponse()); return; } @@ -278,8 +278,9 @@ // It's important this error looks identical to the previous one, as // tokens should not reveal the existence of keyHandles to unrelated appIds. std::move(cb).Run( - true, apdu::ApduResponse(std::vector<uint8_t>(), - apdu::ApduResponse::Status::SW_WRONG_DATA)); + apdu::ApduResponse(std::vector<uint8_t>(), + apdu::ApduResponse::Status::SW_WRONG_DATA) + .GetEncodedResponse()); return; } @@ -311,9 +312,9 @@ // Add signature for full response. AppendTo(&response, sig); - std::move(cb).Run( - true, apdu::ApduResponse(std::move(response), - apdu::ApduResponse::Status::SW_NO_ERROR)); + std::move(cb).Run(apdu::ApduResponse(std::move(response), + apdu::ApduResponse::Status::SW_NO_ERROR) + .GetEncodedResponse()); } } // namespace device
diff --git a/device/fido/virtual_u2f_device.h b/device/fido/virtual_u2f_device.h index b6e3a774..1f56c1d 100644 --- a/device/fido/virtual_u2f_device.h +++ b/device/fido/virtual_u2f_device.h
@@ -70,9 +70,6 @@ base::span<const uint8_t> data, DeviceCallback cb); - std::unique_ptr<crypto::ECPrivateKey> attestation_private_key_; - std::vector<uint8_t> attestation_cert_; - // Keyed on appId/rpId hash (aka "applicationParam") std::map<std::vector<uint8_t>, RegistrationData> registrations_; base::WeakPtrFactory<U2fDevice> weak_factory_;
diff --git a/docs/layout_tests_linux.md b/docs/layout_tests_linux.md index 5b62e043..33a99b7 100644 --- a/docs/layout_tests_linux.md +++ b/docs/layout_tests_linux.md
@@ -31,10 +31,10 @@ 2. Double check that ```shell -ls third_party/content_shell_fonts/content_shell_test_fonts/ +ls third_party/test_fonts/test_fonts/ ``` -is not empty and lists the fonts downloaded through the `content_shell_fonts` +is not empty and lists the fonts downloaded through the `test_fonts` hook in the top level `DEPS` file. ## Plugins
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index f583dd1..109eb54 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -196,6 +196,7 @@ "command_buffer/tests/gl_map_buffer_range_unittest.cc", "command_buffer/tests/gl_native_gmb_backbuffer_unittest.cc", "command_buffer/tests/gl_object_bindings_unittest.cc", + "command_buffer/tests/gl_oes_egl_image_unittest.cc", "command_buffer/tests/gl_offscreen_surface_unittest.cc", "command_buffer/tests/gl_oob_attrib_unittest.cc", "command_buffer/tests/gl_pointcoord_unittest.cc",
diff --git a/gpu/command_buffer/service/decoder_context.h b/gpu/command_buffer/service/decoder_context.h index 6ead2f07..ba35ca6 100644 --- a/gpu/command_buffer/service/decoder_context.h +++ b/gpu/command_buffer/service/decoder_context.h
@@ -17,6 +17,7 @@ #include "gpu/command_buffer/common/context_result.h" #include "gpu/command_buffer/service/async_api_interface.h" #include "gpu/gpu_gles2_export.h" +#include "ui/gfx/geometry/rect.h" namespace gl { class GLContext; @@ -149,6 +150,15 @@ // Gets the texture object associated with the client ID. null is returned on // failure or if the texture has not been bound yet. virtual TextureBase* GetTextureBase(uint32_t client_id) = 0; + virtual void SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) = 0; virtual void BindImage(uint32_t client_texture_id, uint32_t texture_target, gl::GLImage* image,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 6f09197..bc63c6f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -546,6 +546,16 @@ return nullptr; } +void GLES2Decoder::SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) {} + void GLES2Decoder::BeginDecoding() {} void GLES2Decoder::EndDecoding() {} @@ -681,6 +691,15 @@ bool GetServiceTextureId(uint32_t client_texture_id, uint32_t* service_texture_id) override; TextureBase* GetTextureBase(uint32_t client_id) override; + void SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) override; // Restores the current state to the user's settings. void RestoreCurrentFramebufferBindings(); @@ -4970,6 +4989,21 @@ return texture_ref ? texture_ref->texture() : nullptr; } +void GLES2DecoderImpl::SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) { + TextureRef* texture_ref = texture_manager()->GetTexture(client_id); + texture_manager()->SetLevelInfo(texture_ref, texture_ref->texture()->target(), + level, internal_format, width, height, depth, + 0 /* border */, format, type, cleared_rect); +} + void GLES2DecoderImpl::Destroy(bool have_context) { if (!initialized()) return;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index a47529b3..b9419b50 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -99,6 +99,15 @@ // DecoderContext implementation. bool initialized() const override; TextureBase* GetTextureBase(uint32_t client_id) override; + void SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) override; void BeginDecoding() override; void EndDecoding() override; base::StringPiece GetLogPrefix() override;
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 8d4fbd4..e84cc6ac 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -100,6 +100,15 @@ bool HasPollingWork() const override; void PerformPollingWork() override; TextureBase* GetTextureBase(uint32_t client_id) override; + void SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) override; bool WasContextLost() const override; bool WasContextLostByRobustnessExtension() const override; void MarkContextLost(error::ContextLostReason reason) override; @@ -402,6 +411,16 @@ return nullptr; } +void RasterDecoder::SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) {} + void RasterDecoder::BeginDecoding() {} void RasterDecoder::EndDecoding() {} @@ -643,6 +662,18 @@ return nullptr; } +void RasterDecoderImpl::SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) { + NOTIMPLEMENTED(); +} + bool RasterDecoderImpl::WasContextLost() const { return false; }
diff --git a/gpu/command_buffer/service/raster_decoder.h b/gpu/command_buffer/service/raster_decoder.h index e86e5777..64833ed 100644 --- a/gpu/command_buffer/service/raster_decoder.h +++ b/gpu/command_buffer/service/raster_decoder.h
@@ -37,6 +37,15 @@ // DecoderContext implementation. bool initialized() const override; TextureBase* GetTextureBase(uint32_t client_id) override; + void SetLevelInfo(uint32_t client_id, + int level, + unsigned internal_format, + unsigned width, + unsigned height, + unsigned depth, + unsigned format, + unsigned type, + const gfx::Rect& cleared_rect) override; void BeginDecoding() override; void EndDecoding() override; base::StringPiece GetLogPrefix() override;
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index e068885..8a19b8fa 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -461,6 +461,7 @@ decoder_->Destroy(have_context); decoder_.reset(); } + context_ = nullptr; } const GpuDriverBugWorkarounds& GLManager::workarounds() const {
diff --git a/gpu/command_buffer/tests/gl_oes_egl_image_unittest.cc b/gpu/command_buffer/tests/gl_oes_egl_image_unittest.cc new file mode 100644 index 0000000..d9c2107 --- /dev/null +++ b/gpu/command_buffer/tests/gl_oes_egl_image_unittest.cc
@@ -0,0 +1,177 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <GLES2/gl2.h> + +#include "build/build_config.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/buffer_format_util.h" +#include "ui/gl/gl_image.h" +#include "ui/gl/init/gl_factory.h" + +#if defined(OS_LINUX) +#include "ui/gl/gl_image_native_pixmap.h" +#endif + +#define SKIP_TEST_IF(cmd) \ + do { \ + if (cmd) { \ + LOG(INFO) << "Skip test because " << #cmd; \ + return; \ + } \ + } while (false) + +namespace { + +static const int kImageWidth = 64; +static const int kImageHeight = 64; + +class GpuOESEGLImageTest : public testing::Test, + public gpu::GpuCommandBufferTestEGL { + protected: + void SetUp() override { + egl_gles2_initialized_ = InitializeEGLGLES2(kImageWidth, kImageHeight); + } + + void TearDown() override { RestoreGLDefault(); } + + bool egl_gles2_initialized_; +}; + +#if defined(OS_LINUX) + +#define SHADER(Src) #Src + +// clang-format off +const char kVertexShader[] = +SHADER( + attribute vec4 a_position; + varying vec2 v_texCoord; + void main() { + gl_Position = a_position; + v_texCoord = vec2((a_position.x + 1.0) * 0.5, (a_position.y + 1.0) * 0.5); + } +); + +const char* kFragmentShader = +SHADER( + precision mediump float; + uniform sampler2D a_texture; + varying vec2 v_texCoord; + void main() { + gl_FragColor = texture2D(a_texture, v_texCoord); + } +); +// clang-format on + +// The test verifies that the content of an EGLImage can be drawn. Indeed the +// test upload some colored pixels into a GL texture. Then it creates an +// EGLImage from this texture and binds this image to draw it into another +// GL texture. At the end the test downloads the pixels from the final GL +// texture and verifies that the colors match with the pixels uploaded into +// the initial GL texture. +TEST_F(GpuOESEGLImageTest, EGLImageToTexture) { + SKIP_TEST_IF(!egl_gles2_initialized_); + + // This extension is required for creating an EGLImage from a GL texture. + SKIP_TEST_IF(!HasEGLExtension("EGL_KHR_image_base")); + + // This extension is required to render an EGLImage into a GL texture. + SKIP_TEST_IF(!HasGLExtension("GL_OES_EGL_image")); + + gfx::BufferFormat format = gfx::BufferFormat::RGBX_8888; + gfx::Size size(kImageWidth, kImageHeight); + size_t buffer_size = gfx::BufferSizeForBufferFormat(size, format); + uint8_t pixel[] = {128u, 92u, 45u, 255u}; + size_t plane = 0; + uint32_t stride = gfx::RowSizeForBufferFormat(size.width(), format, plane); + + std::unique_ptr<uint8_t[]> pixels(new uint8_t[buffer_size]); + + // Assign a value to each pixel. + for (int y = 0; y < size.height(); ++y) { + uint8_t* line = static_cast<uint8_t*>(pixels.get()) + y * stride; + for (int x = 0; x < size.width() * 4; x += 4) { + line[x + 0] = pixel[0]; + line[x + 1] = pixel[1]; + line[x + 2] = pixel[2]; + line[x + 3] = pixel[3]; + } + } + + // Create an EGLImage from a GL texture. + scoped_refptr<gl::GLImageNativePixmap> image = + CreateGLImageNativePixmap(format, size, pixels.get()); + EXPECT_TRUE(image); + EXPECT_EQ(size, image->GetSize()); + + // Need a texture to bind the image. + GLuint texture_id = 0; + glGenTextures(1, &texture_id); + ASSERT_NE(0u, texture_id); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_id); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // Make sure the texture exists in the service side. + glFinish(); + + // Bind the image. + EXPECT_TRUE(image->BindTexImage(GL_TEXTURE_2D)); + unsigned internal_format = image->GetInternalFormat(); + gl_.decoder()->SetLevelInfo( + texture_id, 0 /* level */, internal_format, size.width(), size.height(), + 1 /* depth */, internal_format, GL_UNSIGNED_BYTE, gfx::Rect(size)); + gl_.decoder()->BindImage(texture_id, GL_TEXTURE_2D, image.get(), + true /* can_bind_to_sampler */); + + // Build program, buffers and draw the texture. + GLuint vertex_shader = + gpu::GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); + GLuint fragment_shader = + gpu::GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShader); + GLuint program = + gpu::GLTestHelper::SetupProgram(vertex_shader, fragment_shader); + ASSERT_NE(0u, program); + glUseProgram(program); + + GLint sampler_location = glGetUniformLocation(program, "a_texture"); + ASSERT_NE(-1, sampler_location); + glUniform1i(sampler_location, 0); + + GLuint vbo = gpu::GLTestHelper::SetupUnitQuad( + glGetAttribLocation(program, "a_position")); + ASSERT_NE(0u, vbo); + glViewport(0, 0, kImageWidth, kImageHeight); + + // Render the EGLImage into the GL texture. + glDrawArrays(GL_TRIANGLES, 0, 6); + ASSERT_TRUE(glGetError() == GL_NO_ERROR); + + // Check if pixels match the values that were assigned to the mapped buffer. + gpu::GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixel, + nullptr); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + // Release the image. + gl_.decoder()->BindImage(texture_id, GL_TEXTURE_2D, image.get(), + false /* can_bind_to_sampler */); + image->ReleaseTexImage(GL_TEXTURE_2D); + + // Clean up. + glDeleteProgram(program); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + glDeleteBuffers(1, &vbo); + glDeleteTextures(1, &texture_id); +} +#endif // defined(OS_LINUX) + +} // namespace
diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc index 402a9694..5a3f935b 100644 --- a/gpu/command_buffer/tests/gl_test_utils.cc +++ b/gpu/command_buffer/tests/gl_test_utils.cc
@@ -11,15 +11,63 @@ #include <memory> #include <string> +#include "base/command_line.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" +#include "gpu/config/gpu_info_collector.h" +#include "gpu/config/gpu_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/init/gl_factory.h" + +#if defined(OS_LINUX) +#include "ui/gl/gl_image_native_pixmap.h" +#endif + +namespace gpu { // GCC requires these declarations, but MSVC requires they not be present. #ifndef COMPILER_MSVC const uint8_t GLTestHelper::kCheckClearValue; #endif +bool GLTestHelper::InitializeGL(gl::GLImplementation gl_impl) { + if (gl_impl == gl::GLImplementation::kGLImplementationNone) { + if (!gl::init::InitializeGLNoExtensionsOneOff()) + return false; + } else { + if (!gl::init::InitializeGLOneOffImplementation( + gl_impl, + false, // fallback_to_software_gl + false, // gpu_service_logging + false, // disable_gl_drawing + false // init_extensions + )) { + return false; + } + } + + gpu::GPUInfo gpu_info; + gpu::CollectGraphicsInfoForTesting(&gpu_info); + gpu::GLManager::g_gpu_feature_info = + gpu::ComputeGpuFeatureInfo(gpu_info, + false, // ignore_gpu_blacklist + false, // disable_gpu_driver_bug_workarounds + false, // log_gpu_control_list_decisions + base::CommandLine::ForCurrentProcess(), + nullptr // needs_more_info + ); + + gl::init::SetDisabledExtensionsPlatform( + gpu::GLManager::g_gpu_feature_info.disabled_extensions); + return gl::init::InitializeExtensionSettingsOneOffPlatform(); +} + +bool GLTestHelper::InitializeGLDefault() { + return GLTestHelper::InitializeGL( + gl::GLImplementation::kGLImplementationNone); +} + bool GLTestHelper::HasExtension(const char* extension) { // Pad with an extra space to ensure that |extension| is not a substring of // another extension. @@ -311,3 +359,105 @@ glDeleteProgram(program); glDeleteBuffers(1, &vertex_buffer); } + +GpuCommandBufferTestEGL::GpuCommandBufferTestEGL() : gl_reinitialized_(false) {} + +GpuCommandBufferTestEGL::~GpuCommandBufferTestEGL() {} + +bool GpuCommandBufferTestEGL::InitializeEGLGLES2(int width, int height) { + if (gl::GetGLImplementation() != + gl::GLImplementation::kGLImplementationEGLGLES2) { + const auto impls = gl::init::GetAllowedGLImplementations(); + if (std::find(impls.begin(), impls.end(), + gl::GLImplementation::kGLImplementationEGLGLES2) == + impls.end()) { + LOG(INFO) << "Skip test, implementation EGLGLES2 is not available"; + return false; + } + + gl_reinitialized_ = true; + gl::init::ShutdownGL(false /* due_to_fallback */); + if (!GLTestHelper::InitializeGL( + gl::GLImplementation::kGLImplementationEGLGLES2)) { + LOG(INFO) << "Skip test, failed to initialize EGLGLES2"; + return false; + } + } + + DCHECK_EQ(gl::GLImplementation::kGLImplementationEGLGLES2, + gl::GetGLImplementation()); + + // Make the GL context current now to get all extensions. + GLManager::Options options; + options.size = gfx::Size(width, height); + gl_.Initialize(options); + gl_.MakeCurrent(); + + bool result = + gl::init::GetGLWindowSystemBindingInfo(&window_system_binding_info_); + DCHECK(result); + + egl_extensions_ = + gl::MakeExtensionSet(window_system_binding_info_.extensions); + gl_extensions_ = + gl::MakeExtensionSet(gl::GetGLExtensionsFromCurrentContext()); + + return true; +} + +void GpuCommandBufferTestEGL::RestoreGLDefault() { + gl_.Destroy(); + + if (gl_reinitialized_) { + gl::init::ShutdownGL(false /* due_to_fallback */); + GLTestHelper::InitializeGLDefault(); + } + + gl_reinitialized_ = false; + gl_extensions_.clear(); + egl_extensions_.clear(); + window_system_binding_info_ = gl::GLWindowSystemBindingInfo(); +} + +#if defined(OS_LINUX) +scoped_refptr<gl::GLImageNativePixmap> +GpuCommandBufferTestEGL::CreateGLImageNativePixmap(gfx::BufferFormat format, + gfx::Size size, + uint8_t* pixels) const { + // Upload raw pixels to a new GL texture. + GLuint tex_client_id = 0; + glGenTextures(1, &tex_client_id); + DCHECK_NE(0u, tex_client_id); + glBindTexture(GL_TEXTURE_2D, tex_client_id); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Make sure the texture exists in the service side. + glFinish(); + + // This works because the test run in a similar mode as In-Process-GPU. + unsigned int tex_service_id = 0; + gl_.decoder()->GetServiceTextureId(tex_client_id, &tex_service_id); + EXPECT_NE(0u, tex_service_id); + + // Create an EGLImage from the real texture id. + scoped_refptr<gl::GLImageNativePixmap> image(new gl::GLImageNativePixmap( + size, gl::GLImageNativePixmap::GetInternalFormatForTesting(format))); + bool result = image->InitializeFromTexture(tex_service_id); + DCHECK(result); + + // The test will own the EGLImage no need to keep a reference on the GL + // texture after returning from this function. This is covered by the + // EGL_KHR_image_base.txt specification, i.e. the underlying memory remains + // allocated as long as there is at least one sibling (like ref count). + glDeleteTextures(1, &tex_client_id); + + return image; +} +#endif + +} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_test_utils.h b/gpu/command_buffer/tests/gl_test_utils.h index 3a1641e..0bd40280 100644 --- a/gpu/command_buffer/tests/gl_test_utils.h +++ b/gpu/command_buffer/tests/gl_test_utils.h
@@ -12,10 +12,23 @@ #include <vector> +#include "build/build_config.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "ui/gl/gl_implementation.h" + +namespace gl { +class GLImageNativePixmap; +} + +namespace gpu { + class GLTestHelper { public: static const uint8_t kCheckClearValue = 123u; + static bool InitializeGL(gl::GLImplementation gl_impl); + static bool InitializeGLDefault(); + static bool HasExtension(const char* extension); static bool CheckGLError(const char* msg, int line); @@ -76,4 +89,45 @@ const char* face_name); }; +class GpuCommandBufferTestEGL { + public: + GpuCommandBufferTestEGL(); + ~GpuCommandBufferTestEGL(); + + // Reinitialize GL to the EGLGLES2 implementation if it is available and not + // the current initialized GL implementation. Return true on sucess, false + // otherwise. + bool InitializeEGLGLES2(int width, int height); + + // Restore the default GL implementation. + void RestoreGLDefault(); + + // Returns whether the current context supports the named EGL extension. + bool HasEGLExtension(const base::StringPiece& extension) { + return gl::HasExtension(egl_extensions_, extension); + } + + // Returns whether the current context supports the named GL extension. + bool HasGLExtension(const base::StringPiece& extension) { + return gl::HasExtension(gl_extensions_, extension); + } + +#if defined(OS_LINUX) + // Create GLImageNativePixmap filled in with the given pixels. + scoped_refptr<gl::GLImageNativePixmap> CreateGLImageNativePixmap( + gfx::BufferFormat format, + gfx::Size size, + uint8_t* pixels) const; +#endif + + protected: + bool gl_reinitialized_; + GLManager gl_; + gl::GLWindowSystemBindingInfo window_system_binding_info_; + gl::ExtensionSet egl_extensions_; + gl::ExtensionSet gl_extensions_; +}; + +} // namespace gpu + #endif // GPU_COMMAND_BUFFER_TESTS_GL_TEST_UTILS_H_
diff --git a/gpu/command_buffer/tests/gl_tests_main.cc b/gpu/command_buffer/tests/gl_tests_main.cc index 2d9a5449..021ac07 100644 --- a/gpu/command_buffer/tests/gl_tests_main.cc +++ b/gpu/command_buffer/tests/gl_tests_main.cc
@@ -4,7 +4,6 @@ #include "base/at_exit.h" #include "base/bind.h" -#include "base/command_line.h" #include "base/feature_list.h" #include "base/message_loop/message_loop.h" #if defined(OS_MACOSX) @@ -13,12 +12,8 @@ #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/tests/gl_manager.h" -#include "gpu/config/gpu_driver_bug_workarounds.h" -#include "gpu/config/gpu_info_collector.h" -#include "gpu/config/gpu_util.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" -#include "ui/gl/init/gl_factory.h" namespace { @@ -29,18 +24,7 @@ base::MessageLoopForIO message_loop; #endif base::FeatureList::InitializeInstance(std::string(), std::string()); - gl::init::InitializeGLNoExtensionsOneOff(); - gpu::GPUInfo gpu_info; - gpu::CollectGraphicsInfoForTesting(&gpu_info); - gpu::GLManager::g_gpu_feature_info = gpu::ComputeGpuFeatureInfo( - gpu_info, - false, // ignore_gpu_blacklist - false, // disable_gpu_driver_bug_workarounds - false, // log_gpu_control_list_decisions - base::CommandLine::ForCurrentProcess(), nullptr); - gl::init::SetDisabledExtensionsPlatform( - gpu::GLManager::g_gpu_feature_info.disabled_extensions); - gl::init::InitializeExtensionSettingsOneOffPlatform(); + gpu::GLTestHelper::InitializeGLDefault(); ::gles2::Initialize(); return testSuite->Run(); }
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc index 4d262b7..4c1f72e 100644 --- a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc +++ b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc
@@ -7,6 +7,7 @@ #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/client_native_pixmap.h" #include "ui/gfx/native_pixmap.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image_native_pixmap.h" #if defined(USE_OZONE)
diff --git a/headless/lib/dom_tree_extraction_expected_nodes.txt b/headless/lib/dom_tree_extraction_expected_nodes.txt index 588c8b0..f27c42d 100644 --- a/headless/lib/dom_tree_extraction_expected_nodes.txt +++ b/headless/lib/dom_tree_extraction_expected_nodes.txt
@@ -276,6 +276,13 @@ "nodeValue": "\n" } { + "attributes": [ { + "name": "style", + "value": "font-family: \"SlightHintedTimesNewRoman\", \"Times New Roman\"" + }, { + "name": ";\"", + "value": "" + } ], "backendNodeId": 26, "boundingBox": { "height": 37.0,
diff --git a/headless/lib/dom_tree_extraction_expected_styles.txt b/headless/lib/dom_tree_extraction_expected_styles.txt index 1d2a58023..d78ea8c 100644 --- a/headless/lib/dom_tree_extraction_expected_styles.txt +++ b/headless/lib/dom_tree_extraction_expected_styles.txt
@@ -61,7 +61,7 @@ { "color": "rgb(0, 0, 0)", "display": "block", - "font-family": "\"Times New Roman\"", + "font-family": "SlightHintedTimesNewRoman, \"Times New Roman\"", "font-style": "normal", "margin-bottom": "21.44px", "margin-left": "0px",
diff --git a/headless/test/data/iframe.html b/headless/test/data/iframe.html index 655c965..1e8b7fe 100644 --- a/headless/test/data/iframe.html +++ b/headless/test/data/iframe.html
@@ -1,5 +1,5 @@ <html> <body> -<h1>Hello from the iframe!</h1> +<h1 style='font-family: "SlightHintedTimesNewRoman", "Times New Roman"';">Hello from the iframe!</h1> </body> </html>
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index 09fd2bb..089b878 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -714,67 +714,55 @@ builders { name: "Win10 FYI Debug (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-10" + mixins: "gpu-slow-bot" } builders { name: "Win10 FYI dEQP Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-10" } builders { name: "Win10 FYI Exp Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-10" } builders { name: "Win10 FYI Release (Intel HD 630)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-10" } builders { name: "Win10 FYI Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-10" } builders { name: "Win7 FYI Debug (AMD)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI Debug (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI dEQP Release (AMD)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI Release (AMD)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI x64 Debug (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI x64 dEQP Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } builders { name: "Win7 FYI x64 Release (NVIDIA)" mixins: "win-gpu-fyi-ci" - dimensions: "os:Windows-7" } } }
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm index 3d66bae..5f332d9 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
@@ -41,6 +41,7 @@ #include "ios/chrome/grit/ios_strings.h" #import "ios/web/public/web_state/context_menu_params.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/time_format.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -76,6 +77,9 @@ int const kNumberOfSectionsBeforeSessions = 2; // Estimated Table Row height. const CGFloat kEstimatedRowHeight = 56; +// The UI displays relative time for up to this number of hours and then +// switches to absolute values. +const int kRelativeTimeMaxHours = 4; } // namespace @@ -271,6 +275,9 @@ [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeSessionHeader]; header.text = base::SysUTF8ToNSString(session->name); + header.subtitleText = l10n_util::GetNSStringF( + IDS_IOS_OPEN_TABS_LAST_USED, + base::SysNSStringToUTF16([self lastSyncStringForSesssion:session])); [model setHeader:header forSectionWithIdentifier:sessionIdentifier]; [self addItemsForSession:session]; } @@ -609,6 +616,43 @@ return session->tabs[indexOfDistantTab].get(); } +- (NSString*)lastSyncStringForSesssion: + (synced_sessions::DistantSession const*)session { + base::Time time = session->modified_time; + NSDate* lastUsedDate = [NSDate dateWithTimeIntervalSince1970:time.ToTimeT()]; + NSString* dateString = + [NSDateFormatter localizedStringFromDate:lastUsedDate + dateStyle:NSDateFormatterShortStyle + timeStyle:NSDateFormatterNoStyle]; + + NSString* timeString; + base::TimeDelta last_used_delta; + if (base::Time::Now() > time) + last_used_delta = base::Time::Now() - time; + + if (last_used_delta.InMicroseconds() < base::Time::kMicrosecondsPerMinute) { + timeString = l10n_util::GetNSString(IDS_IOS_OPEN_TABS_RECENTLY_SYNCED); + // This will return something similar to "Seconds ago mm/dd/yy" + return [NSString stringWithFormat:@"%@ %@", timeString, dateString]; + } + + if (last_used_delta.InHours() < kRelativeTimeMaxHours) { + timeString = base::SysUTF16ToNSString( + ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, + ui::TimeFormat::LENGTH_SHORT, last_used_delta)); + // This will return something similar to "1 min/hour ago mm/dd/yy" + return [NSString stringWithFormat:@"%@ %@", timeString, dateString]; + } + + NSDate* date = [NSDate dateWithTimeIntervalSince1970:time.ToTimeT()]; + timeString = + [NSDateFormatter localizedStringFromDate:date + dateStyle:NSDateFormatterNoStyle + timeStyle:NSDateFormatterShortStyle]; + // This will return something similar to "H:MM mm/dd/yy" + return [NSString stringWithFormat:@"%@ %@", timeString, dateString]; +} + #pragma mark - Navigation helpers - (void)dismissRecentTabsModal {
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn index e3dfc1c..9c698007 100644 --- a/ios/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -53,6 +53,8 @@ "grid_view_controller.mm", "tab_grid_bottom_toolbar.h", "tab_grid_bottom_toolbar.mm", + "tab_grid_page_control.h", + "tab_grid_page_control.mm", "tab_grid_paging.h", "tab_grid_top_toolbar.h", "tab_grid_top_toolbar.mm",
diff --git a/ios/chrome/browser/ui/tab_grid/grid_layout.mm b/ios/chrome/browser/ui/tab_grid/grid_layout.mm index d1307de..3af4b66 100644 --- a/ios/chrome/browser/ui/tab_grid/grid_layout.mm +++ b/ios/chrome/browser/ui/tab_grid/grid_layout.mm
@@ -15,11 +15,13 @@ @interface GridLayout () @property(nonatomic, assign) CGFloat startingTabWidth; @property(nonatomic, assign) CGFloat maxTabWidth; +@property(nonatomic, strong) NSArray<NSIndexPath*>* indexPathsOfDeletingItems; @end @implementation GridLayout @synthesize startingTabWidth = _startingTabWidth; @synthesize maxTabWidth = _maxTabWidth; +@synthesize indexPathsOfDeletingItems = _indexPathsOfDeletingItems; - (instancetype)init { if (self = [super init]) { @@ -42,6 +44,44 @@ } } +- (void)prepareForCollectionViewUpdates: + (NSArray<UICollectionViewUpdateItem*>*)updateItems { + NSMutableArray<NSIndexPath*>* deletingItems = + [NSMutableArray arrayWithCapacity:updateItems.count]; + for (UICollectionViewUpdateItem* item in updateItems) { + if (item.updateAction == UICollectionUpdateActionDelete) { + [deletingItems addObject:item.indexPathBeforeUpdate]; + } + } + self.indexPathsOfDeletingItems = [deletingItems copy]; +} + +- (UICollectionViewLayoutAttributes*) +finalLayoutAttributesForDisappearingItemAtIndexPath: + (NSIndexPath*)itemIndexPath { + UICollectionViewLayoutAttributes* attributes = + [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath]; + // Disappearing items that aren't being deleted just use the default + // attributes. + if (![self.indexPathsOfDeletingItems containsObject:itemIndexPath]) { + return attributes; + } + // Cells being deleted fade out, are scaled down, and drop downwards slightly. + attributes.alpha = 0.0; + // Scaled down to 60%. + CGAffineTransform transform = + CGAffineTransformScale(attributes.transform, 0.6, 0.6); + // Translated down (positive-y direction) by 50% of the cell cell size. + transform = + CGAffineTransformTranslate(transform, 0, attributes.size.height * 0.5); + attributes.transform = transform; + return attributes; +} + +- (void)finalizeCollectionViewUpdates { + self.indexPathsOfDeletingItems = @[]; +} + #pragma mark - Private // This sets the appropriate itemSize given the width of the collection view.
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h new file mode 100644 index 0000000..2418fc4 --- /dev/null +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_ +#define IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h" + +// A three-sectioned control for selecting a page in the tab grid. +// A "slider" is positioned over the section for the selected page. +// This is a fixed-size control; it's an error to set or change its size. +// The sections are arranged in leading-to-trailing order: +// incognito tabs, regular tabs, remote tabs. +@interface TabGridPageControl : UIControl + +// The currently selected page in the control. When this value is changed by +// a user interaction, the UIControlEventValueChanged actions are sent. +// Setting this property will update the position of the slider without +// animation. When an instance of this control is created, this value defaults +// to TabGridPageRegularTabs. +@property(nonatomic, assign) TabGridPage selectedPage; +// The position of the slider, from 0.0 to 1.0, where 0.0 is as far as possible +// to the leading side of the control, and 1.0 is as far as possible to the +// trailing side of the control. Setting this property will update the position +// of the slider without animation. Setting a value below 0.0 or above 1.0 will +// set 0.0 or 1.0 instead. +// Setting this property will *not* update the selected page. +@property(nonatomic, assign) CGFloat sliderPosition; + +// Text displayed next to the incognito and inside the regular tabs icons. The +// available space for text is small -- no wider than two numerals. Text wider +// than this will be clipped. +@property(nonatomic, copy) NSString* incognitoText; +@property(nonatomic, copy) NSString* regularText; + +// Create and return a new instance of this control. This is the preferred way +// to create instances of this class. ++ (instancetype)pageControl; + +// Designated initializer. +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; + +// Set |selectedPage| as the selected page. If |animated| is YES, the +// position change of the slider will be animated. +- (void)setSelectedPage:(TabGridPage)selectedPage animated:(BOOL)animated; + +@end + +#endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm new file mode 100644 index 0000000..25525835 --- /dev/null +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_page_control.mm
@@ -0,0 +1,474 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h" + +#import <CoreGraphics/CoreGraphics.h> + +#include "base/logging.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Structure of this control: +// +// The page control is similar to a UISegmentedCoffee in appearance, but not in +// function. This control doesn't have segments that highlight; instead there +// is a white "slider" that moves across the view onto whichever segment is +// active. Each segment has an image and (optionally) a label. When the slider +// is over a segment, the corresponding image and label are colored black-on- +// white and are slightly larger. This is implemented by having two versions of +// each image and label; the larger "selected" versions are positioned above the +// smaller ones in the view hierarchy but are masked out by the slider view, so +// they are only seen when the slider is over them. +// +// This control is built out of several views. From the bottom up, they are: +// +// * The background view, a grey roundrect with vertical transparent bars. +// * The background image views. +// * The numeric labels on the incognito and regular tab icons. +// * The "slider" view -- a white roundrect that's taller and wider than each +// of the background segments. It clips its subview to its bounds, and it +// adjusts its subview's frame so that it (the subview) remains fixed +// relative to the background. +// * The selected image view, which contains the selected images and labels +// and is a subview of the slider. +// * The selected images and labels. +// +// (Note that currently only labels are used; images will be added once assets +// are available). + +// Notes on layout: +// This control has an intrinsic size, and generally ignores frame changes. It's +// not expected that its bounds will ever change. +// Given that, it's generally simpler to used fixed (frame-based) layout for +// most of the content of this control. However, in order to acommodate RTL +// layout, three layout guides are used to define the position of the +// incognito, regular, and remote tab sections. The layout frames of these +// guides are used to map points in the view to specific TabGridPage values. +// This means that the initial view layout for this control happens in two +// phases. -setupViews creates all of the subviews and the layout guides, but +// the positions of the images and labels is set in -layoutSubviews, after the +// constrainst for the guides have been applied. + +namespace { +// Height and width of the slider. +const CGFloat kSliderHeight = 40.0; +const CGFloat kSliderWidth = 78.0; + +// Height and width of each segment. +const CGFloat kSegmentHeight = 36.0; +const CGFloat kSegmentWidth = 64.0; + +// Points that the slider overhangs a segment on each side, or 0 if the slider +// is narrower than a segment. +const CGFloat kSliderOverhang = MAX((kSliderWidth - kSegmentWidth) / 2.0, 0.0); + +// Width of the separator bars between segments. +const CGFloat kSeparatorWidth = 1.0; + +// Width of the background -- three segments plus two separators. +const CGFloat kBackgroundWidth = 3 * kSegmentWidth + 2 * kSeparatorWidth; + +// Overall height of the control -- the larger of the slider and segment +// heights. +const CGFloat kOverallHeight = MAX(kSliderHeight, kSegmentHeight); +// Overall width of the control -- the background width plusand twice +// the slider overhang. +const CGFloat kOverallWidth = kBackgroundWidth + 2 * kSliderOverhang; + +// Radius used to draw the background and the slider. +const CGFloat kCornerRadius = 13.0; + +// Sizes for the labels and their selected counterparts. +const CGFloat kLabelSize = 20.0; +const CGFloat kSelectedLabelSize = 23.0; + +// Maximum duration of slider motion animation. +const NSTimeInterval kSliderMoveDuration = 0.2; + +// Color for the slider +const int kSliderColor = 0xF8F9FA; +// Color for the background view. +const int kBackgroundColor = 0x5F6368; + +// Returns the point that's at the center of |rect|. +CGPoint RectCenter(CGRect rect) { + return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); +} +} + +// View class used for the background of this control; it draws the grey +// rectangles with clear separators. +@interface TabGridPageControlBackground : UIView +@end + +@interface TabGridPageControl ()<UIGestureRecognizerDelegate> +// Layout guides used to position segment-specific content. +@property(nonatomic, weak) UILayoutGuide* incognitoGuide; +@property(nonatomic, weak) UILayoutGuide* regularGuide; +@property(nonatomic, weak) UILayoutGuide* remoteGuide; +// The view for the slider. +@property(nonatomic, weak) UIView* sliderView; +// The view for the selected images and labels (a subview of |sliderView). +@property(nonatomic, weak) UIView* selectedImageView; +// The labels for the incognito and regular sections, in regular and selected +// variants. +@property(nonatomic, weak) UILabel* incognitoLabel; +@property(nonatomic, weak) UILabel* incognitoSelectedLabel; +@property(nonatomic, weak) UILabel* regularLabel; +@property(nonatomic, weak) UILabel* regularSelectedLabel; +// Temporary labels for the remote tabs section, to be replaced by image assets. +@property(nonatomic, weak) UILabel* remoteLabel; +@property(nonatomic, weak) UILabel* remoteSelectedLabel; +// The center point for the slider corresponding to a |sliderPosition| of 0. +@property(nonatomic) CGFloat sliderOrigin; +// The (signed) x-coordinate distance the slider moves over. The slider's +// position is set by adding a fraction of this distance to |sliderOrigin|, so +// that when |sliderRange| is negative (in RTL layout), the slider will move in +// the negative-x direction from |sliderOrigin|, and otherwise it will move in +// the positive-x direction. +@property(nonatomic) CGFloat sliderRange; +@end + +@implementation TabGridPageControl +// Public properties +@synthesize selectedPage = _selectedPage; +@synthesize sliderPosition = _sliderPosition; +@synthesize incognitoText = _incognitoText; +@synthesize regularText = _regularText; +// Private properties +@synthesize incognitoGuide = _incognitoGuide; +@synthesize regularGuide = _regularGuide; +@synthesize remoteGuide = _remoteGuide; +@synthesize sliderView = _sliderView; +@synthesize selectedImageView = _selectedImageView; +@synthesize incognitoLabel = _incognitoLabel; +@synthesize incognitoSelectedLabel = _incognitoSelectedLabel; +@synthesize regularLabel = _regularLabel; +@synthesize regularSelectedLabel = _regularSelectedLabel; +@synthesize remoteLabel = _remoteLabel; +@synthesize remoteSelectedLabel = _remoteSelectedLabel; +@synthesize sliderOrigin = _sliderOrigin; +@synthesize sliderRange = _sliderRange; + ++ (instancetype)pageControl { + return [[TabGridPageControl alloc] init]; +} + +- (instancetype)init { + CGRect frame = CGRectMake(0, 0, kOverallWidth, kOverallHeight); + if (self = [super initWithFrame:frame]) { + // Default to the regular tab page as the selected page. + + _selectedPage = TabGridPageRegularTabs; + } + return self; +} + +#pragma mark - Public Properies + +- (void)setSelectedPage:(TabGridPage)selectedPage { + [self setSelectedPage:selectedPage animated:NO]; +} + +- (void)setSliderPosition:(CGFloat)sliderPosition { + // Clamp |selectionOffset| to (0.0 - 1.0). + sliderPosition = MIN(MAX(0.0, sliderPosition), 1.0); + CGPoint center = self.sliderView.center; + center.x = self.sliderOrigin + self.sliderRange * sliderPosition; + self.sliderView.center = center; + // Reposition the selected image view so that it's still centered in the + // control itself. + self.selectedImageView.center = + [self convertPoint:RectCenter(self.bounds) toView:self.sliderView]; + _sliderPosition = sliderPosition; +} + +// Setters for the control's text values. These need to update three things: +// the text in both labels (the regular and the "selected" versions that's +// visible when the slider is over a segment), and an ivar to store values that +// are set before the labels are created. +- (void)setIncognitoText:(NSString*)incognitoText { + self.incognitoLabel.text = incognitoText; + self.incognitoSelectedLabel.text = incognitoText; + _incognitoText = [incognitoText copy]; +} + +- (void)setRegularText:(NSString*)regularText { + self.regularLabel.text = regularText; + self.regularSelectedLabel.text = regularText; + _regularText = [regularText copy]; +} + +#pragma mark - Public methods + +- (void)setSelectedPage:(TabGridPage)selectedPage animated:(BOOL)animated { + CGFloat newPosition; + switch (selectedPage) { + case TabGridPageIncognitoTabs: + newPosition = 0.0; + break; + case TabGridPageRegularTabs: + newPosition = 0.5; + break; + case TabGridPageRemoteTabs: + newPosition = 1.0; + break; + } + if (self.selectedPage == selectedPage && newPosition == self.sliderPosition) { + return; + } + + _selectedPage = selectedPage; + if (animated) { + // Scale duration to the distance the slider travels, but cap it at + // the slider move duration. This means that for motion induced by + // tapping on a section, the duration will be the same even if the slider + // is moving across two segments. + CGFloat offsetDelta = abs(newPosition - self.sliderPosition); + NSTimeInterval duration = offsetDelta * kSliderMoveDuration; + [UIView animateWithDuration:MIN(duration, kSliderMoveDuration) + animations:^{ + self.sliderPosition = newPosition; + }]; + } else { + self.sliderPosition = newPosition; + } +} + +#pragma mark - UIView + +- (CGSize)intrinsicContentSize { + return CGSizeMake(kOverallWidth, kOverallHeight); +} + +- (void)willMoveToSuperview:(UIView*)newSuperview { + // The first time this moves to a superview, perform the view setup. + if (newSuperview && self.subviews.count == 0) { + [self setupViews]; + } +} + +- (void)layoutSubviews { + // The superclass call should be made first, so the constraint-based layout + // guides can be set correctly. + [super layoutSubviews]; + // Position the section images and labels, which depend on the layout guides. + self.incognitoLabel.center = [self centerOfSegment:TabGridPageIncognitoTabs]; + self.incognitoSelectedLabel.center = + [self centerOfSegment:TabGridPageIncognitoTabs]; + + self.regularLabel.center = [self centerOfSegment:TabGridPageRegularTabs]; + self.regularSelectedLabel.center = + [self centerOfSegment:TabGridPageRegularTabs]; + + self.remoteLabel.center = [self centerOfSegment:TabGridPageRemoteTabs]; + self.remoteSelectedLabel.center = + [self centerOfSegment:TabGridPageRemoteTabs]; + + // Determine the slider origin and range; this is based on the layout guides + // and can't be computed until they are determined. + self.sliderOrigin = CGRectGetMidX(self.incognitoGuide.layoutFrame); + self.sliderRange = + CGRectGetMidX(self.remoteGuide.layoutFrame) - self.sliderOrigin; + + // Set the slider position using the new slider origin and range. + self.sliderPosition = _sliderPosition; +} + +#pragma mark - Private + +// Sets up all of the subviews for this control, as well as the layout guides +// used to position the section content. +- (void)setupViews { + UIView* backgroundView = [[TabGridPageControlBackground alloc] init]; + backgroundView.layer.cornerRadius = kCornerRadius; + backgroundView.layer.masksToBounds = YES; + [self addSubview:backgroundView]; + backgroundView.center = + CGPointMake(kOverallWidth / 2.0, kOverallHeight / 2.0); + + // Set up the layout guides for the segments. + UILayoutGuide* incognitoGuide = [[UILayoutGuide alloc] init]; + [self addLayoutGuide:incognitoGuide]; + self.incognitoGuide = incognitoGuide; + UILayoutGuide* regularGuide = [[UILayoutGuide alloc] init]; + [self addLayoutGuide:regularGuide]; + self.regularGuide = regularGuide; + UILayoutGuide* remoteGuide = [[UILayoutGuide alloc] init]; + [self addLayoutGuide:remoteGuide]; + self.remoteGuide = remoteGuide; + + // All of the guides are of the same height, and vertically centered in the + // control. + for (UILayoutGuide* guide in @[ incognitoGuide, regularGuide, remoteGuide ]) { + [guide.heightAnchor constraintEqualToConstant:kOverallHeight].active = YES; + [guide.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = + YES; + } + + // Guides are all the same width (except the regular guide is wider to include + // the separators on either side of it. The regular guide is centered in the + // control, and the incognito and remote guides are on the leading and + // trailing sides of it. + [NSLayoutConstraint activateConstraints:@[ + [incognitoGuide.widthAnchor constraintEqualToConstant:kSegmentWidth], + [regularGuide.widthAnchor + constraintEqualToConstant:kSegmentWidth + 2 * kSeparatorWidth], + [remoteGuide.widthAnchor constraintEqualToConstant:kSegmentWidth], + [regularGuide.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], + [incognitoGuide.trailingAnchor + constraintEqualToAnchor:regularGuide.leadingAnchor], + [remoteGuide.leadingAnchor + constraintEqualToAnchor:regularGuide.trailingAnchor] + ]]; + + // Create the section images and labels and add them below the slider. + UILabel* incognitoLabel = [self labelSelected:NO incognito:YES]; + [self addSubview:incognitoLabel]; + self.incognitoLabel = incognitoLabel; + + UILabel* regularLabel = [self labelSelected:NO incognito:NO]; + [self addSubview:regularLabel]; + self.regularLabel = regularLabel; + + // Add the slider above the section images and labels. + CGRect sliderFrame = CGRectMake(0, 0, kSliderWidth, kSliderHeight); + UIView* slider = [[UIView alloc] initWithFrame:sliderFrame]; + slider.layer.cornerRadius = kCornerRadius; + slider.layer.masksToBounds = YES; + slider.backgroundColor = UIColorFromRGB(kSliderColor); + + [self addSubview:slider]; + self.sliderView = slider; + + UIView* selectedImageView = [[UIView alloc] + initWithFrame:(CGRectMake(0, 0, kOverallWidth, kOverallHeight))]; + [self.sliderView addSubview:selectedImageView]; + self.selectedImageView = selectedImageView; + + // Add the selected images and labels to the selected image view so they + // will be clipped by it. + UILabel* incognitoSelectedLabel = [self labelSelected:YES incognito:YES]; + [self.selectedImageView addSubview:incognitoSelectedLabel]; + self.incognitoSelectedLabel = incognitoSelectedLabel; + + UILabel* regularSelectedLabel = [self labelSelected:YES incognito:NO]; + [self.selectedImageView addSubview:regularSelectedLabel]; + self.regularSelectedLabel = regularSelectedLabel; + + // Create a temporary label for the remote tabs section. + // TODO(crbug.com/804500): Remove this when assets are available. + UILabel* remoteLabel = [self labelSelected:NO incognito:NO]; + [self insertSubview:remoteLabel belowSubview:self.sliderView]; + self.remoteLabel = remoteLabel; + UILabel* remoteSelectedLabel = [self labelSelected:YES incognito:NO]; + [self.selectedImageView addSubview:remoteSelectedLabel]; + self.remoteSelectedLabel = remoteSelectedLabel; + remoteLabel.text = @"R"; + remoteSelectedLabel.text = @"R"; + + // Update the label text, in case these properties have been set before the + // views were set up. + self.regularText = _regularText; + self.incognitoText = _incognitoText; + + // Mark the control's layout as dirty so the the guides will be computed, then + // force a layout now so it won't be triggered later (perhaps during an + // animation). + [self setNeedsLayout]; + [self layoutIfNeeded]; + + // Add the gesture recognizer for taps on this control. + UITapGestureRecognizer* tapRecognizer = + [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(handleTap:)]; + [self addGestureRecognizer:tapRecognizer]; +} + +// Creates a label for use in this control. +// Selected labels use a different size and are black. +// Incognito labels have a solid background and use inverted text. +- (UILabel*)labelSelected:(BOOL)selected incognito:(BOOL)incognito { + CGFloat size = selected ? kSelectedLabelSize : kLabelSize; + UIColor* color = selected ? UIColor.blackColor : UIColor.lightGrayColor; + UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size, size)]; + label.backgroundColor = incognito ? color : UIColor.clearColor; + label.layer.borderWidth = 2.5; + label.layer.borderColor = color.CGColor; + label.layer.masksToBounds = YES; + label.layer.cornerRadius = 6.0; + label.textAlignment = NSTextAlignmentCenter; + label.textColor = incognito ? (selected ? UIColorFromRGB(kSliderColor) + : UIColorFromRGB(kBackgroundColor)) + : color; + label.font = + [UIFont systemFontOfSize:size * .6 weight:UIFontWeightBold]; // ? + return label; +} + +// Handles tap gesture recognizer taps, setting a new selected page if the +// tap was outside the current page and sending the value changed actions. +- (void)handleTap:(UIGestureRecognizer*)tapRecognizer { + CGPoint point = [tapRecognizer locationInView:self]; + // Determine which section the tap is in by looking at the layout frames of + // each guide. + TabGridPage page; + if (CGRectContainsPoint(self.incognitoGuide.layoutFrame, point)) { + page = TabGridPageIncognitoTabs; + } else if (CGRectContainsPoint(self.remoteGuide.layoutFrame, point)) { + page = TabGridPageRemoteTabs; + } else { + // bug: taps in the left- or rightmost |kSliderOverhang| points of the + // control will fall through to this case. + // TODO(crbug.com/804500): Fix this. + page = TabGridPageRegularTabs; + } + if (page != self.selectedPage) { + [self setSelectedPage:page animated:YES]; + [self sendActionsForControlEvents:UIControlEventValueChanged]; + } +} + +// Returns the point at the center of |segment|. +- (CGPoint)centerOfSegment:(TabGridPage)segment { + switch (segment) { + case TabGridPageIncognitoTabs: + return RectCenter(self.incognitoGuide.layoutFrame); + case TabGridPageRegularTabs: + return RectCenter(self.regularGuide.layoutFrame); + case TabGridPageRemoteTabs: + return RectCenter(self.remoteGuide.layoutFrame); + } +} + +@end + +@implementation TabGridPageControlBackground + +- (instancetype)init { + return + [super initWithFrame:CGRectMake(0, 0, kBackgroundWidth, kSegmentHeight)]; +} + +- (CGSize)intrinsicContentsSize { + return CGSizeMake(kBackgroundWidth, kSegmentHeight); +} + +- (void)drawRect:(CGRect)rect { + CGContextRef drawing = UIGraphicsGetCurrentContext(); + UIColor* backgroundColor = UIColorFromRGB(kBackgroundColor); + CGContextSetFillColorWithColor(drawing, backgroundColor.CGColor); + CGRect fillRect = CGRectMake(0, 0, kSegmentWidth, kSegmentHeight); + CGContextFillRect(drawing, fillRect); + fillRect.origin.x += kSegmentWidth + kSeparatorWidth; + CGContextFillRect(drawing, fillRect); + fillRect.origin.x += kSegmentWidth + kSeparatorWidth; + CGContextFillRect(drawing, fillRect); +} + +@end
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h index f28fd18..a2906d3 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h
@@ -7,6 +7,8 @@ #import <UIKit/UIKit.h> +@class TabGridPageControl; + // Toolbar view with two text buttons and a segmented control. The contents have // a fixed height and are pinned to the bottom of this view, therefore it is // intended to be used as a top toolbar. @@ -15,7 +17,7 @@ // contents, visibility and actions. @property(nonatomic, weak, readonly) UIButton* leadingButton; @property(nonatomic, weak, readonly) UIButton* trailingButton; -@property(nonatomic, weak, readonly) UIView* segmentedControl; +@property(nonatomic, weak, readonly) TabGridPageControl* pageControl; - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm index e011ad4..8e549ce7 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm
@@ -4,22 +4,21 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h" +#import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif namespace { // Height of the toolbar. -const CGFloat kToolbarHeight = 44.0f; -// Height of the segmented control. The segmented control should have an -// intrinsic width. -const CGFloat kSegmentedControlHeight = 30.0f; +const CGFloat kToolbarHeight = 52.0f; } // namespace @implementation TabGridTopToolbar @synthesize leadingButton = _leadingButton; @synthesize trailingButton = _trailingButton; -@synthesize segmentedControl = _segmentedControl; +@synthesize pageControl = _pageControl; - (instancetype)init { if (self = [super initWithFrame:CGRectZero]) { @@ -37,12 +36,9 @@ leadingButton.titleLabel.adjustsFontForContentSizeCategory = YES; leadingButton.tintColor = [UIColor whiteColor]; - UILabel* segmentedControl = [[UILabel alloc] init]; - segmentedControl.translatesAutoresizingMaskIntoConstraints = NO; - segmentedControl.backgroundColor = [UIColor whiteColor]; - segmentedControl.text = @"Segmented Control"; - segmentedControl.layer.cornerRadius = 11.0f; - segmentedControl.layer.masksToBounds = YES; + // The segmented control has an intrinsic size. + TabGridPageControl* pageControl = [[TabGridPageControl alloc] init]; + pageControl.translatesAutoresizingMaskIntoConstraints = NO; UIButton* trailingButton = [UIButton buttonWithType:UIButtonTypeSystem]; trailingButton.translatesAutoresizingMaskIntoConstraints = NO; @@ -53,10 +49,10 @@ [toolbar.contentView addSubview:leadingButton]; [toolbar.contentView addSubview:trailingButton]; - [toolbar.contentView addSubview:segmentedControl]; + [toolbar.contentView addSubview:pageControl]; _leadingButton = leadingButton; _trailingButton = trailingButton; - _segmentedControl = segmentedControl; + _pageControl = pageControl; NSArray* constraints = @[ [toolbar.topAnchor constraintEqualToAnchor:self.topAnchor], @@ -67,13 +63,9 @@ [leadingButton.leadingAnchor constraintEqualToAnchor:toolbar.layoutMarginsGuide.leadingAnchor], [leadingButton.bottomAnchor constraintEqualToAnchor:toolbar.bottomAnchor], - [segmentedControl.heightAnchor - constraintEqualToConstant:kSegmentedControlHeight], - [segmentedControl.centerXAnchor - constraintEqualToAnchor:toolbar.centerXAnchor], - [segmentedControl.bottomAnchor - constraintEqualToAnchor:toolbar.bottomAnchor - constant:-7.0f], + [pageControl.centerXAnchor constraintEqualToAnchor:toolbar.centerXAnchor], + [pageControl.bottomAnchor constraintEqualToAnchor:toolbar.bottomAnchor + constant:-7.0f], [trailingButton.heightAnchor constraintEqualToConstant:kToolbarHeight], [trailingButton.trailingAnchor constraintEqualToAnchor:toolbar.layoutMarginsGuide.trailingAnchor],
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index 00b566d..62dbe58 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/ui/tab_grid/grid_image_data_source.h" #import "ios/chrome/browser/ui/tab_grid/grid_view_controller.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.h" +#import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -134,6 +135,15 @@ #pragma mark - UIScrollViewDelegate +- (void)scrollViewDidScroll:(UIScrollView*)scrollView { + if (scrollView.dragging) { + CGFloat offsetWidth = + self.scrollView.contentSize.width - self.scrollView.frame.size.width; + CGFloat offset = scrollView.contentOffset.x / offsetWidth; + self.topToolbar.pageControl.sliderPosition = offset; + } +} + - (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView { // Bookkeeping for the current page. CGFloat pageWidth = scrollView.frame.size.width; @@ -526,6 +536,7 @@ self.doneButton = self.topToolbar.trailingButton; self.closeAllButton = self.topToolbar.leadingButton; } + // TODO(crbug.com/818699) : Localize strings. [self.doneButton setTitle:@"Done" forState:UIControlStateNormal]; [self.closeAllButton setTitle:@"Close All" forState:UIControlStateNormal]; @@ -539,10 +550,17 @@ [self.newTabButton addTarget:self action:@selector(newTabButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self.topToolbar.pageControl addTarget:self + action:@selector(pageControlChanged:) + forControlEvents:UIControlEventValueChanged]; + // TODO(crbug.com/804501): Use the actual live tab counts. + self.topToolbar.pageControl.regularText = @"5"; + self.topToolbar.pageControl.incognitoText = @"0"; [self configureButtonsForCurrentPage]; } - (void)configureButtonsForCurrentPage { + [self.topToolbar.pageControl setSelectedPage:self.currentPage animated:YES]; switch (self.currentPage) { case TabGridPageIncognitoTabs: self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty; @@ -671,7 +689,7 @@ [self configureButtonsForCurrentPage]; } -#pragma mark - Button actions +#pragma mark - Control actions - (void)doneButtonTapped:(id)sender { [self.tabPresentationDelegate showActiveTab]; @@ -707,4 +725,8 @@ } } +- (void)pageControlChanged:(id)sender { + self.currentPage = self.topToolbar.pageControl.selectedPage; +} + @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h index af154aa5..a8b8bd3d 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h
@@ -12,14 +12,13 @@ // TableViewTextHeaderFooterItem contains the model data for a // UITableViewHeaderFooterView. @interface TableViewTextHeaderFooterItem : TableViewHeaderFooterItem - @property(nonatomic, readwrite, strong) NSString* text; - +@property(nonatomic, readwrite, strong) NSString* subtitleText; @end // UITableViewHeaderFooterView that displays a text label. @interface TableViewTextHeaderFooterView : UITableViewHeaderFooterView - +@property(nonatomic, readwrite, strong) UILabel* subtitleLabel; @end #endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_TEXT_HEADER_FOOTER_ITEM_H_
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm index 51b5221a..5a9bd8a 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm
@@ -14,9 +14,13 @@ namespace { // The inner insets of the View content. const CGFloat kMargin = 16; + +// The vertical spacing between text labels. +const CGFloat kVerticalSpacing = 2.0; } @implementation TableViewTextHeaderFooterItem +@synthesize subtitleText = _subtitleText; @synthesize text = _text; - (instancetype)initWithType:(NSInteger)type { @@ -37,8 +41,7 @@ TableViewTextHeaderFooterView* header = base::mac::ObjCCastStrict<TableViewTextHeaderFooterView>(headerFooter); header.textLabel.text = self.text; - header.textLabel.font = - [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; + header.subtitleLabel.text = self.subtitleText; } @end @@ -46,21 +49,33 @@ #pragma mark - TableViewTextHeaderFooter @implementation TableViewTextHeaderFooterView +@synthesize subtitleLabel = _subtitleLabel; @synthesize textLabel = _textLabel; - (instancetype)initWithReuseIdentifier:(NSString*)reuseIdentifier { self = [super initWithReuseIdentifier:reuseIdentifier]; if (self) { - // Text Label, set font sizes using dynamic type. + // Labels, set font sizes using dynamic type. _textLabel = [[UILabel alloc] init]; - _textLabel.translatesAutoresizingMaskIntoConstraints = NO; + _textLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; + _subtitleLabel = [[UILabel alloc] init]; + _subtitleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; + + // Vertical StackView. + UIStackView* verticalStack = [[UIStackView alloc] + initWithArrangedSubviews:@[ _textLabel, _subtitleLabel ]]; + verticalStack.axis = UILayoutConstraintAxisVertical; + verticalStack.spacing = kVerticalSpacing; + verticalStack.translatesAutoresizingMaskIntoConstraints = NO; // Container View. UIView* containerView = [[UIView alloc] init]; containerView.translatesAutoresizingMaskIntoConstraints = NO; // Add subviews to View Hierarchy. - [containerView addSubview:_textLabel]; + [containerView addSubview:verticalStack]; [self.contentView addSubview:containerView]; // Set and activate constraints. @@ -80,12 +95,14 @@ constant:-kMargin], [containerView.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor], - // Title Label Constraints. - [_textLabel.leadingAnchor + // Vertical StackView Constraints. + [verticalStack.leadingAnchor constraintEqualToAnchor:containerView.leadingAnchor], - [_textLabel.topAnchor constraintEqualToAnchor:containerView.topAnchor], - [_textLabel.bottomAnchor + [verticalStack.topAnchor constraintEqualToAnchor:containerView.topAnchor], + [verticalStack.bottomAnchor constraintEqualToAnchor:containerView.bottomAnchor], + [verticalStack.trailingAnchor + constraintEqualToAnchor:containerView.trailingAnchor], ]]; } return self;
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium index c0b922b2..0353d28 100644 --- a/ios/third_party/material_components_ios/README.chromium +++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@ Name: Material Components for iOS URL: https://github.com/material-components/material-components-ios Version: 0 -Revision: 7d2e0214553aba8b5bb09fbe023df0f0dc48005a +Revision: dd21af4fef24ddb42d39e9610b84109273c50899 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/ipc/ipc_channel_proxy_unittest.cc b/ipc/ipc_channel_proxy_unittest.cc index 08e4011..2bf18d4 100644 --- a/ipc/ipc_channel_proxy_unittest.cc +++ b/ipc/ipc_channel_proxy_unittest.cc
@@ -418,14 +418,11 @@ std::unique_ptr<QuitListener> listener_; }; -#if !defined(OS_WIN) - // TODO(jam): for some reason this is flaky on win buildbots. TEST_F(IPCChannelBadMessageTest, BadMessage) { sender()->Send(new TestMsg_SendBadMessage()); SendQuitMessageAndWaitForIdle(); EXPECT_TRUE(DidListenerGetBadMessage()); } -#endif DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient) { ChannelReflectorListener listener;
diff --git a/media/cast/net/udp_socket_client_unittest.cc b/media/cast/net/udp_socket_client_unittest.cc index 5dacda40..c1b00df 100644 --- a/media/cast/net/udp_socket_client_unittest.cc +++ b/media/cast/net/udp_socket_client_unittest.cc
@@ -138,8 +138,21 @@ std::move(receiver)); OnUDPSocketCreated(); } + void CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + uint32_t backlog, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + network::mojom::TCPServerSocketRequest request, + CreateTCPServerSocketCallback callback) override {} + void CreateTCPConnectedSocket( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + network::mojom::TCPConnectedSocketRequest request, + network::mojom::TCPConnectedSocketObserverPtr observer, + CreateTCPConnectedSocketCallback callback) override {} - MockUdpSocket* udp_socket() const { return udp_socket_.get(); }; + MockUdpSocket* udp_socket() const { return udp_socket_.get(); } private: mojo::Binding<network::mojom::NetworkContext> binding_;
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc index 6ef8b6e..9c3274ac 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
@@ -10,6 +10,7 @@ #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/linux/native_pixmap_dmabuf.h" #include "ui/gfx/native_pixmap.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image_native_pixmap.h" namespace media {
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index 1285d1d..8a53263 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -173,6 +173,8 @@ vaapi_wrapper_ = VaapiWrapper::CreateForVideoCodec( VaapiWrapper::kDecode, profile, base::Bind(&ReportToUMA, VAAPI_ERROR)); + UMA_HISTOGRAM_BOOLEAN("Media.VAVDA.VaapiWrapperCreationSuccess", + vaapi_wrapper_.get()); if (!vaapi_wrapper_.get()) { VLOGF(1) << "Failed initializing VAAPI for profile " << GetProfileName(profile); @@ -181,13 +183,13 @@ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { decoder_.reset(new H264Decoder( - std::make_unique<VaapiH264Accelerator>(this, vaapi_wrapper_.get()))); + std::make_unique<VaapiH264Accelerator>(this, vaapi_wrapper_))); } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) { decoder_.reset(new VP8Decoder( std::make_unique<VaapiVP8Accelerator>(this, vaapi_wrapper_))); } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) { decoder_.reset(new VP9Decoder( - std::make_unique<VaapiVP9Accelerator>(this, vaapi_wrapper_.get()))); + std::make_unique<VaapiVP9Accelerator>(this, vaapi_wrapper_))); } else { VLOGF(1) << "Unsupported profile " << GetProfileName(profile); return false; @@ -222,7 +224,7 @@ } // Notify the client a picture is ready to be displayed. ++num_frames_at_client_; - TRACE_COUNTER1("media,gpu", "Textures at client", num_frames_at_client_); + TRACE_COUNTER1("media,gpu", "Vaapi frames at client", num_frames_at_client_); VLOGF(4) << "Notifying output picture id " << output_id << " for input " << input_id << " is ready. visible rect: " << visible_rect.ToString(); @@ -284,7 +286,7 @@ input_buffers_.push(std::move(input_buffer)); } - TRACE_COUNTER1("media,gpu", "Input buffers", input_buffers_.size()); + TRACE_COUNTER1("media,gpu", "Vaapi input buffers", input_buffers_.size()); switch (state_) { case kIdle: @@ -609,7 +611,7 @@ } --num_frames_at_client_; - TRACE_COUNTER1("media,gpu", "Textures at client", num_frames_at_client_); + TRACE_COUNTER1("media,gpu", "Vaapi frames at client", num_frames_at_client_); output_buffers_.push(picture_buffer_id); TryOutputSurface(); @@ -709,7 +711,7 @@ // Drop all remaining input buffers, if present. while (!input_buffers_.empty()) input_buffers_.pop(); - TRACE_COUNTER1("media,gpu", "Input buffers", input_buffers_.size()); + TRACE_COUNTER1("media,gpu", "Vaapi input buffers", input_buffers_.size()); decoder_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::ResetTask,
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 91b72c6..764c64c0 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -18,6 +18,7 @@ #include "base/environment.h" #include "base/logging.h" #include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "base/sys_info.h" @@ -164,6 +165,9 @@ void SetDrmFd(base::PlatformFile fd) { drm_fd_.reset(HANDLE_EINTR(dup(fd))); } private: + // Implementation of Initialize() called only once. + bool InitializeOnce(); + // Protected by |va_lock_|. int refcount_; @@ -208,12 +212,21 @@ #if defined(USE_X11) !IsVa_x11Initialized() || #endif - !IsVa_drmInitialized()) + !IsVa_drmInitialized()) { return false; + } + // Manual refcounting to ensure the rest of the method is called only once. if (refcount_++ > 0) return true; + const bool success = InitializeOnce(); + UMA_HISTOGRAM_BOOLEAN("Media.VaapiWrapper.VADisplayStateInitializeSuccess", + success); + return success; +} + +bool VADisplayState::InitializeOnce() { switch (gl::GetGLImplementation()) { case gl::kGLImplementationEGLGLES2: va_display_ = vaGetDisplayDRM(drm_fd_.get());
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc index f255efd9..94b6b4a 100644 --- a/mojo/public/cpp/bindings/lib/connector.cc +++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -89,10 +89,8 @@ } static RunLoopNestingObserver* GetForThread() { - if (!base::MessageLoop::current() || - !base::RunLoop::IsNestingAllowedOnCurrentThread()) { + if (!base::MessageLoop::current()) return nullptr; - } auto* observer = static_cast<RunLoopNestingObserver*>( g_tls_nesting_observer.Get().Get()); if (!observer) {
diff --git a/net/dns/address_sorter_posix_unittest.cc b/net/dns/address_sorter_posix_unittest.cc index 204fc87..1407ab4 100644 --- a/net/dns/address_sorter_posix_unittest.cc +++ b/net/dns/address_sorter_posix_unittest.cc
@@ -79,6 +79,7 @@ return NetworkChangeNotifier::kInvalidNetworkHandle; } void ApplySocketTag(const SocketTag& tag) override {} + void SetMsgConfirm(bool confirm) override {} int Connect(const IPEndPoint& remote) override { if (connected_)
diff --git a/net/dns/mock_mdns_socket_factory.h b/net/dns/mock_mdns_socket_factory.h index 059a93a..3036ff6 100644 --- a/net/dns/mock_mdns_socket_factory.h +++ b/net/dns/mock_mdns_socket_factory.h
@@ -45,6 +45,7 @@ MOCK_METHOD1(SetReceiveBufferSize, int(int32_t size)); MOCK_METHOD1(SetSendBufferSize, int(int32_t size)); MOCK_METHOD0(SetDoNotFragment, int()); + MOCK_METHOD1(SetMsgConfirm, void(bool confirm)); MOCK_METHOD0(Close, void());
diff --git a/net/network_error_logging/network_error_logging_end_to_end_test.cc b/net/network_error_logging/network_error_logging_end_to_end_test.cc index 5b20bff..d395643 100644 --- a/net/network_error_logging/network_error_logging_end_to_end_test.cc +++ b/net/network_error_logging/network_error_logging_end_to_end_test.cc
@@ -199,7 +199,8 @@ // Make sure an upload that is in progress at shutdown does not crash. // This verifies that https://crbug.com/792978 is fixed. -TEST_F(NetworkErrorLoggingEndToEndTest, UploadAtShutdown) { +// Disabled due to frequent timeouts - see https://crbug.com/820950 . +TEST_F(NetworkErrorLoggingEndToEndTest, DISABLED_UploadAtShutdown) { upload_should_hang_ = true; TestDelegate configure_delegate;
diff --git a/net/socket/datagram_socket.h b/net/socket/datagram_socket.h index f529474..254922d 100644 --- a/net/socket/datagram_socket.h +++ b/net/socket/datagram_socket.h
@@ -45,6 +45,10 @@ // return ERR_IO_PENDING. virtual int SetDoNotFragment() = 0; + // If |confirm| is true, then the MSG_CONFIRM flag will be passed to + // subsequent writes if it's supported by the platform. + virtual void SetMsgConfirm(bool confirm) = 0; + // Gets the NetLog for this socket. virtual const NetLogWithSource& NetLog() const = 0; };
diff --git a/net/socket/fuzzed_datagram_client_socket.h b/net/socket/fuzzed_datagram_client_socket.h index 6d19562..172ed24e 100644 --- a/net/socket/fuzzed_datagram_client_socket.h +++ b/net/socket/fuzzed_datagram_client_socket.h
@@ -59,6 +59,7 @@ int SetReceiveBufferSize(int32_t size) override; int SetSendBufferSize(int32_t size) override; int SetDoNotFragment() override; + void SetMsgConfirm(bool confirm) override {} private: void OnReadComplete(const net::CompletionCallback& callback, int result);
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index b9b0f02..65015f5 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h
@@ -799,6 +799,7 @@ int ConnectUsingDefaultNetwork(const IPEndPoint& address) override; NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override; void ApplySocketTag(const SocketTag& tag) override; + void SetMsgConfirm(bool confirm) override {} // AsyncSocket implementation. void OnReadComplete(const MockRead& data) override;
diff --git a/net/socket/udp_client_socket.cc b/net/socket/udp_client_socket.cc index 049a1fca..f84d28d 100644 --- a/net/socket/udp_client_socket.cc +++ b/net/socket/udp_client_socket.cc
@@ -119,6 +119,10 @@ return socket_.SetDoNotFragment(); } +void UDPClientSocket::SetMsgConfirm(bool confirm) { + socket_.SetMsgConfirm(confirm); +} + const NetLogWithSource& UDPClientSocket::NetLog() const { return socket_.NetLog(); }
diff --git a/net/socket/udp_client_socket.h b/net/socket/udp_client_socket.h index 4abdb27..9f4f1ea 100644 --- a/net/socket/udp_client_socket.h +++ b/net/socket/udp_client_socket.h
@@ -49,6 +49,7 @@ int SetReceiveBufferSize(int32_t size) override; int SetSendBufferSize(int32_t size) override; int SetDoNotFragment() override; + void SetMsgConfirm(bool confirm) override; const NetLogWithSource& NetLog() const override; void EnableRecvOptimization() override;
diff --git a/net/socket/udp_server_socket.cc b/net/socket/udp_server_socket.cc index d5f107a..ca9d848 100644 --- a/net/socket/udp_server_socket.cc +++ b/net/socket/udp_server_socket.cc
@@ -67,6 +67,10 @@ return socket_.SetDoNotFragment(); } +void UDPServerSocket::SetMsgConfirm(bool confirm) { + return socket_.SetMsgConfirm(confirm); +} + void UDPServerSocket::Close() { socket_.Close(); }
diff --git a/net/socket/udp_server_socket.h b/net/socket/udp_server_socket.h index 5d3cbdb2..0d2dc7e3 100644 --- a/net/socket/udp_server_socket.h +++ b/net/socket/udp_server_socket.h
@@ -39,6 +39,7 @@ int SetReceiveBufferSize(int32_t size) override; int SetSendBufferSize(int32_t size) override; int SetDoNotFragment() override; + void SetMsgConfirm(bool confirm) override; void Close() override; int GetPeerAddress(IPEndPoint* address) const override; int GetLocalAddress(IPEndPoint* address) const override;
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc index 9bc55d7..e84a785 100644 --- a/net/socket/udp_socket_posix.cc +++ b/net/socket/udp_socket_posix.cc
@@ -199,6 +199,7 @@ addr_family_(0), is_connected_(false), socket_options_(SOCKET_OPTION_MULTICAST_LOOP), + sendto_flags_(0), multicast_interface_(0), multicast_time_to_live_(1), bind_type_(bind_type), @@ -649,6 +650,16 @@ #endif } +void UDPSocketPosix::SetMsgConfirm(bool confirm) { +#if !defined(OS_MACOSX) && !defined(OS_IOS) + if (confirm) { + sendto_flags_ |= MSG_CONFIRM; + } else { + sendto_flags_ &= ~MSG_CONFIRM; + } +#endif // !defined(OS_MACOSX) && !defined(OS_IOS) +} + int UDPSocketPosix::AllowAddressReuse() { DCHECK_NE(socket_, kInvalidSocket); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -867,12 +878,8 @@ } } - int result = HANDLE_EINTR(sendto(socket_, - buf->data(), - buf_len, - 0, - addr, - storage.addr_len)); + int result = HANDLE_EINTR(sendto(socket_, buf->data(), buf_len, sendto_flags_, + addr, storage.addr_len)); if (result < 0) result = MapSystemError(errno); if (result != ERR_IO_PENDING)
diff --git a/net/socket/udp_socket_posix.h b/net/socket/udp_socket_posix.h index 65958803..77189fe 100644 --- a/net/socket/udp_socket_posix.h +++ b/net/socket/udp_socket_posix.h
@@ -177,6 +177,10 @@ // return ERR_IO_PENDING. int SetDoNotFragment(); + // If |confirm| is true, then the MSG_CONFIRM flag will be passed to + // subsequent writes if it's supported by the platform. + void SetMsgConfirm(bool confirm); + // Returns true if the socket is already connected or bound. bool is_connected() const { return is_connected_; } @@ -354,6 +358,9 @@ // options that should be applied to |socket_| before Bind(). int socket_options_; + // Flags passed to sendto(). + int sendto_flags_; + // Multicast interface. uint32_t multicast_interface_;
diff --git a/net/socket/udp_socket_win.cc b/net/socket/udp_socket_win.cc index 7790d6a..b848b54 100644 --- a/net/socket/udp_socket_win.cc +++ b/net/socket/udp_socket_win.cc
@@ -567,6 +567,8 @@ return rv == 0 ? OK : MapSystemError(WSAGetLastError()); } +void UDPSocketWin::SetMsgConfirm(bool confirm) {} + int UDPSocketWin::AllowAddressReuse() { DCHECK_NE(socket_, INVALID_SOCKET); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/net/socket/udp_socket_win.h b/net/socket/udp_socket_win.h index 71094d4..09d8196 100644 --- a/net/socket/udp_socket_win.h +++ b/net/socket/udp_socket_win.h
@@ -137,6 +137,9 @@ // return ERR_IO_PENDING. int SetDoNotFragment(); + // This is a no-op on Windows. + void SetMsgConfirm(bool confirm); + // Returns true if the socket is already connected or bound. bool is_connected() const { return is_connected_; }
diff --git a/net/traffic_annotation/network_traffic_annotation_test_helper.h b/net/traffic_annotation/network_traffic_annotation_test_helper.h index ce77c41..82b2ba1 100644 --- a/net/traffic_annotation/network_traffic_annotation_test_helper.h +++ b/net/traffic_annotation/network_traffic_annotation_test_helper.h
@@ -7,7 +7,7 @@ #include "net/traffic_annotation/network_traffic_annotation.h" -// Macro for unit tests traffic annotations. +// Macros for tests traffic annotations. #define TRAFFIC_ANNOTATION_FOR_TESTS \ net::DefineNetworkTrafficAnnotation( \ "test", "Traffic annotation for unit, browser and other tests")
diff --git a/printing/backend/cups_jobs.cc b/printing/backend/cups_jobs.cc index ab347e7f..3461e00 100644 --- a/printing/backend/cups_jobs.cc +++ b/printing/backend/cups_jobs.cc
@@ -450,9 +450,15 @@ return false; } + // TODO(crbug.com/821497): Use a library to canonicalize the URL. + size_t first_non_slash = resource.find_first_not_of('/'); + const std::string path = (first_non_slash == std::string::npos) + ? "" + : resource.substr(first_non_slash); + std::string printer_uri = base::StringPrintf("%s://%s:%d/%s", encrypted ? kIppsScheme : kIppScheme, - address.c_str(), port, resource.c_str()); + address.c_str(), port, path.c_str()); ipp_status_t status; ScopedIppPtr response =
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index 66a45f78..a7cf45ba 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -52,6 +52,12 @@ "resource_scheduler_client.h", "restricted_cookie_manager.cc", "restricted_cookie_manager.h", + "socket_factory.cc", + "socket_factory.h", + "tcp_connected_socket.cc", + "tcp_connected_socket.h", + "tcp_server_socket.cc", + "tcp_server_socket.h", "throttling/network_conditions.cc", "throttling/network_conditions.h", "throttling/throttling_controller.cc", @@ -66,8 +72,6 @@ "throttling/throttling_upload_data_stream.h", "udp_socket.cc", "udp_socket.h", - "udp_socket_factory.cc", - "udp_socket_factory.h", "upload_progress_tracker.cc", "upload_progress_tracker.h", "url_loader.cc", @@ -139,11 +143,11 @@ "proxy_resolving_client_socket_unittest.cc", "resource_scheduler_unittest.cc", "restricted_cookie_manager_unittest.cc", + "tcp_socket_unittest.cc", "test/test_url_loader_factory_unittest.cc", "test_chunked_data_pipe_getter.cc", "test_chunked_data_pipe_getter.h", "throttling/throttling_controller_unittest.cc", - "udp_socket_factory_unittest.cc", "udp_socket_unittest.cc", "upload_progress_tracker_unittest.cc", "url_loader_unittest.cc",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 60a07ff..41fb0e7 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -36,6 +36,7 @@ #include "net/reporting/reporting_policy.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/default_channel_id_store.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "services/network/http_server_properties_pref_delegate.h" @@ -49,7 +50,6 @@ #include "services/network/throttling/network_conditions.h" #include "services/network/throttling/throttling_controller.h" #include "services/network/throttling/throttling_network_transaction_factory.h" -#include "services/network/udp_socket_factory.h" #include "services/network/url_loader.h" #include "services/network/url_loader_factory.h" #include "services/network/url_request_context_builder_mojo.h" @@ -92,7 +92,8 @@ mojom::NetworkContextParamsPtr params) : network_service_(network_service), params_(std::move(params)), - binding_(this, std::move(request)) { + binding_(this, std::move(request)), + socket_factory_(network_service_->net_log()) { url_request_context_owner_ = MakeURLRequestContext(params_.get()); url_request_context_getter_ = url_request_context_owner_.url_request_context_getter; @@ -115,7 +116,8 @@ std::unique_ptr<URLRequestContextBuilderMojo> builder) : network_service_(network_service), params_(std::move(params)), - binding_(this, std::move(request)) { + binding_(this, std::move(request)), + socket_factory_(network_service_->net_log()) { url_request_context_owner_ = ApplyContextParamsToBuilder( builder.get(), params_.get(), network_service->quic_disabled(), network_service->net_log()); @@ -136,8 +138,9 @@ url_request_context_getter_(std::move(url_request_context_getter)), binding_(this, std::move(request)), cookie_manager_(std::make_unique<CookieManager>( - url_request_context_getter_->GetURLRequestContext() - ->cookie_store())) { + url_request_context_getter_->GetURLRequestContext()->cookie_store())), + socket_factory_(network_service_ ? network_service_->net_log() + : nullptr) { // May be nullptr in tests. if (network_service_) network_service_->RegisterNetworkContext(this); @@ -222,7 +225,10 @@ } NetworkContext::NetworkContext(mojom::NetworkContextParamsPtr params) - : network_service_(nullptr), params_(std::move(params)), binding_(this) { + : network_service_(nullptr), + params_(std::move(params)), + binding_(this), + socket_factory_(network_service_->net_log()) { url_request_context_owner_ = MakeURLRequestContext(params_.get()); url_request_context_getter_ = url_request_context_owner_.url_request_context_getter; @@ -486,9 +492,32 @@ void NetworkContext::CreateUDPSocket(mojom::UDPSocketRequest request, mojom::UDPSocketReceiverPtr receiver) { - if (!udp_socket_factory_) - udp_socket_factory_ = std::make_unique<UDPSocketFactory>(); - udp_socket_factory_->CreateUDPSocket(std::move(request), std::move(receiver)); + socket_factory_.CreateUDPSocket(std::move(request), std::move(receiver)); +} + +void NetworkContext::CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + uint32_t backlog, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPServerSocketRequest request, + CreateTCPServerSocketCallback callback) { + socket_factory_.CreateTCPServerSocket( + local_addr, backlog, + static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation), + std::move(request), std::move(callback)); +} + +void NetworkContext::CreateTCPConnectedSocket( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPConnectedSocketRequest request, + mojom::TCPConnectedSocketObserverPtr observer, + CreateTCPConnectedSocketCallback callback) { + socket_factory_.CreateTCPConnectedSocket( + local_addr, remote_addr_list, + static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation), + std::move(request), std::move(observer), std::move(callback)); } void NetworkContext::AddHSTSForTesting(const std::string& host,
diff --git a/services/network/network_context.h b/services/network/network_context.h index 0c558a5..0519c8a 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -20,8 +20,10 @@ #include "services/network/cookie_manager.h" #include "services/network/http_cache_data_remover.h" #include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" #include "services/network/public/mojom/udp_socket.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/socket_factory.h" #include "services/network/url_request_context_owner.h" namespace net { @@ -33,7 +35,6 @@ class NetworkService; class ResourceScheduler; class ResourceSchedulerClient; -class UDPSocketFactory; class URLRequestContextBuilderMojo; // A NetworkContext creates and manages access to a URLRequestContext. @@ -112,6 +113,19 @@ mojom::NetworkConditionsPtr conditions) override; void CreateUDPSocket(mojom::UDPSocketRequest request, mojom::UDPSocketReceiverPtr receiver) override; + void CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + uint32_t backlog, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPServerSocketRequest request, + CreateTCPServerSocketCallback callback) override; + void CreateTCPConnectedSocket( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPConnectedSocketRequest request, + mojom::TCPConnectedSocketObserverPtr observer, + CreateTCPConnectedSocketCallback callback) override; void AddHSTSForTesting(const std::string& host, base::Time expiry, bool include_subdomains, @@ -169,7 +183,7 @@ std::unique_ptr<CookieManager> cookie_manager_; - std::unique_ptr<UDPSocketFactory> udp_socket_factory_; + SocketFactory socket_factory_; std::vector<std::unique_ptr<HttpCacheDataRemover>> http_cache_data_removers_;
diff --git a/services/network/public/cpp/network_param_ipc_traits.h b/services/network/public/cpp/network_param_ipc_traits.h index dbc7440..a52c22f 100644 --- a/services/network/public/cpp/network_param_ipc_traits.h +++ b/services/network/public/cpp/network_param_ipc_traits.h
@@ -282,6 +282,7 @@ IPC_STRUCT_TRAITS_BEGIN(network::URLLoaderCompletionStatus) IPC_STRUCT_TRAITS_MEMBER(error_code) + IPC_STRUCT_TRAITS_MEMBER(exists_in_cache) IPC_STRUCT_TRAITS_MEMBER(completion_time) IPC_STRUCT_TRAITS_MEMBER(encoded_data_length) IPC_STRUCT_TRAITS_MEMBER(encoded_body_length) @@ -358,7 +359,6 @@ IPC_STRUCT_TRAITS_MEMBER(ct_policy_compliance) IPC_STRUCT_TRAITS_MEMBER(is_legacy_symantec_cert) IPC_STRUCT_TRAITS_MEMBER(content_length) - IPC_STRUCT_TRAITS_MEMBER(was_cached) IPC_STRUCT_TRAITS_MEMBER(encoded_data_length) IPC_STRUCT_TRAITS_MEMBER(encoded_body_length) IPC_STRUCT_TRAITS_MEMBER(appcache_id)
diff --git a/services/network/public/cpp/resource_response.cc b/services/network/public/cpp/resource_response.cc index 3b6c98f..777a2b4 100644 --- a/services/network/public/cpp/resource_response.cc +++ b/services/network/public/cpp/resource_response.cc
@@ -21,7 +21,6 @@ new_response->head.ct_policy_compliance = head.ct_policy_compliance; new_response->head.is_legacy_symantec_cert = head.is_legacy_symantec_cert; new_response->head.content_length = head.content_length; - new_response->head.was_cached = head.was_cached; new_response->head.encoded_data_length = head.encoded_data_length; new_response->head.encoded_body_length = head.encoded_body_length; new_response->head.appcache_id = head.appcache_id;
diff --git a/services/network/public/cpp/resource_response_info.cc b/services/network/public/cpp/resource_response_info.cc index 1e0470a..c47e87b 100644 --- a/services/network/public/cpp/resource_response_info.cc +++ b/services/network/public/cpp/resource_response_info.cc
@@ -15,7 +15,6 @@ content_length(-1), encoded_data_length(-1), encoded_body_length(-1), - was_cached(false), appcache_id(0), was_fetched_via_spdy(false), was_alpn_negotiated(false),
diff --git a/services/network/public/cpp/resource_response_info.h b/services/network/public/cpp/resource_response_info.h index 12f5cd7..9b9c6c7 100644 --- a/services/network/public/cpp/resource_response_info.h +++ b/services/network/public/cpp/resource_response_info.h
@@ -69,9 +69,6 @@ // has been read to the end. int64_t encoded_body_length; - // True if the response was fetched from the network cache. - bool was_cached; - // The appcache this response was loaded from, or kAppCacheNoCacheId. // TODO(rdsmith): Remove conceptual dependence on appcache. int64_t appcache_id;
diff --git a/services/network/public/cpp/url_loader_completion_status.cc b/services/network/public/cpp/url_loader_completion_status.cc index 095bd13..b7792fa 100644 --- a/services/network/public/cpp/url_loader_completion_status.cc +++ b/services/network/public/cpp/url_loader_completion_status.cc
@@ -26,6 +26,7 @@ bool URLLoaderCompletionStatus::operator==( const URLLoaderCompletionStatus& rhs) const { return error_code == rhs.error_code && + exists_in_cache == rhs.exists_in_cache && completion_time == rhs.completion_time && encoded_data_length == rhs.encoded_data_length && encoded_body_length == rhs.encoded_body_length &&
diff --git a/services/network/public/cpp/url_loader_completion_status.h b/services/network/public/cpp/url_loader_completion_status.h index dec74f3..4d474d1 100644 --- a/services/network/public/cpp/url_loader_completion_status.h +++ b/services/network/public/cpp/url_loader_completion_status.h
@@ -36,6 +36,9 @@ // The error code. ERR_FAILED is set for CORS errors. int error_code = 0; + // A copy of the data requested exists in the cache. + bool exists_in_cache = false; + // Time the request completed. base::TimeTicks completion_time;
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 838874d..bfd5dd5 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -70,6 +70,7 @@ "proxy_config_with_annotation.mojom", "request_context_frame_type.mojom", "restricted_cookie_manager.mojom", + "tcp_socket.mojom", "url_loader.mojom", "url_loader_factory.mojom", ]
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index df71a07..f666cb26 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -9,9 +9,11 @@ import "net/interfaces/address_list.mojom"; import "net/interfaces/ip_endpoint.mojom"; import "services/network/public/mojom/cookie_manager.mojom"; +import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; import "services/network/public/mojom/network_change_manager.mojom"; import "services/network/public/mojom/proxy_config.mojom"; import "services/network/public/mojom/proxy_config_with_annotation.mojom"; +import "services/network/public/mojom/tcp_socket.mojom"; import "services/network/public/mojom/udp_socket.mojom"; import "services/network/public/mojom/url_loader.mojom"; import "services/network/public/mojom/url_loader_factory.mojom"; @@ -188,8 +190,46 @@ // is not interested in incoming data. // Any sockets that are created but are yet to be destroyed will be destroyed // when NetworkContext goes away. - CreateUDPSocket(network.mojom.UDPSocket& request, - network.mojom.UDPSocketReceiver? receiver); + CreateUDPSocket(UDPSocket& request, UDPSocketReceiver? receiver); + + // Creates a TCP server socket that listens on |local_addr|. The socket + // created can only be used for the purpose specified in |traffic_annotation|, + // and cannot be re-used for other purposes. Caller must specify an address + // family in |local_addr| to be either IPv4 or IPv6. If port in |local_addr| + // is 0, the OS will pick an available port. If address bytes are 0, the OS + // will pick a local address of the specified address family. |backlog| will + // be passed to the OS to set the size of accept queue. + // On success, the resulting local address will be written to |local_addr_out| + // and |result| is net::OK. On failure, |result| is a network error code. + // + // Any sockets that are created but are yet to be destroyed will be destroyed + // when NetworkContext goes away. + CreateTCPServerSocket(net.interfaces.IPEndPoint local_addr, + uint32 backlog, + MutableNetworkTrafficAnnotationTag traffic_annotation, + TCPServerSocket& socket) + => (int32 result, net.interfaces.IPEndPoint? local_addr_out); + + // Creates a TCP socket connected to |remote_addr|. |observer| will be used + // to listen for any network connection error on the newly established + // connection. The socket created can only be used for the purpose specified + // in |traffic_annotation|, and cannot be re-used for other purposes. + // |local_addr| should be set to null unless the caller wants to bind the + // socket to a specific address and port. On success, |result| is net::OK. + // Caller is to use |send_stream| to send data and |receive_stream| to receive + // data over the connection. On failure, |result| is a network error code. + // + // Any sockets that are created but are yet to be destroyed will be destroyed + // when NetworkContext goes away. + CreateTCPConnectedSocket( + net.interfaces.IPEndPoint? local_addr, + net.interfaces.AddressList remote_addr_list, + MutableNetworkTrafficAnnotationTag traffic_annotation, + TCPConnectedSocket& socket, + TCPConnectedSocketObserver observer) + => (int32 result, + handle<data_pipe_consumer>? receive_stream, + handle<data_pipe_producer>? send_stream); [Sync] // Adds explicitly-specified data as if it was processed from an
diff --git a/services/network/public/mojom/tcp_socket.mojom b/services/network/public/mojom/tcp_socket.mojom new file mode 100644 index 0000000..0367f3a --- /dev/null +++ b/services/network/public/mojom/tcp_socket.mojom
@@ -0,0 +1,53 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +import "net/interfaces/ip_endpoint.mojom"; + +// Represents a connected TCP socket. Writes and Reads are through the data +// pipes supplied upon construction. Consumer should use +// TCPConnectedSocketObserver interface to get notified about any error occurred +// during reading or writing to data pipes. Consumer can close the socket by +// destroying the interface pointer. +interface TCPConnectedSocket { + // Gets the local address of this connected socket. On success, |net_error| is + // net::OK and |local_addr| contains the local address of the socket. On + // failure, |local_addr| is null and |net_error| is a net error code. + GetLocalAddress() => (int32 net_error, net.interfaces.IPEndPoint? local_addr); +}; + +// Interface to listen for network connection error on a TCPConnectedSocket. +// Because data pipe doesn't surface any network connection error, if a network +// error happens during a read or a write, consumer can find out about it by +// implementing this interface. +interface TCPConnectedSocketObserver { + // Called when an error occurs during reading from the network. The producer + // side of |receive_stream| will be closed. + OnReadError(int32 net_error); + + // Called when an error occurs during sending to the network. The consumer + // side of |send_stream| will be closed. + OnWriteError(int32 net_error); +}; + +// Represents a TCP server socket that has been successfully bound to a local +// address. Caller can close the socket by destroying the interface pointer. +interface TCPServerSocket { + // Waits for an incoming connection request. On success, returns net::OK, + // |remote_addr| represents the peer address, |connected_socket| is the new + // connection established. Caller uses |send_stream| to send data and + // |receive_stream| for receiving data over the new connection. On failure, + // |net_error| is a net error code and other fields are null. + // Up to |backlog| Accept()s can be pending at a time. |backlog| is a + // number that is specified when requesting TCPServerSocket. If more than + // |backlog| number of Accept()s are outstanding, + // net::ERR_INSUFFICIENT_RESOUCES will be returned. + Accept(TCPConnectedSocketObserver observer) + => (int32 net_error, + net.interfaces.IPEndPoint? remote_addr, + TCPConnectedSocket? connected_socket, + handle<data_pipe_consumer>? send_stream, + handle<data_pipe_producer>? receive_stream); +};
diff --git a/services/network/socket_factory.cc b/services/network/socket_factory.cc new file mode 100644 index 0000000..b4dca59 --- /dev/null +++ b/services/network/socket_factory.cc
@@ -0,0 +1,69 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/socket_factory.h" + +#include <utility> + +#include "base/memory/ptr_util.h" +#include "base/optional.h" +#include "net/base/completion_once_callback.h" +#include "net/base/net_errors.h" +#include "net/log/net_log.h" +#include "services/network/tcp_connected_socket.h" +#include "services/network/udp_socket.h" + +namespace network { + +SocketFactory::SocketFactory(net::NetLog* net_log) : net_log_(net_log) {} + +SocketFactory::~SocketFactory() {} + +void SocketFactory::CreateUDPSocket(mojom::UDPSocketRequest request, + mojom::UDPSocketReceiverPtr receiver) { + udp_socket_bindings_.AddBinding( + std::make_unique<UDPSocket>(std::move(receiver), net_log_), + std::move(request)); +} + +void SocketFactory::CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + int backlog, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPServerSocketRequest request, + mojom::NetworkContext::CreateTCPServerSocketCallback callback) { + auto socket = + std::make_unique<TCPServerSocket>(this, net_log_, traffic_annotation); + net::IPEndPoint local_addr_out; + int result = socket->Listen(local_addr, backlog, &local_addr_out); + if (result != net::OK) { + std::move(callback).Run(result, base::nullopt); + return; + } + tcp_server_socket_bindings_.AddBinding(std::move(socket), std::move(request)); + std::move(callback).Run(result, local_addr_out); +} + +void SocketFactory::CreateTCPConnectedSocket( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPConnectedSocketRequest request, + mojom::TCPConnectedSocketObserverPtr observer, + mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) { + auto socket = std::make_unique<TCPConnectedSocket>( + std::move(observer), net_log_, traffic_annotation); + TCPConnectedSocket* socket_raw = socket.get(); + tcp_connected_socket_bindings_.AddBinding(std::move(socket), + std::move(request)); + socket_raw->Connect(local_addr, remote_addr_list, std::move(callback)); +} + +void SocketFactory::OnAccept(std::unique_ptr<TCPConnectedSocket> socket, + mojom::TCPConnectedSocketRequest request) { + tcp_connected_socket_bindings_.AddBinding(std::move(socket), + std::move(request)); +} + +} // namespace network
diff --git a/services/network/socket_factory.h b/services/network/socket_factory.h new file mode 100644 index 0000000..59d1ac67 --- /dev/null +++ b/services/network/socket_factory.h
@@ -0,0 +1,75 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_NETWORK_SOCKET_FACTORY_H_ +#define SERVICES_NETWORK_SOCKET_FACTORY_H_ + +#include <memory> +#include <vector> + +#include "base/component_export.h" +#include "base/macros.h" +#include "mojo/public/cpp/bindings/strong_binding_set.h" +#include "net/socket/tcp_socket.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" +#include "services/network/public/mojom/udp_socket.mojom.h" +#include "services/network/tcp_server_socket.h" + +namespace net { +class NetLog; +} // namespace net + +namespace network { + +class UDPSocket; +class TCPConnectedSocket; + +// Helper class that handles UDPSocketRequest. It takes care of destroying the +// UDPSocket implementation instances when mojo pipes are broken. +class COMPONENT_EXPORT(NETWORK_SERVICE) SocketFactory + : public TCPServerSocket::Delegate { + public: + // Constructs a SocketFactory. If |net_log| is non-null, it is used to + // log NetLog events when logging is enabled. |net_log| used to must outlive + // |this|. + explicit SocketFactory(net::NetLog* net_log); + virtual ~SocketFactory(); + + void CreateUDPSocket(mojom::UDPSocketRequest request, + mojom::UDPSocketReceiverPtr receiver); + void CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + int backlog, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPServerSocketRequest request, + mojom::NetworkContext::CreateTCPServerSocketCallback callback); + void CreateTCPConnectedSocket( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + mojom::TCPConnectedSocketRequest request, + mojom::TCPConnectedSocketObserverPtr observer, + mojom::NetworkContext::CreateTCPConnectedSocketCallback callback); + + private: + // TCPServerSocket::Delegate implementation: + void OnAccept(std::unique_ptr<TCPConnectedSocket> socket, + mojom::TCPConnectedSocketRequest request) override; + + void OnConnectCompleted(int result); + + net::NetLog* net_log_; + mojo::StrongBindingSet<mojom::UDPSocket> udp_socket_bindings_; + mojo::StrongBindingSet<mojom::TCPServerSocket> tcp_server_socket_bindings_; + mojo::StrongBindingSet<mojom::TCPConnectedSocket> + tcp_connected_socket_bindings_; + + DISALLOW_COPY_AND_ASSIGN(SocketFactory); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_SOCKET_FACTORY_H_
diff --git a/services/network/tcp_connected_socket.cc b/services/network/tcp_connected_socket.cc new file mode 100644 index 0000000..2962c9cf --- /dev/null +++ b/services/network/tcp_connected_socket.cc
@@ -0,0 +1,250 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/tcp_connected_socket.h" + +#include <utility> + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/numerics/safe_conversions.h" +#include "base/optional.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/log/net_log.h" + +namespace network { + +TCPConnectedSocket::TCPConnectedSocket( + mojom::TCPConnectedSocketObserverPtr observer, + net::NetLog* net_log, + const net::NetworkTrafficAnnotationTag& traffic_annotation) + : observer_(std::move(observer)), + net_log_(net_log), + readable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL), + writable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL), + traffic_annotation_(traffic_annotation) { + // TODO(xunjieli): Consider supporting null |observer_|, if there are + // consumers who do not care about read/write errors. + DCHECK(observer_); +} + +TCPConnectedSocket::TCPConnectedSocket( + mojom::TCPConnectedSocketObserverPtr observer, + std::unique_ptr<net::StreamSocket> socket, + mojo::ScopedDataPipeProducerHandle receive_pipe_handle, + mojo::ScopedDataPipeConsumerHandle send_pipe_handle, + const net::NetworkTrafficAnnotationTag& traffic_annotation) + : observer_(std::move(observer)), + net_log_(nullptr), + socket_(std::move(socket)), + send_stream_(std::move(send_pipe_handle)), + readable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL), + receive_stream_(std::move(receive_pipe_handle)), + writable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL), + traffic_annotation_(traffic_annotation) { + StartWatching(); +} + +TCPConnectedSocket::~TCPConnectedSocket() {} + +void TCPConnectedSocket::Connect( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) { + DCHECK(!socket_); + DCHECK(callback); + + auto socket = std::make_unique<net::TCPClientSocket>( + remote_addr_list, nullptr /*socket_performance_watcher*/, net_log_, + net::NetLogSource()); + connect_callback_ = std::move(callback); + int result = net::OK; + if (local_addr) + result = socket->Bind(local_addr.value()); + if (result == net::OK) { + result = socket->Connect(base::BindRepeating( + &TCPConnectedSocket::OnConnectCompleted, base::Unretained(this))); + } + socket_ = std::move(socket); + if (result == net::ERR_IO_PENDING) + return; + OnConnectCompleted(result); +} + +void TCPConnectedSocket::GetLocalAddress(GetLocalAddressCallback callback) { + DCHECK(socket_); + + net::IPEndPoint local_addr; + int result = socket_->GetLocalAddress(&local_addr); + if (result != net::OK) { + std::move(callback).Run(result, base::nullopt); + return; + } + std::move(callback).Run(result, local_addr); +} + +void TCPConnectedSocket::OnConnectCompleted(int result) { + DCHECK(!connect_callback_.is_null()); + DCHECK(!receive_stream_.is_valid()); + DCHECK(!send_stream_.is_valid()); + + if (result != net::OK) { + std::move(connect_callback_) + .Run(result, mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + return; + } + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + receive_stream_ = std::move(receive_pipe.producer_handle); + send_stream_ = std::move(send_pipe.consumer_handle); + + StartWatching(); + std::move(connect_callback_) + .Run(net::OK, std::move(receive_pipe.consumer_handle), + std::move(send_pipe.producer_handle)); +} + +void TCPConnectedSocket::StartWatching() { + readable_handle_watcher_.Watch( + send_stream_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + base::BindRepeating(&TCPConnectedSocket::OnSendStreamReadable, + base::Unretained(this))); + writable_handle_watcher_.Watch( + receive_stream_.get(), + MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + base::BindRepeating(&TCPConnectedSocket::OnReceiveStreamWritable, + base::Unretained(this))); + ReceiveMore(); + SendMore(); +} + +void TCPConnectedSocket::ReceiveMore() { + DCHECK(receive_stream_.is_valid()); + DCHECK(!pending_receive_); + + uint32_t num_bytes; + MojoResult result = NetToMojoPendingBuffer::BeginWrite( + &receive_stream_, &pending_receive_, &num_bytes); + if (result == MOJO_RESULT_SHOULD_WAIT) { + writable_handle_watcher_.ArmOrNotify(); + return; + } + if (result != MOJO_RESULT_OK) { + ShutdownReceive(); + return; + } + DCHECK_EQ(MOJO_RESULT_OK, result); + DCHECK(pending_receive_); + scoped_refptr<net::IOBuffer> buf( + new NetToMojoIOBuffer(pending_receive_.get())); + int read_result = socket_->Read( + buf.get(), base::saturated_cast<int>(num_bytes), + base::BindRepeating(&TCPConnectedSocket::OnNetworkReadCompleted, + base::Unretained(this))); + if (read_result == net::ERR_IO_PENDING) + return; + OnNetworkReadCompleted(read_result); +} + +void TCPConnectedSocket::OnReceiveStreamWritable(MojoResult result) { + if (result != MOJO_RESULT_OK) { + ShutdownReceive(); + return; + } + ReceiveMore(); +} + +void TCPConnectedSocket::OnNetworkReadCompleted(int bytes_read) { + DCHECK(pending_receive_); + + if (bytes_read < 0) + observer_->OnReadError(bytes_read); + + if (bytes_read <= 0) { + ShutdownReceive(); + return; + } + if (bytes_read > 0) { + receive_stream_ = pending_receive_->Complete(bytes_read); + pending_receive_ = nullptr; + ReceiveMore(); + } +} + +void TCPConnectedSocket::ShutdownReceive() { + writable_handle_watcher_.Cancel(); + pending_receive_ = nullptr; + receive_stream_.reset(); +} + +void TCPConnectedSocket::SendMore() { + DCHECK(send_stream_.is_valid()); + DCHECK(!pending_send_); + + uint32_t num_bytes = 0; + MojoResult result = MojoToNetPendingBuffer::BeginRead( + &send_stream_, &pending_send_, &num_bytes); + if (result == MOJO_RESULT_SHOULD_WAIT) { + readable_handle_watcher_.ArmOrNotify(); + return; + } + if (result != MOJO_RESULT_OK) { + ShutdownSend(); + return; + } + DCHECK_EQ(MOJO_RESULT_OK, result); + DCHECK(pending_send_); + scoped_refptr<net::IOBuffer> buf( + new net::WrappedIOBuffer(pending_send_->buffer())); + int write_result = socket_->Write( + buf.get(), static_cast<int>(num_bytes), + base::BindRepeating(&TCPConnectedSocket::OnNetworkWriteCompleted, + base::Unretained(this)), + traffic_annotation_); + if (write_result == net::ERR_IO_PENDING) + return; + OnNetworkWriteCompleted(write_result); +} + +void TCPConnectedSocket::OnSendStreamReadable(MojoResult result) { + if (result != MOJO_RESULT_OK) { + ShutdownSend(); + return; + } + SendMore(); +} + +void TCPConnectedSocket::OnNetworkWriteCompleted(int bytes_written) { + DCHECK(pending_send_); + + if (bytes_written < 0) + observer_->OnWriteError(bytes_written); + if (bytes_written <= 0) { + ShutdownSend(); + return; + } + + if (bytes_written > 0) { + // Partial write is possible. + pending_send_->CompleteRead(bytes_written); + send_stream_ = pending_send_->ReleaseHandle(); + pending_send_ = nullptr; + SendMore(); + } +} + +void TCPConnectedSocket::ShutdownSend() { + readable_handle_watcher_.Cancel(); + pending_send_ = nullptr; + send_stream_.reset(); +} + +} // namespace network
diff --git a/services/network/tcp_connected_socket.h b/services/network/tcp_connected_socket.h new file mode 100644 index 0000000..17665feb --- /dev/null +++ b/services/network/tcp_connected_socket.h
@@ -0,0 +1,106 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_ +#define SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_ + +#include <memory> + +#include "base/component_export.h" +#include "base/containers/span.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "net/base/address_family.h" +#include "net/base/completion_callback.h" +#include "net/base/ip_endpoint.h" +#include "net/interfaces/address_family.mojom.h" +#include "net/interfaces/ip_endpoint.mojom.h" +#include "net/socket/tcp_client_socket.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/net_adapters.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" + +namespace net { +class NetLog; +class StreamSocket; +} // namespace net + +namespace network { + +class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket + : public mojom::TCPConnectedSocket { + public: + TCPConnectedSocket( + mojom::TCPConnectedSocketObserverPtr observer, + net::NetLog* net_log, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + TCPConnectedSocket( + mojom::TCPConnectedSocketObserverPtr observer, + std::unique_ptr<net::StreamSocket> socket, + mojo::ScopedDataPipeProducerHandle receive_pipe_handle, + mojo::ScopedDataPipeConsumerHandle send_pipe_handle, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + ~TCPConnectedSocket() override; + void Connect( + const base::Optional<net::IPEndPoint>& local_addr, + const net::AddressList& remote_addr_list, + mojom::NetworkContext::CreateTCPConnectedSocketCallback callback); + + // mojom::TCPConnectedSocket implementation. + void GetLocalAddress(GetLocalAddressCallback callback) override; + + private: + // Invoked when net::TCPClientSocket::Connect() completes. + void OnConnectCompleted(int net_result); + + // Helper to start watching |send_stream_| and |receive_stream_|. + void StartWatching(); + + // "Receiving" in this context means reading from |socket_| and writing to + // the Mojo |receive_stream_|. + void ReceiveMore(); + void OnReceiveStreamWritable(MojoResult result); + void OnNetworkReadCompleted(int result); + void ShutdownReceive(); + + // "Writing" is reading from the Mojo |send_stream_| and writing to the + // |socket_|. + void SendMore(); + void OnSendStreamReadable(MojoResult result); + void OnNetworkWriteCompleted(int result); + void ShutdownSend(); + + mojom::TCPConnectedSocketObserverPtr observer_; + + net::NetLog* net_log_; + + std::unique_ptr<net::StreamSocket> socket_; + + mojom::NetworkContext::CreateTCPConnectedSocketCallback connect_callback_; + + // The *stream handles will be null while there is an in-progress transation + // between net and mojo. During this time, the handle will be owned by the + // *PendingBuffer. + + // For reading from the Mojo pipe and writing to the network. + mojo::ScopedDataPipeConsumerHandle send_stream_; + scoped_refptr<MojoToNetPendingBuffer> pending_send_; + mojo::SimpleWatcher readable_handle_watcher_; + + // For reading from the network and writing to Mojo pipe. + mojo::ScopedDataPipeProducerHandle receive_stream_; + scoped_refptr<NetToMojoPendingBuffer> pending_receive_; + mojo::SimpleWatcher writable_handle_watcher_; + + net::NetworkTrafficAnnotationTag traffic_annotation_; + + DISALLOW_COPY_AND_ASSIGN(TCPConnectedSocket); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_
diff --git a/services/network/tcp_server_socket.cc b/services/network/tcp_server_socket.cc new file mode 100644 index 0000000..e8f53dc --- /dev/null +++ b/services/network/tcp_server_socket.cc
@@ -0,0 +1,123 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/tcp_server_socket.h" + +#include <utility> + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/numerics/safe_conversions.h" +#include "base/optional.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/log/net_log.h" +#include "net/socket/tcp_server_socket.h" +#include "services/network/tcp_connected_socket.h" + +namespace network { + +TCPServerSocket::TCPServerSocket( + Delegate* delegate, + net::NetLog* net_log, + const net::NetworkTrafficAnnotationTag& traffic_annotation) + : delegate_(delegate), + socket_( + std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource())), + backlog_(0), + traffic_annotation_(traffic_annotation), + weak_factory_(this) {} + +TCPServerSocket::~TCPServerSocket() {} + +int TCPServerSocket::Listen(const net::IPEndPoint& local_addr, + int backlog, + net::IPEndPoint* local_addr_out) { + if (backlog == 0) { + // SocketPosix::Listen and TCPSocketWin::Listen DCHECKs on backlog > 0. + return net::ERR_INVALID_ARGUMENT; + } + backlog_ = backlog; + int net_error = socket_->Listen(local_addr, backlog); + if (net_error == net::OK) + socket_->GetLocalAddress(local_addr_out); + return net_error; +} + +void TCPServerSocket::Accept(mojom::TCPConnectedSocketObserverPtr observer, + AcceptCallback callback) { + if (pending_accepts_queue_.size() >= static_cast<size_t>(backlog_)) { + std::move(callback).Run(net::ERR_INSUFFICIENT_RESOURCES, base::nullopt, + nullptr, mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + return; + } + + pending_accepts_queue_.push_back(std::make_unique<PendingAccept>( + std::move(callback), std::move(observer))); + if (pending_accepts_queue_.size() == 1) + ProcessNextAccept(); +} + +void TCPServerSocket::SetSocketForTest( + std::unique_ptr<net::ServerSocket> socket) { + socket_ = std::move(socket); +} + +TCPServerSocket::PendingAccept::PendingAccept( + AcceptCallback callback, + mojom::TCPConnectedSocketObserverPtr observer) + : callback(std::move(callback)), observer(std::move(observer)) {} + +TCPServerSocket::PendingAccept::~PendingAccept() {} + +void TCPServerSocket::OnAcceptCompleted(int result) { + DCHECK_NE(net::ERR_IO_PENDING, result); + DCHECK(!pending_accepts_queue_.empty()); + + auto pending_accept = std::move(pending_accepts_queue_.front()); + pending_accepts_queue_.erase(pending_accepts_queue_.begin()); + + net::IPEndPoint peer_addr; + if (result == net::OK) { + DCHECK(accepted_socket_); + result = accepted_socket_->GetPeerAddress(&peer_addr); + } + if (result == net::OK) { + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + mojom::TCPConnectedSocketPtr socket; + auto connected_socket = std::make_unique<TCPConnectedSocket>( + std::move(pending_accept->observer), + base::WrapUnique(accepted_socket_.release()), + std::move(receive_pipe.producer_handle), + std::move(send_pipe.consumer_handle), traffic_annotation_); + delegate_->OnAccept(std::move(connected_socket), + mojo::MakeRequest(&socket)); + std::move(pending_accept->callback) + .Run(result, peer_addr, std::move(socket), + std::move(receive_pipe.consumer_handle), + std::move(send_pipe.producer_handle)); + } else { + std::move(pending_accept->callback) + .Run(result, base::nullopt, nullptr, + mojo::ScopedDataPipeConsumerHandle(), + mojo::ScopedDataPipeProducerHandle()); + } + ProcessNextAccept(); +} + +void TCPServerSocket::ProcessNextAccept() { + if (pending_accepts_queue_.empty()) + return; + int result = + socket_->Accept(&accepted_socket_, + base::BindRepeating(&TCPServerSocket::OnAcceptCompleted, + base::Unretained(this))); + if (result == net::ERR_IO_PENDING) + return; + OnAcceptCompleted(result); +} + +} // namespace network
diff --git a/services/network/tcp_server_socket.h b/services/network/tcp_server_socket.h new file mode 100644 index 0000000..0b52d11d --- /dev/null +++ b/services/network/tcp_server_socket.h
@@ -0,0 +1,91 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_NETWORK_TCP_SERVER_SOCKET_H_ +#define SERVICES_NETWORK_TCP_SERVER_SOCKET_H_ + +#include <memory> +#include <vector> + +#include "base/component_export.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "net/base/ip_endpoint.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/mojom/tcp_socket.mojom.h" + +namespace net { +class NetLog; +class ServerSocket; +class StreamSocket; +} // namespace net + +namespace network { +class TCPConnectedSocket; + +class COMPONENT_EXPORT(NETWORK_SERVICE) TCPServerSocket + : public mojom::TCPServerSocket { + public: + // A delegate interface that is notified when new connections are established. + class Delegate { + public: + Delegate() {} + ~Delegate() {} + + // Invoked when a new connection is accepted. The delegate should take + // ownership of |socket| and set up binding for |request|. + virtual void OnAccept(std::unique_ptr<TCPConnectedSocket> socket, + mojom::TCPConnectedSocketRequest request) = 0; + }; + + // Constructs a TCPServerSocket. |delegate| must outlive |this|. When a new + // connection is accepted, |delegate| will be notified to take ownership of + // the connection. + TCPServerSocket(Delegate* delegate, + net::NetLog* net_log, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + ~TCPServerSocket() override; + + int Listen(const net::IPEndPoint& local_addr, + int backlog, + net::IPEndPoint* local_addr_out); + + // TCPServerSocket implementation. + void Accept(mojom::TCPConnectedSocketObserverPtr observer, + AcceptCallback callback) override; + + // Replaces the underlying socket implementation with |socket| in tests. + void SetSocketForTest(std::unique_ptr<net::ServerSocket> socket); + + private: + struct PendingAccept { + PendingAccept(AcceptCallback callback, + mojom::TCPConnectedSocketObserverPtr observer); + ~PendingAccept(); + + AcceptCallback callback; + mojom::TCPConnectedSocketObserverPtr observer; + }; + // Invoked when socket_->Accept() completes. + void OnAcceptCompleted(int result); + // Process the next Accept() from |pending_accepts_queue_|. + void ProcessNextAccept(); + + Delegate* delegate_; + std::unique_ptr<net::ServerSocket> socket_; + int backlog_; + std::vector<std::unique_ptr<PendingAccept>> pending_accepts_queue_; + std::unique_ptr<net::StreamSocket> accepted_socket_; + net::NetworkTrafficAnnotationTag traffic_annotation_; + + base::WeakPtrFactory<TCPServerSocket> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(TCPServerSocket); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
diff --git a/services/network/tcp_socket_unittest.cc b/services/network/tcp_socket_unittest.cc new file mode 100644 index 0000000..dfb9bb1 --- /dev/null +++ b/services/network/tcp_socket_unittest.cc
@@ -0,0 +1,939 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdint.h> + +#include <utility> +#include <vector> + +#include "base/callback_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread.h" +#include "mojo/common/data_pipe_utils.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "net/base/completion_callback.h" +#include "net/base/completion_once_callback.h" +#include "net/base/net_errors.h" +#include "net/base/test_completion_callback.h" +#include "net/socket/server_socket.h" +#include "net/socket/socket_test_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/udp_socket.mojom.h" +#include "services/network/socket_factory.h" +#include "services/network/tcp_connected_socket.h" +#include "services/network/tcp_server_socket.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace network { + +namespace { + +// A mock ServerSocket that completes Accept() using a specified result. +class MockServerSocket : public net::ServerSocket { + public: + MockServerSocket() {} + ~MockServerSocket() override {} + + // net::ServerSocket implementation. + int Listen(const net::IPEndPoint& address, int backlog) override { + return net::OK; + } + + int GetLocalAddress(net::IPEndPoint* address) const override { + return net::OK; + } + + int Accept(std::unique_ptr<net::StreamSocket>* socket, + const net::CompletionCallback& callback) override { + DCHECK(accept_callback_.is_null()); + if (accept_result_ == net::OK && mode_ == net::SYNCHRONOUS) + *socket = CreateMockAcceptSocket(); + if (mode_ == net::ASYNC || accept_result_ == net::ERR_IO_PENDING) { + accept_socket_ = socket; + accept_callback_ = callback; + } + run_loop_.Quit(); + + if (mode_ == net::ASYNC) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&MockServerSocket::CompleteAccept, + base::Unretained(this), accept_result_)); + return net::ERR_IO_PENDING; + } + return accept_result_; + } + + void SetAcceptResult(net::IoMode mode, int result) { + // It doesn't make sense to return net::ERR_IO_PENDING asynchronously. + DCHECK(!(mode == net::ASYNC && result == net::ERR_IO_PENDING)); + + mode_ = mode; + accept_result_ = result; + } + + void WaitForFirstAccept() { run_loop_.Run(); } + + void CompleteAccept(int result) { + DCHECK(!accept_callback_.is_null()); + DCHECK_NE(net::ERR_IO_PENDING, result); + + *accept_socket_ = CreateMockAcceptSocket(); + accept_socket_ = nullptr; + base::ResetAndReturn(&accept_callback_).Run(result); + } + + private: + // Must live longer than all SocketDataProviders. + const net::MockRead kReads[1] = { + net::MockRead(net::ASYNC, net::ERR_IO_PENDING)}; + + std::unique_ptr<net::StreamSocket> CreateMockAcceptSocket() { + auto data_provider = std::make_unique<net::StaticSocketDataProvider>( + kReads, arraysize(kReads), nullptr, 0); + data_provider->set_connect_data( + net::MockConnect(net::SYNCHRONOUS, net::OK)); + auto mock_socket = std::make_unique<net::MockTCPClientSocket>( + net::AddressList(), nullptr /*netlog*/, data_provider.get()); + data_providers_.push_back(std::move(data_provider)); + EXPECT_EQ(net::OK, mock_socket->Connect(base::DoNothing())); + return std::move(mock_socket); + } + + net::IoMode mode_ = net::SYNCHRONOUS; + int accept_result_ = net::OK; + net::CompletionCallback accept_callback_; + std::unique_ptr<net::StreamSocket>* accept_socket_; + base::RunLoop run_loop_; + std::vector<std::unique_ptr<net::StaticSocketDataProvider>> data_providers_; +}; + +class TestTCPConnectedSocketObserver + : public mojom::TCPConnectedSocketObserver { + public: + TestTCPConnectedSocketObserver() : binding_(this) {} + ~TestTCPConnectedSocketObserver() override { + EXPECT_EQ(net::OK, read_error_); + EXPECT_EQ(net::OK, write_error_); + } + + // Returns a mojo pointer. This can only be called once. + mojom::TCPConnectedSocketObserverPtr GetObserverPtr() { + DCHECK(!binding_); + mojom::TCPConnectedSocketObserverPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + return ptr; + } + + // Waits for Read and Write error. Returns the error observed. + int WaitForReadError() { + read_loop_.Run(); + int error = read_error_; + read_error_ = net::OK; + return error; + } + + int WaitForWriteError() { + write_loop_.Run(); + int error = write_error_; + write_error_ = net::OK; + return error; + } + + private: + // mojom::TCPConnectedSocketObserver implementation. + void OnReadError(int net_error) override { + read_error_ = net_error; + read_loop_.Quit(); + } + + void OnWriteError(int net_error) override { + write_error_ = net_error; + write_loop_.Quit(); + } + + int read_error_ = net::OK; + int write_error_ = net::OK; + base::RunLoop read_loop_; + base::RunLoop write_loop_; + mojo::Binding<mojom::TCPConnectedSocketObserver> binding_; + + DISALLOW_COPY_AND_ASSIGN(TestTCPConnectedSocketObserver); +}; + +// A server implemented using mojom::TCPServerSocket. It owns the server socket +// pointer and as well as client connections. SendData() and StartReading() +// operate on the newest client connection. +class TestServer { + public: + TestServer() + : TestServer(net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0)) {} + explicit TestServer(const net::IPEndPoint& server_addr) + : factory_(nullptr), + readable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC), + server_addr_(server_addr) {} + ~TestServer() {} + + void Start(uint32_t backlog) { + int net_error = net::ERR_FAILED; + base::RunLoop run_loop; + factory_.CreateTCPServerSocket( + server_addr_, backlog, TRAFFIC_ANNOTATION_FOR_TESTS, + mojo::MakeRequest(&server_socket_), + base::BindOnce( + [](base::RunLoop* run_loop, int* result_out, + net::IPEndPoint* local_addr_out, int result, + const base::Optional<net::IPEndPoint>& local_addr) { + *result_out = result; + if (local_addr) + *local_addr_out = local_addr.value(); + run_loop->Quit(); + }, + base::Unretained(&run_loop), base::Unretained(&net_error), + base::Unretained(&server_addr_))); + run_loop.Run(); + EXPECT_EQ(net::OK, net_error); + } + + // Accepts one connection. Upon successful completion, |callback| will be + // invoked. + void AcceptOneConnection(net::CompletionOnceCallback callback) { + observer_ = std::make_unique<TestTCPConnectedSocketObserver>(); + server_socket_->Accept( + observer_->GetObserverPtr(), + base::BindOnce(&TestServer::OnAccept, base::Unretained(this), + std::move(callback))); + } + + // Sends data over the most recent connection that is established. + void SendData(const std::string& msg) { + EXPECT_TRUE( + mojo::common::BlockingCopyFromString(msg, server_socket_send_handle_)); + } + + // Starts reading. Can be called multiple times. It cancels any previous + // StartReading(). Once |expected_contents| is read, |callback| will be + // invoked. If an error occurs or the pipe is broken before read can + // complete, |callback| will be run, but ADD_FAILURE() will be called. + void StartReading(const std::string& expected_contents, + base::OnceClosure callback) { + readable_handle_watcher_.Cancel(); + received_contents_.clear(); + expected_contents_ = expected_contents; + read_callback_ = std::move(callback); + readable_handle_watcher_.Watch( + server_socket_receive_handle_.get(), + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + base::BindRepeating(&TestServer::OnReadable, base::Unretained(this))); + } + + void DestroyServerSocket() { server_socket_.reset(); } + + const net::IPEndPoint& server_addr() { return server_addr_; } + + private: + void OnAccept(net::CompletionOnceCallback callback, + int result, + const base::Optional<net::IPEndPoint>& remote_addr, + mojom::TCPConnectedSocketPtr connected_socket, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + connected_sockets_.push_back(std::move(connected_socket)); + server_socket_receive_handle_ = std::move(receive_pipe_handle); + server_socket_send_handle_ = std::move(send_pipe_handle); + std::move(callback).Run(result); + } + + void OnReadable(MojoResult result) { + if (result != MOJO_RESULT_OK) { + ADD_FAILURE() << "Unexpected broken pipe with error: " << result; + EXPECT_EQ(expected_contents_, received_contents_); + std::move(read_callback_).Run(); + return; + } + char buffer[16]; + uint32_t read_size = sizeof(buffer); + result = server_socket_receive_handle_->ReadData(buffer, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) + return; + if (result != MOJO_RESULT_OK) { + ADD_FAILURE() << "Unexpected read error: " << result; + EXPECT_EQ(expected_contents_, received_contents_); + std::move(read_callback_).Run(); + return; + } + + received_contents_.append(buffer, read_size); + + if (received_contents_.size() == expected_contents_.size()) { + EXPECT_EQ(expected_contents_, received_contents_); + std::move(read_callback_).Run(); + } + } + + SocketFactory factory_; + mojom::TCPServerSocketPtr server_socket_; + std::vector<mojom::TCPConnectedSocketPtr> connected_sockets_; + std::unique_ptr<TestTCPConnectedSocketObserver> observer_; + mojo::ScopedDataPipeConsumerHandle server_socket_receive_handle_; + mojo::ScopedDataPipeProducerHandle server_socket_send_handle_; + mojo::SimpleWatcher readable_handle_watcher_; + net::IPEndPoint server_addr_; + std::string expected_contents_; + base::OnceClosure read_callback_; + std::string received_contents_; +}; + +} // namespace + +class TCPSocketTest : public testing::Test { + public: + TCPSocketTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO), + factory_(nullptr /*net_log*/) {} + ~TCPSocketTest() override {} + + // Reads |num_bytes| from |handle| or reads until an error occurs. Returns the + // bytes read as a string. + std::string Read(mojo::ScopedDataPipeConsumerHandle* handle, + size_t num_bytes) { + std::string received_contents; + while (received_contents.size() < num_bytes) { + base::RunLoop().RunUntilIdle(); + std::vector<char> buffer(num_bytes); + uint32_t read_size = static_cast<uint32_t>(num_bytes); + MojoResult result = handle->get().ReadData(buffer.data(), &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) + continue; + if (result != MOJO_RESULT_OK) + return received_contents; + received_contents.append(buffer.data(), read_size); + } + return received_contents; + } + + // Creates a TCPServerSocket with the mock server socket, |socket|. + void CreateServerSocketWithMockSocket( + uint32_t backlog, + mojom::TCPServerSocketRequest request, + std::unique_ptr<net::ServerSocket> socket) { + auto server_socket_impl = std::make_unique<TCPServerSocket>( + &factory_, nullptr /*netlog*/, TRAFFIC_ANNOTATION_FOR_TESTS); + server_socket_impl->SetSocketForTest(std::move(socket)); + net::IPEndPoint local_addr; + EXPECT_EQ(net::OK, + server_socket_impl->Listen(local_addr, backlog, &local_addr)); + tcp_server_socket_bindings_.AddBinding(std::move(server_socket_impl), + std::move(request)); + } + + // Creates a TCPConnectedSocket with a mock client socket, |socket|. + // This can be only called once. + void CreateConnectedSocketWithMockSocket( + mojom::TCPConnectedSocketRequest request, + mojo::ScopedDataPipeProducerHandle receive_pipe_handle, + mojo::ScopedDataPipeConsumerHandle send_pipe_handle, + std::unique_ptr<net::MockTCPClientSocket> socket) { + net::TestCompletionCallback dummy_callback; + EXPECT_EQ(net::OK, socket->Connect(dummy_callback.callback())); + auto socket_impl = std::make_unique<TCPConnectedSocket>( + test_observer_.GetObserverPtr(), std::move(socket), + std::move(receive_pipe_handle), std::move(send_pipe_handle), + TRAFFIC_ANNOTATION_FOR_TESTS); + tcp_connected_socket_bindings_.AddBinding(std::move(socket_impl), + std::move(request)); + } + + int CreateTCPConnectedSocketSync( + mojom::TCPConnectedSocketRequest request, + mojom::TCPConnectedSocketObserverPtr observer, + const base::Optional<net::IPEndPoint>& local_addr, + const net::IPEndPoint& remote_addr, + mojo::ScopedDataPipeConsumerHandle* receive_pipe_handle_out, + mojo::ScopedDataPipeProducerHandle* send_pipe_handle_out) { + net::AddressList remote_addr_list(remote_addr); + base::RunLoop run_loop; + int net_error = net::ERR_FAILED; + factory_.CreateTCPConnectedSocket( + local_addr, remote_addr_list, TRAFFIC_ANNOTATION_FOR_TESTS, + std::move(request), std::move(observer), + base::BindOnce( + [](base::RunLoop* run_loop, int* result_out, + mojo::ScopedDataPipeConsumerHandle* consumer_handle, + mojo::ScopedDataPipeProducerHandle* producer_handle, int result, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + *result_out = result; + *consumer_handle = std::move(receive_pipe_handle); + *producer_handle = std::move(send_pipe_handle); + run_loop->Quit(); + }, + base::Unretained(&run_loop), base::Unretained(&net_error), + receive_pipe_handle_out, send_pipe_handle_out)); + run_loop.Run(); + return net_error; + } + + TestTCPConnectedSocketObserver* observer() { return &test_observer_; } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + SocketFactory factory_; + TestTCPConnectedSocketObserver test_observer_; + mojo::StrongBindingSet<mojom::TCPServerSocket> tcp_server_socket_bindings_; + mojo::StrongBindingSet<mojom::TCPConnectedSocket> + tcp_connected_socket_bindings_; + + DISALLOW_COPY_AND_ASSIGN(TCPSocketTest); +}; + +TEST_F(TCPSocketTest, ReadAndWrite) { + const struct TestData { + base::Optional<net::IPEndPoint> client_addr; + net::IPEndPoint server_addr; + } kTestCases[] = { + {base::nullopt, net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0)}, + {base::nullopt, net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0)}, + {net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0), + net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0)}, + {net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0), + net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0)}, + }; + for (auto test : kTestCases) { + TestServer server(test.server_addr); + server.Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server.AcceptOneConnection(accept_callback.callback()); + + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + + mojom::TCPConnectedSocketPtr client_socket; + TestTCPConnectedSocketObserver observer; + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + test.client_addr, server.server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + ASSERT_EQ(net::OK, accept_callback.WaitForResult()); + + // Test sending data from server to client. + const char kTestMsg[] = "hello"; + server.SendData(kTestMsg); + EXPECT_EQ(kTestMsg, + Read(&client_socket_receive_handle, arraysize(kTestMsg) - 1)); + + // Test sending data from client to server. + base::RunLoop read_run_loop; + server.StartReading(kTestMsg, read_run_loop.QuitClosure()); + EXPECT_TRUE(mojo::common::BlockingCopyFromString( + kTestMsg, client_socket_send_handle)); + read_run_loop.Run(); + } +} + +TEST_F(TCPSocketTest, CannotConnectToWrongInterface) { + const struct TestData { + net::IPEndPoint client_addr; + net::IPEndPoint server_addr; + } kTestCases[] = { + {net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0), + net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0)}, + {net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0), + net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0)}, + }; + for (auto test : kTestCases) { + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + + TestTCPConnectedSocketObserver observer; + TestServer server(test.server_addr); + server.Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server.AcceptOneConnection(accept_callback.callback()); + + mojom::TCPConnectedSocketPtr client_socket; + int result = CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + test.client_addr, server.server_addr(), &client_socket_receive_handle, + &client_socket_send_handle); + // Both net::ERR_INVALID_ARGUMENT and net::ERR_ADDRESS_UNREACHABLE can be + // returned. On Linux, for eample, the former is returned when talking ipv4 + // to a ipv6 remote, and the latter is returned when talking ipv6 to a ipv4 + // remote. net::ERR_CONNECTION_FAILED is returned on Windows. + EXPECT_TRUE(result == net::ERR_CONNECTION_FAILED || + result == net::ERR_INVALID_ARGUMENT || + result == net::ERR_ADDRESS_UNREACHABLE) + << "actual result: " << result; + } +} + +// TODO(xunjieli): This test is flaky on MacOS crbug.com/821224. +TEST_F(TCPSocketTest, DISABLED_ServerReceivesMultipleAccept) { + uint32_t backlog = 10; + TestServer server; + server.Start(backlog); + + std::vector<std::unique_ptr<net::TestCompletionCallback>> accept_callbacks; + // Issue |backlog| Accepts(), so the queue is filled up. + for (size_t i = 0; i < backlog; ++i) { + auto callback = std::make_unique<net::TestCompletionCallback>(); + server.AcceptOneConnection(callback->callback()); + accept_callbacks.push_back(std::move(callback)); + } + // Accept() beyond the queue size should fail immediately. + net::TestCompletionCallback callback; + server.AcceptOneConnection(callback.callback()); + EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, callback.WaitForResult()); + + // After handling incoming connections, all callbacks should now complete. + for (size_t i = 0; i < backlog; ++i) { + TestTCPConnectedSocketObserver observer; + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + mojom::TCPConnectedSocketPtr client_socket; + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + base::nullopt /*local_addr*/, server.server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + } + for (const auto& callback : accept_callbacks) { + EXPECT_EQ(net::OK, callback->WaitForResult()); + } +} + +// Tests that if a socket is closed, the other side can observe that the pipes +// are broken. +TEST_F(TCPSocketTest, SocketClosed) { + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + mojom::TCPConnectedSocketPtr client_socket; + + TestTCPConnectedSocketObserver observer; + const char kTestMsg[] = "hello"; + auto server = std::make_unique<TestServer>(); + server->Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server->AcceptOneConnection(accept_callback.callback()); + + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + base::nullopt /*local_addr*/, server->server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + ASSERT_EQ(net::OK, accept_callback.WaitForResult()); + + // Send some data from server to client. + server->SendData(kTestMsg); + EXPECT_EQ(kTestMsg, + Read(&client_socket_receive_handle, arraysize(kTestMsg) - 1)); + // Resetting the |server| destroys the TCPConnectedSocket ptr owned by the + // server. + server = nullptr; + + // Read should return EOF. + EXPECT_EQ("", Read(&client_socket_receive_handle, 1)); + + // Read from |client_socket_receive_handle| again should return that the pipe + // is broken. + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult mojo_result = client_socket_receive_handle->ReadData( + buffer, &read_size, MOJO_READ_DATA_FLAG_NONE); + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, mojo_result); + EXPECT_TRUE(client_socket_receive_handle->QuerySignalsState().peer_closed()); + + // Send pipe should be closed. + while (true) { + base::RunLoop().RunUntilIdle(); + uint32_t size = arraysize(kTestMsg); + MojoResult r = client_socket_send_handle->WriteData( + kTestMsg, &size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); + if (r == MOJO_RESULT_SHOULD_WAIT) + continue; + if (r == MOJO_RESULT_FAILED_PRECONDITION) + break; + } + EXPECT_TRUE(client_socket_send_handle->QuerySignalsState().peer_closed()); + int result = observer.WaitForWriteError(); + EXPECT_TRUE(result == net::ERR_CONNECTION_RESET || + result == net::ERR_CONNECTION_ABORTED) + << "actual result: " << result; +} + +TEST_F(TCPSocketTest, ReadPipeClosed) { + TestTCPConnectedSocketObserver observer; + const char kTestMsg[] = "hello"; + TestServer server; + server.Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server.AcceptOneConnection(accept_callback.callback()); + + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + mojom::TCPConnectedSocketPtr client_socket; + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + base::nullopt /*local_addr*/, server.server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + ASSERT_EQ(net::OK, accept_callback.WaitForResult()); + + // Close |client_socket_receive_handle|. The socket should remain open. + client_socket_receive_handle.reset(); + + // Send should proceed as normal. + base::RunLoop read_run_loop; + server.StartReading(kTestMsg, read_run_loop.QuitClosure()); + EXPECT_TRUE(mojo::common::BlockingCopyFromString(kTestMsg, + client_socket_send_handle)); + read_run_loop.Run(); +} + +TEST_F(TCPSocketTest, WritePipeClosed) { + TestTCPConnectedSocketObserver observer; + const char kTestMsg[] = "hello"; + TestServer server; + server.Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server.AcceptOneConnection(accept_callback.callback()); + + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + mojom::TCPConnectedSocketPtr client_socket; + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + base::nullopt /*local_addr*/, server.server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + ASSERT_EQ(net::OK, accept_callback.WaitForResult()); + + // Close |client_socket_send_handle|. The socket should remain open. + client_socket_send_handle.reset(); + + // Receive should proceed as normal. + server.SendData(kTestMsg); + EXPECT_EQ(kTestMsg, + Read(&client_socket_receive_handle, arraysize(kTestMsg) - 1)); +} + +// Tests that if the server socket is destroyed, any connected sockets that it +// handed out remain alive. +TEST_F(TCPSocketTest, ServerSocketClosedAcceptedSocketAlive) { + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle; + mojo::ScopedDataPipeProducerHandle client_socket_send_handle; + + TestTCPConnectedSocketObserver observer; + const char kTestMsg[] = "hello"; + TestServer server; + server.Start(1 /*backlog*/); + net::TestCompletionCallback accept_callback; + server.AcceptOneConnection(accept_callback.callback()); + + mojom::TCPConnectedSocketPtr client_socket; + EXPECT_EQ(net::OK, + CreateTCPConnectedSocketSync( + mojo::MakeRequest(&client_socket), observer.GetObserverPtr(), + base::nullopt /*local_addr*/, server.server_addr(), + &client_socket_receive_handle, &client_socket_send_handle)); + ASSERT_EQ(net::OK, accept_callback.WaitForResult()); + + // Now destroys the server socket. + server.DestroyServerSocket(); + base::RunLoop().RunUntilIdle(); + + // Sending and receiving should still work. + server.SendData(kTestMsg); + EXPECT_EQ(kTestMsg, + Read(&client_socket_receive_handle, arraysize(kTestMsg) - 1)); + + base::RunLoop read_run_loop; + server.StartReading(kTestMsg, read_run_loop.QuitClosure()); + EXPECT_TRUE(mojo::common::BlockingCopyFromString(kTestMsg, + client_socket_send_handle)); + read_run_loop.Run(); +} + +// Tests both async and sync cases. +class TCPSocketWithMockSocketTest + : public TCPSocketTest, + public ::testing::WithParamInterface<net::IoMode> {}; + +INSTANTIATE_TEST_CASE_P(/* no prefix */, + TCPSocketWithMockSocketTest, + testing::Values(net::SYNCHRONOUS, net::ASYNC)); + +// Tests that a server socket handles Accept() correctly when the underlying +// implementation completes Accept() in sync and async mode. +TEST_P(TCPSocketWithMockSocketTest, + ServerAcceptClientConnectionWithMockSocket) { + net::IoMode mode = GetParam(); + auto mock_server_socket = std::make_unique<MockServerSocket>(); + MockServerSocket* mock_server_socket_raw = mock_server_socket.get(); + mojom::TCPServerSocketPtr server_socket; + uint32_t kBacklog = 10; + // Use a mock socket to control net::ServerSocket::Accept() behavior. + CreateServerSocketWithMockSocket(kBacklog, mojo::MakeRequest(&server_socket), + std::move(mock_server_socket)); + + // Complete first Accept() using manual completion via CompleteAccept(). + mock_server_socket_raw->SetAcceptResult(net::SYNCHRONOUS, + net::ERR_IO_PENDING); + std::vector<std::unique_ptr<net::TestCompletionCallback>> accept_callbacks; + for (size_t i = 0; i < kBacklog; ++i) { + auto callback = std::make_unique<net::TestCompletionCallback>(); + TestTCPConnectedSocketObserver observer; + server_socket->Accept( + observer.GetObserverPtr(), + base::BindOnce( + [](net::CompletionOnceCallback callback, int result, + const base::Optional<net::IPEndPoint>& remote_addr, + mojom::TCPConnectedSocketPtr connected_socket, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + std::move(callback).Run(result); + }, + std::move(callback->callback()))); + accept_callbacks.push_back(std::move(callback)); + } + + mock_server_socket_raw->WaitForFirstAccept(); + mock_server_socket_raw->SetAcceptResult(mode, net::OK); + mock_server_socket_raw->CompleteAccept(net::OK); + + // First net::ServerSocket::Accept() will complete asynchronously + // internally. Other queued Accept() will complete + // synchronously/asynchronously depending on |mode| internally. + for (const auto& callback : accept_callbacks) { + EXPECT_EQ(net::OK, callback->WaitForResult()); + } + + // New Accept() should complete synchronously internally. Make sure this is + // okay. + auto callback = std::make_unique<net::TestCompletionCallback>(); + TestTCPConnectedSocketObserver observer; + server_socket->Accept( + observer.GetObserverPtr(), + base::BindOnce( + [](net::CompletionOnceCallback callback, int result, + const base::Optional<net::IPEndPoint>& remote_addr, + mojom::TCPConnectedSocketPtr connected_socket, + mojo::ScopedDataPipeConsumerHandle receive_pipe_handle, + mojo::ScopedDataPipeProducerHandle send_pipe_handle) { + std::move(callback).Run(result); + }, + std::move(callback->callback()))); + EXPECT_EQ(net::OK, callback->WaitForResult()); +} + +TEST_P(TCPSocketWithMockSocketTest, ReadAndWriteMultiple) { + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle = + std::move(receive_pipe.consumer_handle); + mojo::ScopedDataPipeProducerHandle client_socket_send_handle = + std::move(send_pipe.producer_handle); + + mojom::TCPConnectedSocketPtr client_socket; + const char kTestMsg[] = "abcdefghij"; + const size_t kMsgSize = arraysize(kTestMsg) - 1; + const int kNumIterations = 3; + std::vector<net::MockRead> reads; + std::vector<net::MockWrite> writes; + int sequence_number = 0; + net::IoMode mode = GetParam(); + for (int j = 0; j < kNumIterations; ++j) { + for (size_t i = 0; i < kMsgSize; ++i) { + reads.push_back(net::MockRead(mode, &kTestMsg[i], 1, sequence_number++)); + } + if (j == kNumIterations - 1) { + reads.push_back(net::MockRead(mode, net::OK, sequence_number++)); + } + for (size_t i = 0; i < kMsgSize; ++i) { + writes.push_back( + net::MockWrite(mode, &kTestMsg[i], 1, sequence_number++)); + } + } + net::StaticSocketDataProvider data_provider(reads.data(), reads.size(), + writes.data(), writes.size()); + data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK)); + auto mock_socket = std::make_unique<net::MockTCPClientSocket>( + net::AddressList(), nullptr /*netlog*/, &data_provider); + + CreateConnectedSocketWithMockSocket(mojo::MakeRequest(&client_socket), + std::move(receive_pipe.producer_handle), + std::move(send_pipe.consumer_handle), + std::move(mock_socket)); + + // Loop kNumIterations times to test that writes can follow reads, and reads + // can follow writes. + for (int j = 0; j < kNumIterations; ++j) { + // Reading kMsgSize should coalesce the 1-byte mock reads. + EXPECT_EQ(kTestMsg, Read(&client_socket_receive_handle, kMsgSize)); + // Write multiple times. + for (size_t i = 0; i < kMsgSize; ++i) { + uint32_t num_bytes = 1; + EXPECT_EQ(MOJO_RESULT_OK, + client_socket_send_handle->WriteData( + &kTestMsg[i], &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); + // Flush the 1 byte write. + base::RunLoop().RunUntilIdle(); + } + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketWithMockSocketTest, PartialStreamSocketWrite) { + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle = + std::move(receive_pipe.consumer_handle); + mojo::ScopedDataPipeProducerHandle client_socket_send_handle = + std::move(send_pipe.producer_handle); + + mojom::TCPConnectedSocketPtr client_socket; + const char kTestMsg[] = "abcdefghij"; + const size_t kMsgSize = arraysize(kTestMsg) - 1; + const int kNumIterations = 3; + std::vector<net::MockRead> reads; + std::vector<net::MockWrite> writes; + int sequence_number = 0; + net::IoMode mode = GetParam(); + for (int j = 0; j < kNumIterations; ++j) { + for (size_t i = 0; i < kMsgSize; ++i) { + reads.push_back(net::MockRead(mode, &kTestMsg[i], 1, sequence_number++)); + } + if (j == kNumIterations - 1) { + reads.push_back(net::MockRead(mode, net::OK, sequence_number++)); + } + for (size_t i = 0; i < kMsgSize; ++i) { + writes.push_back( + net::MockWrite(mode, &kTestMsg[i], 1, sequence_number++)); + } + } + net::StaticSocketDataProvider data_provider(reads.data(), reads.size(), + writes.data(), writes.size()); + data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK)); + auto mock_socket = std::make_unique<net::MockTCPClientSocket>( + net::AddressList(), nullptr /*netlog*/, &data_provider); + + CreateConnectedSocketWithMockSocket(mojo::MakeRequest(&client_socket), + std::move(receive_pipe.producer_handle), + std::move(send_pipe.consumer_handle), + std::move(mock_socket)); + + // Loop kNumIterations times to test that writes can follow reads, and reads + // can follow writes. + for (int j = 0; j < kNumIterations; ++j) { + // Reading kMsgSize should coalesce the 1-byte mock reads. + EXPECT_EQ(kTestMsg, Read(&client_socket_receive_handle, kMsgSize)); + // Write twice, each with kMsgSize/2 bytes which is bigger than the 1-byte + // MockWrite(). This is to exercise that StreamSocket::Write() can do + // partial write. + uint32_t first_write_size = kMsgSize / 2; + EXPECT_EQ(MOJO_RESULT_OK, + client_socket_send_handle->WriteData( + &kTestMsg[0], &first_write_size, MOJO_WRITE_DATA_FLAG_NONE)); + // Flush the kMsgSize/2 byte write. + base::RunLoop().RunUntilIdle(); + uint32_t second_write_size = kMsgSize - first_write_size; + EXPECT_EQ(MOJO_RESULT_OK, + client_socket_send_handle->WriteData(&kTestMsg[first_write_size], + &second_write_size, + MOJO_WRITE_DATA_FLAG_NONE)); + // Flush the kMsgSize/2 byte write. + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketWithMockSocketTest, ReadError) { + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle = + std::move(receive_pipe.consumer_handle); + mojo::ScopedDataPipeProducerHandle client_socket_send_handle = + std::move(send_pipe.producer_handle); + + mojom::TCPConnectedSocketPtr client_socket; + net::IoMode mode = GetParam(); + net::MockRead reads[] = {net::MockRead(mode, net::ERR_FAILED)}; + const char kTestMsg[] = "hello!"; + net::MockWrite writes[] = { + net::MockWrite(mode, kTestMsg, arraysize(kTestMsg) - 1, 0)}; + net::StaticSocketDataProvider data_provider(reads, arraysize(reads), writes, + arraysize(writes)); + data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK)); + auto mock_socket = std::make_unique<net::MockTCPClientSocket>( + net::AddressList(), nullptr /*netlog*/, &data_provider); + + CreateConnectedSocketWithMockSocket(mojo::MakeRequest(&client_socket), + std::move(receive_pipe.producer_handle), + std::move(send_pipe.consumer_handle), + std::move(mock_socket)); + + EXPECT_EQ("", Read(&client_socket_receive_handle, 1)); + EXPECT_EQ(net::ERR_FAILED, observer()->WaitForReadError()); + // Writes can proceed even though there is a read error. + uint32_t num_bytes = arraysize(kTestMsg) - 1; + EXPECT_EQ(MOJO_RESULT_OK, + client_socket_send_handle->WriteData(&kTestMsg, &num_bytes, + MOJO_WRITE_DATA_FLAG_NONE)); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +TEST_P(TCPSocketWithMockSocketTest, WriteError) { + mojo::DataPipe send_pipe; + mojo::DataPipe receive_pipe; + mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle = + std::move(receive_pipe.consumer_handle); + mojo::ScopedDataPipeProducerHandle client_socket_send_handle = + std::move(send_pipe.producer_handle); + + mojom::TCPConnectedSocketPtr client_socket; + net::IoMode mode = GetParam(); + const char kTestMsg[] = "hello!"; + net::MockRead reads[] = { + net::MockRead(mode, kTestMsg, arraysize(kTestMsg) - 1, 0), + net::MockRead(mode, net::OK)}; + net::MockWrite writes[] = {net::MockWrite(mode, net::ERR_FAILED)}; + net::StaticSocketDataProvider data_provider(reads, arraysize(reads), writes, + arraysize(writes)); + data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK)); + auto mock_socket = std::make_unique<net::MockTCPClientSocket>( + net::AddressList(), nullptr /*netlog*/, &data_provider); + + CreateConnectedSocketWithMockSocket(mojo::MakeRequest(&client_socket), + std::move(receive_pipe.producer_handle), + std::move(send_pipe.consumer_handle), + std::move(mock_socket)); + + uint32_t num_bytes = arraysize(kTestMsg) - 1; + EXPECT_EQ(MOJO_RESULT_OK, + client_socket_send_handle->WriteData(&kTestMsg, &num_bytes, + MOJO_WRITE_DATA_FLAG_NONE)); + EXPECT_EQ(net::ERR_FAILED, observer()->WaitForWriteError()); + // Reads can proceed even though there is a read error. + EXPECT_EQ(kTestMsg, Read(&client_socket_receive_handle, arraysize(kTestMsg))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(data_provider.AllReadDataConsumed()); + EXPECT_TRUE(data_provider.AllWriteDataConsumed()); +} + +} // namespace network
diff --git a/services/network/udp_socket.cc b/services/network/udp_socket.cc index 4a19c98..e43690f 100644 --- a/services/network/udp_socket.cc +++ b/services/network/udp_socket.cc
@@ -137,22 +137,15 @@ UDPSocket::PendingSendRequest::~PendingSendRequest() {} -UDPSocket::UDPSocket(mojom::UDPSocketRequest request, - mojom::UDPSocketReceiverPtr receiver) - : is_bound_(false), +UDPSocket::UDPSocket(mojom::UDPSocketReceiverPtr receiver, net::NetLog* net_log) + : net_log_(net_log), + is_bound_(false), is_connected_(false), receiver_(std::move(receiver)), - remaining_recv_slots_(0), - binding_(this) { - binding_.Bind(std::move(request)); -} + remaining_recv_slots_(0) {} UDPSocket::~UDPSocket() {} -void UDPSocket::set_connection_error_handler(base::OnceClosure handler) { - binding_.set_connection_error_handler(std::move(handler)); -} - void UDPSocket::Connect(const net::IPEndPoint& remote_addr, mojom::UDPSocketOptionsPtr options, ConnectCallback callback) { @@ -295,7 +288,7 @@ const { return std::make_unique<SocketWrapperImpl>( net::DatagramSocket::RANDOM_BIND, base::BindRepeating(&base::RandInt), - nullptr, net::NetLogSource()); + net_log_, net::NetLogSource()); } bool UDPSocket::IsConnectedOrBound() const {
diff --git a/services/network/udp_socket.h b/services/network/udp_socket.h index 8f5ae10..b5b627a 100644 --- a/services/network/udp_socket.h +++ b/services/network/udp_socket.h
@@ -13,8 +13,6 @@ #include "base/containers/span.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/interface_request.h" #include "net/base/address_family.h" #include "net/base/completion_callback.h" #include "net/base/ip_endpoint.h" @@ -26,6 +24,7 @@ namespace net { class IOBuffer; class IOBufferWithSize; +class NetLog; } // namespace net namespace network { @@ -70,13 +69,9 @@ const net::CompletionCallback& callback) = 0; }; - UDPSocket(mojom::UDPSocketRequest request, - mojom::UDPSocketReceiverPtr receiver); + UDPSocket(mojom::UDPSocketReceiverPtr receiver, net::NetLog* net_log); ~UDPSocket() override; - // Sets connection error handler. - void set_connection_error_handler(base::OnceClosure handler); - // UDPSocket implementation. void Connect(const net::IPEndPoint& remote_addr, mojom::UDPSocketOptionsPtr options, @@ -137,6 +132,8 @@ void OnRecvFromCompleted(uint32_t buffer_size, int net_result); void OnSendToCompleted(int net_result); + net::NetLog* net_log_; + // Whether a Bind() has been successfully executed. bool is_bound_; @@ -166,8 +163,6 @@ base::circular_deque<std::unique_ptr<PendingSendRequest>> pending_send_requests_; - mojo::Binding<mojom::UDPSocket> binding_; - DISALLOW_COPY_AND_ASSIGN(UDPSocket); };
diff --git a/services/network/udp_socket_factory.cc b/services/network/udp_socket_factory.cc deleted file mode 100644 index 54ac3e4..0000000 --- a/services/network/udp_socket_factory.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/network/udp_socket_factory.h" - -#include <utility> - -#include "base/memory/ptr_util.h" -#include "base/optional.h" -#include "net/base/net_errors.h" -#include "services/network/udp_socket.h" - -namespace network { - -UDPSocketFactory::UDPSocketFactory() {} - -UDPSocketFactory::~UDPSocketFactory() {} - -void UDPSocketFactory::CreateUDPSocket(mojom::UDPSocketRequest request, - mojom::UDPSocketReceiverPtr receiver) { - auto socket = - std::make_unique<UDPSocket>(std::move(request), std::move(receiver)); - // base::Unretained is safe as the destruction of |this| will also destroy - // |udp_sockets_| which owns this socket. - socket->set_connection_error_handler( - base::BindOnce(&UDPSocketFactory::OnPipeBroken, base::Unretained(this), - base::Unretained(socket.get()))); - udp_sockets_.push_back(std::move(socket)); -} - -void UDPSocketFactory::OnPipeBroken(UDPSocket* socket) { - udp_sockets_.erase( - std::find_if(udp_sockets_.begin(), udp_sockets_.end(), - [socket](const std::unique_ptr<network::UDPSocket>& ptr) { - return ptr.get() == socket; - })); -} - -} // namespace network
diff --git a/services/network/udp_socket_factory.h b/services/network/udp_socket_factory.h deleted file mode 100644 index 58d47e8..0000000 --- a/services/network/udp_socket_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_ -#define SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_ - -#include <memory> -#include <vector> - -#include "base/component_export.h" -#include "base/macros.h" -#include "services/network/public/mojom/udp_socket.mojom.h" - -namespace network { - -class UDPSocket; - -// Helper class that handles UDPSocketRequest. It takes care of destroying the -// UDPSocket implementation instances when mojo pipes are broken. -class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocketFactory { - public: - UDPSocketFactory(); - virtual ~UDPSocketFactory(); - - void CreateUDPSocket(mojom::UDPSocketRequest request, - mojom::UDPSocketReceiverPtr receiver); - - protected: - // Handles connection errors. This is virtual for testing. - virtual void OnPipeBroken(UDPSocket* client); - - private: - std::vector<std::unique_ptr<UDPSocket>> udp_sockets_; - - DISALLOW_COPY_AND_ASSIGN(UDPSocketFactory); -}; - -} // namespace network - -#endif // SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_
diff --git a/services/network/udp_socket_factory_unittest.cc b/services/network/udp_socket_factory_unittest.cc deleted file mode 100644 index 2076e6e5..0000000 --- a/services/network/udp_socket_factory_unittest.cc +++ /dev/null
@@ -1,63 +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 <utility> - -#include "services/network/udp_socket_factory.h" - -#include "base/logging.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "net/base/net_errors.h" -#include "services/network/public/mojom/udp_socket.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace network { - -class UDPSocketFactoryTest : public testing::Test { - public: - UDPSocketFactoryTest() {} - ~UDPSocketFactoryTest() override {} - - private: - base::test::ScopedTaskEnvironment scoped_task_environment_; - - DISALLOW_COPY_AND_ASSIGN(UDPSocketFactoryTest); -}; - -class TestUDPSocketFactory : public UDPSocketFactory { - public: - TestUDPSocketFactory() {} - ~TestUDPSocketFactory() override {} - - void WaitUntilPipeBroken() { run_loop_.Run(); } - - private: - // UDPSocketFactory implementation: - void OnPipeBroken(UDPSocket* client) override { - UDPSocketFactory::OnPipeBroken(client); - run_loop_.Quit(); - } - - base::RunLoop run_loop_; -}; -// Tests that when client end of the pipe is closed, the factory implementation -// cleans up the server side of the pipe. -TEST_F(UDPSocketFactoryTest, ConnectionError) { - TestUDPSocketFactory factory; - - mojom::UDPSocketReceiverPtr receiver_interface_ptr; - mojom::UDPSocketPtr socket_ptr; - - factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); - - // Close client side of the pipe. - socket_ptr.reset(); - - factory.WaitUntilPipeBroken(); -} - -} // namespace network
diff --git a/services/network/udp_socket_unittest.cc b/services/network/udp_socket_unittest.cc index 0fa16b75..7ca3552 100644 --- a/services/network/udp_socket_unittest.cc +++ b/services/network/udp_socket_unittest.cc
@@ -21,6 +21,7 @@ #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/public/mojom/udp_socket.mojom.h" +#include "services/network/socket_factory.h" #include "services/network/udp_socket_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -199,8 +200,9 @@ }; TEST_F(UDPSocketTest, Settings) { + SocketFactory factory(nullptr /*net_log*/); mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), nullptr); net::IPEndPoint server_addr; net::IPEndPoint any_port(GetLocalHostWithAnyPort()); @@ -217,8 +219,9 @@ // Tests that Send() is used after Bind() is not supported. Send() should only // be used after Connect(). TEST_F(UDPSocketTest, TestSendWithBind) { + SocketFactory factory(nullptr /*net_log*/); mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); @@ -235,6 +238,7 @@ // Tests that when SendTo() is used after Connect() is not supported. SendTo() // should only be used after Bind(). TEST_F(UDPSocketTest, TestSendToWithConnect) { + SocketFactory factory(nullptr /*net_log*/); // Create a server socket to listen for incoming datagrams. test::UDPSocketReceiverImpl receiver; mojo::Binding<mojom::UDPSocketReceiver> receiver_binding(&receiver); @@ -242,8 +246,8 @@ receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), - std::move(receiver_interface_ptr)); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket), + std::move(receiver_interface_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -251,7 +255,7 @@ // Create a client socket to send datagrams. mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&client_socket), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); ASSERT_EQ(net::OK, @@ -265,8 +269,9 @@ // Tests that the sequence of calling Bind()/Connect() and setters is // important. TEST_F(UDPSocketTest, TestUnexpectedSequences) { + SocketFactory factory(nullptr /*net_log*/); mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), nullptr); test::UDPSocketTestHelper helper(&socket_ptr); net::IPEndPoint local_addr(GetLocalHostWithAnyPort()); @@ -291,7 +296,9 @@ // ERR_IO_PENDING, udp_socket.cc doesn't free the send buffer. TEST_F(UDPSocketTest, TestBufferValid) { mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + UDPSocket impl(nullptr /*receiver*/, nullptr /*net_log*/); + mojo::Binding<mojom::UDPSocket> binding(&impl); + binding.Bind(mojo::MakeRequest(&socket_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); @@ -329,7 +336,9 @@ // ERR_INSUFFICIENT_RESOURCES is returned appropriately. TEST_F(UDPSocketTest, TestInsufficientResources) { mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + UDPSocket impl(nullptr /*receiver*/, nullptr /*net_log*/); + mojo::Binding<mojom::UDPSocket> binding(&impl); + binding.Bind(mojo::MakeRequest(&socket_ptr)); const size_t kQueueSize = UDPSocket::kMaxPendingSendRequests; @@ -376,8 +385,9 @@ receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), - std::move(receiver_interface_ptr)); + UDPSocket impl(std::move(receiver_interface_ptr), nullptr /*net_log*/); + mojo::Binding<mojom::UDPSocket> binding(&impl); + binding.Bind(mojo::MakeRequest(&server_socket)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -392,6 +402,7 @@ } TEST_F(UDPSocketTest, TestReadSend) { + SocketFactory factory(nullptr /*net_log*/); // Create a server socket to listen for incoming datagrams. test::UDPSocketReceiverImpl receiver; mojo::Binding<mojom::UDPSocketReceiver> receiver_binding(&receiver); @@ -399,8 +410,8 @@ receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), - std::move(receiver_interface_ptr)); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket), + std::move(receiver_interface_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -408,7 +419,7 @@ // Create a client socket to send datagrams. mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&client_socket), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); ASSERT_EQ(net::OK, @@ -461,9 +472,10 @@ } TEST_F(UDPSocketTest, TestReadSendTo) { + SocketFactory factory(nullptr /*net_log*/); // Create a server socket to send data. mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -476,8 +488,8 @@ receiver_binding.Bind(mojo::MakeRequest(&client_receiver_ptr)); mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), - std::move(client_receiver_ptr)); + factory.CreateUDPSocket(mojo::MakeRequest(&client_socket), + std::move(client_receiver_ptr)); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); ASSERT_EQ(net::OK, @@ -527,6 +539,7 @@ } TEST_F(UDPSocketTest, TestReceiveMoreWithBufferSize) { + SocketFactory factory(nullptr /*net_log*/); // Create a server socket to listen for incoming datagrams. test::UDPSocketReceiverImpl receiver; mojo::Binding<mojom::UDPSocketReceiver> receiver_binding(&receiver); @@ -534,8 +547,8 @@ receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), - std::move(receiver_interface_ptr)); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket), + std::move(receiver_interface_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -543,7 +556,7 @@ // Create a client socket to send datagrams. mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&client_socket), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); ASSERT_EQ(net::OK, @@ -578,8 +591,9 @@ // Make sure passing an invalid net::IPEndPoint will be detected by // serialization/deserialization in mojo. TEST_F(UDPSocketTest, TestSendToInvalidAddress) { + SocketFactory factory(nullptr /*net_log*/); mojom::UDPSocketPtr server_socket; - UDPSocket impl(mojo::MakeRequest(&server_socket), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); @@ -611,8 +625,9 @@ receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); + UDPSocket impl(std::move(receiver_interface_ptr), nullptr /*net_log*/); + mojo::Binding<mojom::UDPSocket> binding(&impl); + binding.Bind(mojo::MakeRequest(&socket_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); @@ -640,6 +655,7 @@ #define MAYBE_JoinMulticastGroup JoinMulticastGroup #endif // defined(OS_ANDROID) TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) { + SocketFactory factory(nullptr /*net_log*/); const char kGroup[] = "237.132.100.17"; net::IPAddress group_ip; @@ -649,7 +665,8 @@ test::UDPSocketReceiverImpl receiver; mojo::Binding<mojom::UDPSocketReceiver> receiver_binding(&receiver); receiver_binding.Bind(mojo::MakeRequest(&receiver_ptr)); - UDPSocket impl(mojo::MakeRequest(&socket_ptr), std::move(receiver_ptr)); + factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), + std::move(receiver_ptr)); test::UDPSocketTestHelper helper(&socket_ptr); @@ -685,7 +702,7 @@ // Create a second socket to send a packet to multicast group. mojom::UDPSocketPtr second_socket_ptr; - UDPSocket second_socket_impl(mojo::MakeRequest(&second_socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&second_socket_ptr), nullptr); test::UDPSocketTestHelper second_socket_helper(&second_socket_ptr); net::IPEndPoint second_socket_address(bind_ip_address, 0); ASSERT_EQ(net::OK, @@ -716,15 +733,16 @@ } TEST_F(UDPSocketTest, ErrorHappensDuringSocketOptionsConfiguration) { + SocketFactory factory(nullptr /*net_log*/); mojom::UDPSocketPtr server_socket_ptr; - UDPSocket server_impl(mojo::MakeRequest(&server_socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&server_socket_ptr), nullptr); test::UDPSocketTestHelper server_helper(&server_socket_ptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); ASSERT_EQ(net::OK, server_helper.BindSync(server_addr, nullptr, &server_addr)); mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); + factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr), nullptr); test::UDPSocketTestHelper helper(&socket_ptr); // Invalid options.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 36b5bfd..7828aebe 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -47,7 +47,6 @@ response->head.headers = request->response_headers(); request->GetCharset(&response->head.charset); response->head.content_length = request->GetExpectedContentSize(); - response->head.was_cached = request->was_cached(); request->GetMimeType(&response->head.mime_type); net::HttpResponseInfo response_info = request->response_info(); response->head.was_fetched_via_spdy = response_info.was_fetched_via_spdy; @@ -689,6 +688,7 @@ URLLoaderCompletionStatus status; status.error_code = error_code; + status.exists_in_cache = url_request_->response_info().was_cached; status.completion_time = base::TimeTicks::Now(); status.encoded_data_length = url_request_->GetTotalReceivedBytes(); status.encoded_body_length = url_request_->GetRawBodyBytes();
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc index ca2faee..45bb3ad 100644 --- a/services/network/url_loader_factory.cc +++ b/services/network/url_loader_factory.cc
@@ -89,6 +89,7 @@ if (client) { URLLoaderCompletionStatus status; status.error_code = net::ERR_INSUFFICIENT_RESOURCES; + status.exists_in_cache = false; status.completion_time = base::TimeTicks::Now(); client->OnComplete(status); }
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc index dfd08fa..26ed309f 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc
@@ -43,15 +43,6 @@ if (!base::win::GetLoadedModulesSnapshot(::GetCurrentProcess(), &modules)) return maps; - auto process_metrics = base::ProcessMetrics::CreateCurrentProcessMetrics(); - uint64_t pss_bytes = 0; - bool res = process_metrics->GetProportionalSetSizeBytes(&pss_bytes); - if (res) { - mojom::VmRegionPtr region = mojom::VmRegion::New(); - region->byte_stats_proportional_resident = pss_bytes; - maps.push_back(std::move(region)); - } - // Query the base address for each module, and attach it to the dump. for (size_t i = 0; i < modules.size(); ++i) { wchar_t module_name[MAX_PATH];
diff --git a/services/ui/ws/display_manager.cc b/services/ui/ws/display_manager.cc index 9503df2..e580213 100644 --- a/services/ui/ws/display_manager.cc +++ b/services/ui/ws/display_manager.cc
@@ -37,11 +37,11 @@ namespace ui { namespace ws { -DisplayManager::DisplayManager(WindowServer* window_server) +DisplayManager::DisplayManager(WindowServer* window_server, bool is_hosting_viz) : window_server_(window_server), cursor_location_manager_(std::make_unique<CursorLocationManager>()) { #if defined(OS_CHROMEOS) - if (window_server->is_hosting_viz()) { + if (is_hosting_viz) { // TODO: http://crbug.com/701468 fix function key preferences and sticky // keys. ui::EventRewriterChromeOS::Delegate* delegate = nullptr;
diff --git a/services/ui/ws/display_manager.h b/services/ui/ws/display_manager.h index abb91d9..00b48484 100644 --- a/services/ui/ws/display_manager.h +++ b/services/ui/ws/display_manager.h
@@ -34,7 +34,7 @@ // those that do. class DisplayManager : public display::ScreenManagerDelegate { public: - explicit DisplayManager(WindowServer* window_server); + DisplayManager(WindowServer* window_server, bool is_hosting_viz); ~DisplayManager() override; // Called once WindowServer::display_creation_config() has been determined.
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index fdf7d39..bf92ce8d 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -135,7 +135,7 @@ WindowServer::WindowServer(WindowServerDelegate* delegate, bool should_host_viz) : delegate_(delegate), next_client_id_(kWindowServerClientId + 1), - display_manager_(std::make_unique<DisplayManager>(this)), + display_manager_(std::make_unique<DisplayManager>(this, should_host_viz)), current_operation_(nullptr), in_destructor_(false), next_wm_change_id_(0),
diff --git a/storage/browser/fileapi/file_system_url.cc b/storage/browser/fileapi/file_system_url.cc index 7074e203..184c475 100644 --- a/storage/browser/fileapi/file_system_url.cc +++ b/storage/browser/fileapi/file_system_url.cc
@@ -26,6 +26,12 @@ FileSystemURL::FileSystemURL(const FileSystemURL& other) = default; +FileSystemURL::FileSystemURL(FileSystemURL&& other) noexcept = default; + +FileSystemURL& FileSystemURL::operator=(FileSystemURL&& rhs) = default; + +FileSystemURL& FileSystemURL::operator=(const FileSystemURL& rhs) = default; + // static FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { return FileSystemURL(url);
diff --git a/storage/browser/fileapi/file_system_url.h b/storage/browser/fileapi/file_system_url.h index b9e8a99..eaedb23 100644 --- a/storage/browser/fileapi/file_system_url.h +++ b/storage/browser/fileapi/file_system_url.h
@@ -79,8 +79,17 @@ public: FileSystemURL(); FileSystemURL(const FileSystemURL& other); + // Constructs FileSystemURL with the contents of |other|, which is left in + // valid but unspecified state. + FileSystemURL(FileSystemURL&& other) noexcept; ~FileSystemURL(); + // Replaces the contents with those of |rhs|, which is left in valid but + // unspecified state. + FileSystemURL& operator=(FileSystemURL&& rhs); + + FileSystemURL& operator=(const FileSystemURL& rhs); + // Methods for creating FileSystemURL without attempting to crack them. // Should be used only in tests. static FileSystemURL CreateForTest(const GURL& url);
diff --git a/storage/browser/fileapi/file_system_url_unittest.cc b/storage/browser/fileapi/file_system_url_unittest.cc index ef13cf10..71e0488c3 100644 --- a/storage/browser/fileapi/file_system_url_unittest.cc +++ b/storage/browser/fileapi/file_system_url_unittest.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <utility> + #include "base/files/file_path.h" #include "base/macros.h" #include "storage/common/fileapi/file_system_types.h" @@ -221,4 +223,29 @@ EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_bar_perm_a)); } +TEST(FileSystemURLTest, ValidAfterMoves) { + // Move constructor. + { + FileSystemURL original = FileSystemURL::CreateForTest( + GURL("http://foo"), kFileSystemTypeTemporary, + base::FilePath::FromUTF8Unsafe("a")); + EXPECT_TRUE(original.is_valid()); + FileSystemURL new_url(std::move(original)); + EXPECT_TRUE(new_url.is_valid()); + EXPECT_TRUE(original.is_valid()); + } + + // Move operator. + { + FileSystemURL original = FileSystemURL::CreateForTest( + GURL("http://foo"), kFileSystemTypeTemporary, + base::FilePath::FromUTF8Unsafe("a")); + EXPECT_TRUE(original.is_valid()); + FileSystemURL new_url; + new_url = std::move(std::move(original)); + EXPECT_TRUE(new_url.is_valid()); + EXPECT_TRUE(original.is_valid()); + } +} + } // namespace content
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestApplication.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestApplication.java index 80ca421..c5f29d48 100644 --- a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestApplication.java +++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestApplication.java
@@ -18,7 +18,7 @@ protected void attachBaseContext(Context base) { super.attachBaseContext(base); assert getBaseContext() != null; - if (BuildConfig.isMultidexEnabled()) { + if (BuildConfig.IS_MULTIDEX_ENABLED) { ChromiumMultiDexInstaller.install(this); } }
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 4848b5e1..780198e 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -44276,7 +44276,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44308,7 +44308,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44338,7 +44338,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44370,7 +44370,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44400,7 +44400,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44432,7 +44432,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44462,7 +44462,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44494,7 +44494,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44524,7 +44524,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44556,7 +44556,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44586,7 +44586,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44618,7 +44618,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44648,7 +44648,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44680,7 +44680,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44710,7 +44710,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44742,7 +44742,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44772,7 +44772,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44804,7 +44804,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44834,7 +44834,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44866,7 +44866,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44896,7 +44896,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44928,7 +44928,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44958,7 +44958,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -44990,7 +44990,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45020,7 +45020,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45052,7 +45052,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45082,7 +45082,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45114,7 +45114,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45144,7 +45144,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45176,7 +45176,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45206,7 +45206,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45238,7 +45238,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45268,7 +45268,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45300,7 +45300,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45330,7 +45330,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45362,7 +45362,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45392,7 +45392,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45422,7 +45422,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45454,7 +45454,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45484,7 +45484,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45516,7 +45516,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45546,7 +45546,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45578,7 +45578,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45608,7 +45608,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45640,7 +45640,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45670,7 +45670,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45702,7 +45702,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45732,7 +45732,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45764,7 +45764,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45794,7 +45794,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45824,7 +45824,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45856,7 +45856,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45886,7 +45886,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45918,7 +45918,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45948,7 +45948,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -45980,7 +45980,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46010,7 +46010,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46042,7 +46042,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46072,7 +46072,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46104,7 +46104,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46134,7 +46134,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46166,7 +46166,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46196,7 +46196,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46228,7 +46228,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46258,7 +46258,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46290,7 +46290,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46320,7 +46320,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46352,7 +46352,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46382,7 +46382,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46414,7 +46414,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46444,7 +46444,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46476,7 +46476,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46506,7 +46506,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46538,7 +46538,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46568,7 +46568,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46600,7 +46600,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46630,7 +46630,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46662,7 +46662,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46692,7 +46692,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46724,7 +46724,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46754,7 +46754,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46786,7 +46786,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46816,7 +46816,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46848,7 +46848,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46878,7 +46878,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46910,7 +46910,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46940,7 +46940,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -46972,7 +46972,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47002,7 +47002,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47034,7 +47034,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47064,7 +47064,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47096,7 +47096,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47126,7 +47126,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47158,7 +47158,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47188,7 +47188,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47218,7 +47218,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47250,7 +47250,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47282,7 +47282,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47312,7 +47312,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47342,7 +47342,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47374,7 +47374,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47406,7 +47406,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47436,7 +47436,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47468,7 +47468,7 @@ { "gpu": "8086:1616", "id": "build180-b4", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47498,7 +47498,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47530,7 +47530,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47560,7 +47560,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47592,7 +47592,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47622,7 +47622,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47654,7 +47654,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47684,7 +47684,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47716,7 +47716,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47746,7 +47746,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47778,7 +47778,7 @@ { "gpu": "8086:1616", "id": "build118-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47808,7 +47808,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47838,7 +47838,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47870,7 +47870,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47902,7 +47902,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47932,7 +47932,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47964,7 +47964,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -47994,7 +47994,7 @@ { "gpu": "8086:1616", "id": "build117-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48024,7 +48024,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48056,7 +48056,7 @@ { "gpu": "8086:1616", "id": "build119-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48086,7 +48086,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48118,7 +48118,7 @@ { "gpu": "8086:1616", "id": "build120-b1", - "os": "Windows-10-16299.248", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48152,7 +48152,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48184,7 +48184,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48214,7 +48214,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48246,7 +48246,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48276,7 +48276,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48308,7 +48308,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48338,7 +48338,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48370,7 +48370,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48400,7 +48400,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48432,7 +48432,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48462,7 +48462,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48494,7 +48494,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48524,7 +48524,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48556,7 +48556,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48586,7 +48586,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48618,7 +48618,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48648,7 +48648,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48680,7 +48680,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48710,7 +48710,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48742,7 +48742,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48772,7 +48772,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48804,7 +48804,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48834,7 +48834,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48866,7 +48866,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48896,7 +48896,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48928,7 +48928,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48958,7 +48958,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -48990,7 +48990,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49020,7 +49020,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49052,7 +49052,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49082,7 +49082,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49114,7 +49114,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49144,7 +49144,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49176,7 +49176,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49206,7 +49206,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49238,7 +49238,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49268,7 +49268,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49298,7 +49298,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49330,7 +49330,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49351,7 +49351,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49381,7 +49381,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49413,7 +49413,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49443,7 +49443,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49475,7 +49475,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49505,7 +49505,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49537,7 +49537,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49567,7 +49567,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49599,7 +49599,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49629,7 +49629,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49661,7 +49661,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49691,7 +49691,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49721,7 +49721,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49753,7 +49753,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49783,7 +49783,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49815,7 +49815,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49845,7 +49845,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49877,7 +49877,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49907,7 +49907,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49939,7 +49939,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -49969,7 +49969,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50001,7 +50001,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50031,7 +50031,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50063,7 +50063,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50093,7 +50093,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50125,7 +50125,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50155,7 +50155,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50187,7 +50187,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50217,7 +50217,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50249,7 +50249,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50279,7 +50279,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50311,7 +50311,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50341,7 +50341,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50373,7 +50373,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50403,7 +50403,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50435,7 +50435,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50465,7 +50465,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50497,7 +50497,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50527,7 +50527,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50559,7 +50559,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50589,7 +50589,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50621,7 +50621,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50651,7 +50651,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50683,7 +50683,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50713,7 +50713,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50745,7 +50745,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50775,7 +50775,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50807,7 +50807,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50837,7 +50837,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50869,7 +50869,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50899,7 +50899,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50931,7 +50931,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50961,7 +50961,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -50993,7 +50993,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51023,7 +51023,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51055,7 +51055,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51085,7 +51085,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51115,7 +51115,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51147,7 +51147,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51179,7 +51179,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51209,7 +51209,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51239,7 +51239,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51271,7 +51271,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51303,7 +51303,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51333,7 +51333,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51365,7 +51365,7 @@ { "gpu": "102b:0534", "id": "build136-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51395,7 +51395,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51427,7 +51427,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51457,7 +51457,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51489,7 +51489,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51519,7 +51519,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51551,7 +51551,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51581,7 +51581,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51613,7 +51613,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51643,7 +51643,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51675,7 +51675,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51705,7 +51705,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51735,7 +51735,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51767,7 +51767,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51799,7 +51799,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51829,7 +51829,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51861,7 +51861,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51891,7 +51891,7 @@ { "gpu": "102b:0534", "id": "build132-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51912,7 +51912,7 @@ { "gpu": "102b:0534", "id": "build135-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51942,7 +51942,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -51974,7 +51974,7 @@ { "gpu": "102b:0534", "id": "build134-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -52004,7 +52004,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ], @@ -52036,7 +52036,7 @@ { "gpu": "102b:0534", "id": "build133-m1", - "os": "Windows-10-10240", + "os": "Windows-10", "pool": "Chrome-perf" } ],
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index e2053c3..60e7b70 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -60,8 +60,6 @@ -WebViewTests/WebViewTest.ClearPersistentCookies/1 -WebViewTests/WebViewTest.ClearSessionCookies/0 -WebViewTests/WebViewTest.ClearSessionCookies/1 --WebViewTests/WebViewTest.DownloadCookieIsolation/0 --WebViewTests/WebViewTest.DownloadCookieIsolation/1 -WebViewTests/WebViewTest.DownloadCookieIsolation_CrossSession/0 -WebViewTests/WebViewTest.DownloadCookieIsolation_CrossSession/1 -WebViewTests/WebViewTest.StoragePersistence/0
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c5b71e7..706b970 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2108,6 +2108,25 @@ ] } ], + "NavigationMojoResponse": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "win" + ], + "experiments": [ + { + "name": "NavigationMojoResponse", + "enable_features": [ + "NavigationMojoResponse" + ] + } + ] + } + ], "NetAdaptiveProxyConnectionTimeout": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations index ad6dfa693..52ec24d1 100644 --- a/third_party/WebKit/LayoutTests/MSANExpectations +++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -36,8 +36,11 @@ crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Timeout ] crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-merged-nodes.js [ Timeout ] crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe.js [ Timeout ] crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js [ Timeout ] crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers.js [ Timeout ] +crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe.js [ Timeout ] crbug.com/667560 [ Linux ] http/tests/devtools/startup/console/console-format-startup.js [ Timeout Pass ] crbug.com/751906 [ Linux ] http/tests/devtools/console/console-correct-suggestions.js [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 4313256..846f5b2d 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -82445,6 +82445,90 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin.html", @@ -107941,6 +108025,11 @@ {} ] ], + "css/css-font-loading/idlharness.https-expected.txt": [ + [ + {} + ] + ], "css/css-fonts/OWNERS": [ [ {} @@ -124026,6 +124115,11 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/flex-basis-expected.txt": [ + [ + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/font-style-expected.txt": [ [ {} @@ -131306,6 +131400,41 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin-ref.html": [ [ {} @@ -149961,6 +150090,11 @@ {} ] ], + "interfaces/css-font-loading.idl": [ + [ + {} + ] + ], "interfaces/css-typed-om.idl": [ [ {} @@ -178897,6 +179031,12 @@ {} ] ], + "css/css-font-loading/idlharness.https.html": [ + [ + "/css/css-font-loading/idlharness.https.html", + {} + ] + ], "css/css-fonts/calc-in-font-variation-settings.html": [ [ "/css/css-fonts/calc-in-font-variation-settings.html", @@ -182845,6 +182985,12 @@ {} ] ], + "css/css-typed-om/stylevalue-subclasses/cssKeywordValue-value.html": [ + [ + "/css/css-typed-om/stylevalue-subclasses/cssKeywordValue-value.html", + {} + ] + ], "css/css-typed-om/stylevalue-subclasses/cssKeywordValue.html": [ [ "/css/css-typed-om/stylevalue-subclasses/cssKeywordValue.html", @@ -183403,6 +183549,48 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/flex-basis.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-basis.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-direction.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-direction.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-flow.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-flow.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-grow.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-grow.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-shrink.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-shrink.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-wrap.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex-wrap.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/flex.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/flex.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/float.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/float.html", @@ -277130,6 +277318,14 @@ "ad355c3d5220c1b938182241a8e8abe030ace699", "testharness" ], + "css/css-font-loading/idlharness.https-expected.txt": [ + "2711c37911c9d0547173d0ebb4215745017d43fb", + "support" + ], + "css/css-font-loading/idlharness.https.html": [ + "00399ffcb0ff8000e79ab4aeefdb90cabdb0fd4d", + "testharness" + ], "css/css-fonts/OWNERS": [ "18aa6fb5e88093cc3ddbe9b22d2b008a3c3a6477", "support" @@ -303023,11 +303219,15 @@ "testharness" ], "css/css-typed-om/stylevalue-subclasses/cssKeywordValue-invalid.html": [ - "63600cc74e62ecbaf98bf786de17362764ec947e", + "b20c888c2ecc5dc7f87a2fa7114141a86a63598d", + "testharness" + ], + "css/css-typed-om/stylevalue-subclasses/cssKeywordValue-value.html": [ + "55f20761cbbe3dc27c718621d3e4d57eae041e8a", "testharness" ], "css/css-typed-om/stylevalue-subclasses/cssKeywordValue.html": [ - "236520d8ac6199066d1e082b9860f2381ff61be6", + "d2ab852da57ca24e9675fd670a0bf3546063fa69", "testharness" ], "css/css-typed-om/stylevalue-subclasses/cssMatrixComponent.tentative.html": [ @@ -303422,6 +303622,38 @@ "d7424e7fb7c27cfa31fb0e40ee9045129ed96c03", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/flex-basis-expected.txt": [ + "d68571702188ba3bf28ea394e618f7ff0d8fe5d8", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-basis.html": [ + "87f3eed7306a43a312c95fd8b525fcd5d3e167cc", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-direction.html": [ + "a27187c16080fe2daacd1c0a99657773a2b8c2d0", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-flow.html": [ + "7cc29cb60930ad904ac6a90ed6fad5673b84ed81", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-grow.html": [ + "7882699c2414306523501d253115198622a18cc9", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-shrink.html": [ + "8025e8905f2547ebdad41159c1872e6c9d868458", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex-wrap.html": [ + "1f57e275b4c9d195e9f82ead41410f0954fdff86", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/flex.html": [ + "3bfc9c981b2131ed480f5d0bc2b90f76743e2b28", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/float.html": [ "1dfca0045c2b57f36d5165139087301ffe54c63a", "testharness" @@ -316306,6 +316538,62 @@ "8a2dd4d9df36e30405b98391b37c34bf7a9626e8", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html": [ + "62aefeb96bc6427e444c5f8f9d3ca4e5db75cbde", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html": [ + "22e5a0e050237ea6f8842951f65045e468fa1e13", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html": [ + "2908851b1673cb8e365b268fbd5efb8884e8fb8a", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html": [ + "66dc81e18b0e14b28599da60495eee949559e6e4", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html": [ + "b63a415a9d01779265c284b5e0ab96126f81be29", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html": [ + "204143162d5bb402c034ab9137a2c7d0c7d9d773", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html": [ + "09ee47b125984cd56db2bd55c69c70ec8fffc574", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html": [ + "b6dffeba5007d6031be409bfc369bb4d7cb212de", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html": [ + "cc8960069089b49e2483d56d741ead5fd6d1dc0f", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html": [ + "6b198e21da4b54d421b4085de81886ba1aa7e3e7", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html": [ + "adfe9c5e9d5a9beefae3028c568605150f4c4b0b", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html": [ + "8bc4299480079e93164f1a4010b3d65617f96984", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html": [ + "37d8c2c639214cb8532426a7cae297246d95dc1b", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html": [ + "c287e46a8dd6df43f302f8049c8d03afde211494", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin-ref.html": [ "d69196dab17976f19490ad2df62117f0317ecb32", "support" @@ -346102,6 +346390,10 @@ "0d74ef8e7681fddddfb786b75075a1dd0ddb9147", "support" ], + "interfaces/css-font-loading.idl": [ + "a0d53cc4e88f38cce9fd45759963e5da9a6f3dc3", + "support" + ], "interfaces/css-typed-om.idl": [ "3c918afebfb20266dd4003e71a008ed19c448fbc", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html new file mode 100644 index 0000000..447dd28 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html
@@ -0,0 +1,33 @@ +<html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> + +// When the response for the HTML file contains "Accept-CH" in the response +// headers, then the browser should not attach the specified client hints in +// the HTTP request headers if the response was delivered by an insecure HTTP +// server. Test this functionality by fetching an XHR from this page hosted on +// an insecure HTTP server. The response headers for this page include +// "Accept-CH: device-memory, dpr, viewport-width". +// +// echo_client_hints_received.py includes "device-memory-received", +// "dpr-received" and "viewport-width-received" in the response headers +// depending on the set of client hints it receives in the request headers. + + promise_test(t => { + return fetch("/client-hints/echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser does not include client hints in the headers + // when fetching the XHR from an insecure HTTP server. + assert_false(r.headers.has("device-memory-received")); + assert_false(r.headers.has("dpr-received")); + assert_false(r.headers.has("viewport-width-received")); + }); +}, "Accept-CH header test"); + +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html.headers b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html.headers new file mode 100644 index 0000000..38f4f33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.http.html.headers
@@ -0,0 +1 @@ +Accept-CH: device-memory, dpr, viewport-width \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html deleted file mode 100644 index c0f0581..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html +++ /dev/null
@@ -1,30 +0,0 @@ -<html> -<body> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> - -<script> - -// If the response for the HTML file contains "Accept-CH: device-memory" in -// the response headers, then the browser should attach device-memory client -// hint in the HTTP request headers. Test this functionality by fetching an -// XHR from this page. The response headers for this page include -// "Accept-CH: device-memory". -// -// echo_device_memory_header_received.py includes "device-memory-received" in -// the response headers only if the request included "device-memory" in the -// headers. - - promise_test(t => { - return fetch("/client-hints/echo_device_memory_header_received.py").then(r => { - assert_equals(r.status, 200) - // Verify that the browser included "device-memory" in the headers when - // fetching the XHR. - assert_true(r.headers.has("device-memory-received")); - }); -}, "Accept-CH header test"); - -</script> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html.headers b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html.headers deleted file mode 100644 index 401e1af..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.https.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Accept-CH: device-memory \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html new file mode 100644 index 0000000..6826326 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html
@@ -0,0 +1,32 @@ +<html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> + +// If the response for the HTML file contains "Accept-CH" in the response +// headers, then the browser should attach the specified client hints in the +// HTTP request headers. Test this functionality by fetching an +// XHR from this page. The response headers for this page include +// "Accept-CH: device-memory, dpr, viewport-width". +// +// echo_client_hints_received.py includes "device-memory-received", +// "dpr-received" and "viewport-width-received" in the response headers +// depending on the set of client hints it receives in the request headers. + + promise_test(t => { + return fetch("https://{{domains[]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py", {"mode": "no-cors"}).then(r => { + assert_equals(r.status, 200) + // Verify that the browser includes client hints in the headers when + // fetching the XHR. + assert_true(r.headers.has("device-memory-received"), "device-memory-received"); + assert_true(r.headers.has("dpr-received"), "dpr-received"); + assert_true(r.headers.has("viewport-width-received"), "viewport-width-received"); + }); +}, "Accept-CH header test"); + +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html.headers b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html.headers new file mode 100644 index 0000000..38f4f33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html.headers
@@ -0,0 +1 @@ +Accept-CH: device-memory, dpr, viewport-width \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_client_hints_received.py b/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_client_hints_received.py new file mode 100644 index 0000000..a787fed --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_client_hints_received.py
@@ -0,0 +1,12 @@ +def main(request, response): + """ + Simple handler that sets a response header based on if device-memory + request header was received or not. + """ + + if "device-memory" in request.headers: + response.headers.set("device-memory-received", "true") + if "dpr" in request.headers: + response.headers.set("dpr-received", "true") + if "viewport-width" in request.headers: + response.headers.set("viewport-width-received", "true") \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_device_memory_header_received.py b/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_device_memory_header_received.py deleted file mode 100644 index 0ab4368..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/echo_device_memory_header_received.py +++ /dev/null
@@ -1,8 +0,0 @@ -def main(request, response): - """ - Simple handler that sets a response header based on if device-memory - request header was received or not. - """ - - if "device-memory" in request.headers: - response.headers.set("device-memory-received", "true") \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt new file mode 100644 index 0000000..61a0d30 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt
@@ -0,0 +1,78 @@ +frame (anonymous) - didStartProvisionalLoadForFrame +frame (anonymous) - didCommitLoadForFrame +main frame - didReceiveTitle: Font Loading API IDL tests +main frame - didFinishDocumentLoadForFrame +main frame - didHandleOnloadEventsForFrame +main frame - didFinishLoadForFrame +This is a testharness.js-based test. +PASS Test IDL implementation of CSS Font Loading +PASS Document interface: attribute fonts +PASS Unscopable handled correctly for fonts property on Document +PASS Document interface: document must inherit property "fonts" with the proper type +PASS WorkerGlobalScope interface: existence and properties of interface object +PASS FontFace interface: existence and properties of interface object +PASS FontFace interface object length +PASS FontFace interface object name +PASS FontFace interface: existence and properties of interface prototype object +PASS FontFace interface: existence and properties of interface prototype object's "constructor" property +PASS FontFace interface: existence and properties of interface prototype object's @@unscopables property +PASS FontFace interface: attribute family +PASS Unscopable handled correctly for family property on FontFace +PASS FontFace interface: attribute style +PASS Unscopable handled correctly for style property on FontFace +PASS FontFace interface: attribute weight +PASS Unscopable handled correctly for weight property on FontFace +PASS FontFace interface: attribute stretch +PASS Unscopable handled correctly for stretch property on FontFace +PASS FontFace interface: attribute unicodeRange +PASS Unscopable handled correctly for unicodeRange property on FontFace +PASS FontFace interface: attribute variant +PASS Unscopable handled correctly for variant property on FontFace +PASS FontFace interface: attribute featureSettings +PASS Unscopable handled correctly for featureSettings property on FontFace +FAIL FontFace interface: attribute variationSettings assert_true: The prototype object must have a property "variationSettings" expected true got false +PASS Unscopable handled correctly for variationSettings property on FontFace +PASS FontFace interface: attribute display +PASS Unscopable handled correctly for display property on FontFace +PASS FontFace interface: attribute status +PASS Unscopable handled correctly for status property on FontFace +PASS FontFace interface: operation load() +PASS Unscopable handled correctly for load() on FontFace +PASS FontFace interface: attribute loaded +PASS Unscopable handled correctly for loaded property on FontFace +PASS FontFaceSetLoadEvent interface: existence and properties of interface object +PASS FontFaceSetLoadEvent interface object length +PASS FontFaceSetLoadEvent interface object name +PASS FontFaceSetLoadEvent interface: existence and properties of interface prototype object +PASS FontFaceSetLoadEvent interface: existence and properties of interface prototype object's "constructor" property +PASS FontFaceSetLoadEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS FontFaceSetLoadEvent interface: attribute fontfaces +PASS Unscopable handled correctly for fontfaces property on FontFaceSetLoadEvent +FAIL FontFaceSet interface: existence and properties of interface object assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface object length assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface object name assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface: existence and properties of interface prototype object assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +FAIL FontFaceSet interface: operation add(FontFace) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for add(FontFace) on FontFaceSet +FAIL FontFaceSet interface: operation delete(FontFace) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for delete(FontFace) on FontFaceSet +FAIL FontFaceSet interface: operation clear() assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for clear() on FontFaceSet +FAIL FontFaceSet interface: attribute onloading assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for onloading property on FontFaceSet +FAIL FontFaceSet interface: attribute onloadingdone assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for onloadingdone property on FontFaceSet +FAIL FontFaceSet interface: attribute onloadingerror assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for onloadingerror property on FontFaceSet +FAIL FontFaceSet interface: operation load(CSSOMString, CSSOMString) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for load(CSSOMString, CSSOMString) on FontFaceSet +FAIL FontFaceSet interface: operation check(CSSOMString, CSSOMString) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for check(CSSOMString, CSSOMString) on FontFaceSet +FAIL FontFaceSet interface: attribute ready assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for ready property on FontFaceSet +FAIL FontFaceSet interface: attribute status assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Unscopable handled correctly for status property on FontFaceSet +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https.html new file mode 100644 index 0000000..037e62f9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<title>Font Loading API IDL tests</title> +<link rel="help" href="https://drafts.csswg.org/css-font-loading/#fontfacesetloadevent"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> +<script src="/resources/idlharness.js"></script> +<script> +"use strict"; + +function doTest([dom, cssfontloading]) { + const idl_array = new IdlArray(); + idl_array.add_untested_idls(dom); + idl_array.add_untested_idls("[Exposed=Worker] interface WorkerGlobalScope : EventTarget { };"); + idl_array.add_objects({Document: ["document"]}); + idl_array.add_idls(cssfontloading); + idl_array.test(); +} + +function fetchText(url) { + return fetch(url).then((response) => response.text()); +} + +promise_test(() => { + return Promise.all([ + "/interfaces/dom.idl", + "/interfaces/css-font-loading.idl", + ].map(fetchText)).then(doTest); +}, "Test IDL implementation of CSS Font Loading"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html new file mode 100644 index 0000000..f37a73d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsla() syntax accepts comma-less expressions (and comments as separators), percentage alpha and omitting of alpha component - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: hsla(120, 75%, 50%, 0.2); } + #p2 { background-color: hsla(120, 75%, 50%, 0.4); } + #p3 { background-color: hsla(120, 75%, 50%, 0.6); } + #p4 { background-color: hsl(120, 75%, 50%); } + #p5 { background-color: hsl(120, 75%, 50%); } + #p6 { background-color: hsl(120, 75%, 50%); } + #p7 { background-color: hsl(120, 75%, 50%); } + #p8 { background-color: hsl(120, 75%, 50%); } + #p9 { background-color: hsl(120, 75%, 50%); } + #p10 { background-color: hsl(120, 75%, 50%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html new file mode 100644 index 0000000..2b8c7d31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-001.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsla() syntax accepts comma-less expressions (and comments as separators), percentage alpha and omitting of alpha component - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hsl-notation" /> + <meta name="assert" content="hsla() should accept comma-less expressions (and comments as separators), percentage alpha and omitting of alpha component." /> + <link rel="match" href="background-color-hsl-001-ref.html" /> + <style type="text/css"> + #p1 { background-color: hsla(120.0, 75%, 50%, 20%); } + #p2 { background-color: hsla(120, 75%, 50%, 0.4); } + #p3 { background-color: hsla(120 75% 50% / 60%); } + #p4 { background-color: hsla(120.0 75% 50% / 1.0); } + #p5 { background-color: hsla(120/* comment */75%/* comment */50%/1.0); } + #p6 { background-color: hsla(120,/* comment */75%,/* comment */50%,100%); } + #p7 { background-color: hsla(120.0, 75%, 50%); } + #p8 { background-color: hsla(120 75% 50%); } + #p9 { background-color: hsla(120/* comment */75%/* comment */50%); } + #p10 { background-color: hsla(120/* comment */,75%,/* comment */50%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html new file mode 100644 index 0000000..90284b9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsl() syntax accepts comma-less expressions (and comments as separators) and alpha component (and percentage alpha) - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: hsla(120, 75%, 50%, 0.2); } + #p2 { background-color: hsla(120, 75%, 50%, 0.4); } + #p3 { background-color: hsla(120, 75%, 50%, 0.6); } + #p4 { background-color: hsla(120, 75%, 50%, 0.8); } + #p5 { background-color: hsla(120.0, 75%, 50%, 1.0); } + #p6 { background-color: hsla(120.0, 75%, 50%, 1.0); } + #p7 { background-color: hsla(120.0, 75%, 50%, 1.0); } + #p8 { background-color: hsla(120, 75%, 50%, 1.0); } + #p9 { background-color: hsla(120, 75%, 50%, 1.0); } + #p10 { background-color: hsla(120, 75%, 50%, 1.0); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html new file mode 100644 index 0000000..a1e9a012 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-002.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsl() syntax accepts comma-less expressions (and comments as separators) and alpha component (and percentage alpha) - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hsl-notation" /> + <meta name="assert" content="hsl() should accept comma-less expressions (and comments as separators) and alpha component (and percentage alpha)." /> + <link rel="match" href="background-color-hsl-002-ref.html" /> + <style type="text/css"> + #p1 { background-color: hsl(120, 75%, 50%, 0.2); } + #p2 { background-color: hsl(120, 75%, 50%, 40%); } + #p3 { background-color: hsl(120 75% 50% / 0.6); } + #p4 { background-color: hsl(120 75% 50% / 80%); } + #p5 { background-color: hsl(120/* comment */75%/* comment */50%/1.0); } + #p6 { background-color: hsl(120/* comment */75%/* comment */50%/100%); } + #p7 { background-color: hsl(120,/* comment */75%,/* comment */50%,1.0); } + #p8 { background-color: hsl(120,/* comment */75%,/* comment */50%,100%); } + #p9 { background-color: hsl(120/* comment */75%/* comment */50%); } + #p10 { background-color: hsl(120/* comment */,75%,/* comment */50%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html new file mode 100644 index 0000000..e0db417 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: support <angle> value for hsl()/hsla() hue component - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: hsla(120, 75%, 50%, 0.2); } + #p2 { background-color: hsla(120.0, 75%, 50%, 0.4); } + #p3 { background-color: hsla(1.2e2, 75%, 50%, 0.6); } + #p4 { background-color: hsla(120, 75%, 50%, 0.8); } + #p5 { background-color: hsla(120, 75%, 50%, 1.0); } + #p6 { background-color: hsl(240, 75%, 50%); } + #p7 { background-color: hsl(600.0, 75%, 50%); } + #p8 { background-color: hsl(9.6e2, 75%, 50%); } + #p9 { background-color: hsl(600, 75%, 50%); } + #p10 { background-color: hsl(240, 75%, 50%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html new file mode 100644 index 0000000..f9c256e17 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-003.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: support <angle> value for hsl()/hsla() hue component - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hsl-notation" /> + <meta name="assert" content="hsl()/hsla() hue component should support <angle> value." /> + <link rel="match" href="background-color-hsl-003-ref.html" /> + <style type="text/css"> + #p1 { background-color: hsla(120, 75%, 50%, 0.2); } + #p2 { background-color: hsla(120deg, 75%, 50%, 0.4); } + #p3 { background-color: hsla(133.33333333grad, 75%, 50%, 0.6); } + #p4 { background-color: hsla(2.0943951024rad, 75%, 50%, 0.8); } + #p5 { background-color: hsla(0.3333333333turn, 75%, 50%, 1.0); } + #p6 { background-color: hsl(240, 75%, 50%); } + #p7 { background-color: hsl(600deg, 75%, 50%); } + #p8 { background-color: hsl(1066.66666666grad, 75%, 50%); } + #p9 { background-color: hsl(10.4719755118rad, 75%, 50%); } + #p10 { background-color: hsl(2.6666666666turn, 75%, 50%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html new file mode 100644 index 0000000..f630740f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsla() and hsl() are aliases of each other - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: hsl(120, 75%, 50%); } + #p2 { background-color: hsl(120.0, 75%, 50%); } + #p3 { background-color: hsl(1.2e2, 75%, 50%); } + #p4 { background-color: hsl(1.2E2, 75%, 50%); } + #p5 { background-color: hsl(60, 75%, 50%); } + #p6 { background-color: hsla(120, 75%, 50%, 0.2); } + #p7 { background-color: hsla(120.0, 75%, 50%, 0.4); } + #p8 { background-color: hsla(1.2e2, 75%, 50%, 0.6); } + #p9 { background-color: hsla(1.2E2, 75%, 50%, 0.8); } + #p10 { background-color: hsla(60.0, 75%, 50%, 1.0); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html new file mode 100644 index 0000000..1cd6684 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-hsl-004.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: hsla() and hsl() are aliases of each other - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hsl-notation" /> + <meta name="assert" content="hsla() should have the identical grammar and behavior to hsl()." /> + <link rel="match" href="background-color-hsl-004-ref.html" /> + <style type="text/css"> + #p1 { background-color: hsla(120, 75%, 50%); } + #p2 { background-color: hsla(120.0, 75%, 50%); } + #p3 { background-color: hsla(1.2e2, 75%, 50%); } + #p4 { background-color: hsla(1.2E2, 75%, 50%); } + #p5 { background-color: hsla(60, 75%, 50%); } + #p6 { background-color: hsl(120, 75%, 50%, 0.2); } + #p7 { background-color: hsl(120.0, 75%, 50%, 0.4); } + #p8 { background-color: hsl(1.2e2, 75%, 50%, 0.6); } + #p9 { background-color: hsl(1.2E2, 75%, 50%, 0.8); } + #p10 { background-color: hsl(60.0, 75%, 50%, 1.0); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html new file mode 100644 index 0000000..b03f0a3f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgb() syntax accepts alpha component (and percentage alpha value), non-integer components and comma-less expressions (and comments as separators) - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: rgba(10%, 60%, 10%, 0.2); } + #p2 { background-color: rgba(10, 175, 10, 0.4); } + #p3 { background-color: rgba(10, 175, 10, 0.6); } + #p4 { background-color: rgba(10, 175, 10, 0.8); } + #p5 { background-color: rgba(10, 175, 10, 1.0); } + #p6 { background-color: rgba(10, 150, 50, 1.0); } + #p7 { background-color: rgba(10%, 60%, 10%, 1.0); } + #p8 { background-color: rgb(10, 100, 100); } + #p9 { background-color: rgb(10, 75, 125); } + #p10 { background-color: rgb(10, 50, 150); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html new file mode 100644 index 0000000..061eeac --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-001.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgb() syntax accepts alpha component (and percentage alpha value), non-integer components and comma-less expressions (and comments as separators) - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#rgb-functions" /> + <meta name="assert" content="rgb() should accept alpha component (and percentage alpha value), non-integer components and comma-less expressions (and comments as separators)." /> + <link rel="match" href="background-color-rgb-001-ref.html" /> + <style type="text/css"> + #p1 { background-color: rgb(10%, 60%, 10%, 20%); } + #p2 { background-color: rgb(10, 175, 10, 0.4); } + #p3 { background-color: rgb(10 175 10 / 60%); } + #p4 { background-color: rgb(10.0 175.0 10.0 / 0.8); } + #p5 { background-color: rgb(10/* comment */175/* comment */10/100%); } + #p6 { background-color: rgb(10,/* comment */150,/* comment */50); } + #p7 { background-color: rgb(10%, 60%, 10%); } + #p8 { background-color: rgb(10.0 100.0 100.0); } + #p9 { background-color: rgb(10/* comment */75/* comment */125); } + #p10 { background-color: rgb(10.0, 50.0, 150.0); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html new file mode 100644 index 0000000..be29c86c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgba() syntax accepts non-integer components, comma-less expressions (and comments as separators), percentage alpha and omitting of alpha component - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: rgba(10, 175, 10, 0.2); } + #p2 { background-color: rgba(10, 175, 10, 0.4); } + #p3 { background-color: rgba(10%, 75%, 10%, 0.6); } + #p4 { background-color: rgba(10, 175, 10, 0.8); } + #p5 { background-color: rgb(10, 175, 10); } + #p6 { background-color: rgb(10, 150, 50); } + #p7 { background-color: rgb(10, 125, 75); } + #p8 { background-color: rgb(10%, 45%, 45%); } + #p9 { background-color: rgb(10, 75, 125); } + #p10 { background-color: rgb(10, 50, 150); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html new file mode 100644 index 0000000..8919f0e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-002.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgba() syntax accepts non-integer components, comma-less expressions (and comments as separators), percentage alpha and omitting of alpha component - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#rgb-functions" /> + <meta name="assert" content="rgba() should accept non-integer components, comma-less expressions (and comments as separators), percentage alpha and omitting of alpha." /> + <link rel="match" href="background-color-rgb-002-ref.html" /> + <style type="text/css"> + #p1 { background-color: rgba(10.0, 175.0, 10.0, 0.2); } + #p2 { background-color: rgba(10, 175, 10, 40%); } + #p3 { background-color: rgba(10% 75% 10% / 0.6); } + #p4 { background-color: rgba(10 175 10 / 80%); } + #p5 { background-color: rgba(10/* comment */175/* comment */10/100%); } + #p6 { background-color: rgba(10,/* comment */150,/* comment */50); } + #p7 { background-color: rgba(10.0, 125.0, 75.0); } + #p8 { background-color: rgba(10%, 45%, 45%); } + #p9 { background-color: rgba(10/* comment */75/* comment */125); } + #p10 { background-color: rgba(10.0, 50.0, 150.0); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html new file mode 100644 index 0000000..70227ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003-ref.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgb() and rgba() are aliases of each other - ref</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <style type="text/css"> + #p1 { background-color: rgba(10, 175, 10, 0.2); } + #p2 { background-color: rgba(10, 175, 10, 0.4); } + #p3 { background-color: rgba(10, 175, 10, 0.6); } + #p4 { background-color: rgba(10%, 70%, 10%, 0.8); } + #p5 { background-color: rgba(10%, 70%, 10%, 1.0); } + #p6 { background-color: rgb(10, 150, 50); } + #p7 { background-color: rgb(10, 125, 75); } + #p8 { background-color: rgb(10%,40%, 40%); } + #p9 { background-color: rgb(10%, 45%, 50%); } + #p10 { background-color: rgb(10%, 50%, 60%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html new file mode 100644 index 0000000..6a22ba0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/color4/background-color-rgb-003.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>CSS-Color-4: rgb() and rgba() are aliases of each other - test</title> + <link rel="author" title="Jerry Shih" href="mailto:bignose1007@gmail.com" /> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/" /> + <link rel="help" href="https://drafts.csswg.org/css-color-4/#rgb-functions" /> + <meta name="assert" content="rgb() should have the identical grammar and behavior to rgba()." /> + <link rel="match" href="background-color-rgb-003-ref.html" /> + <style type="text/css"> + #p1 { background-color: rgb(10, 175, 10, 0.2); } + #p2 { background-color: rgb(10, 175, 10, 0.4); } + #p3 { background-color: rgb(10, 175, 10, 0.6); } + #p4 { background-color: rgb(10%, 70%, 10%, 0.8); } + #p5 { background-color: rgb(10%, 70%, 10%, 1.0); } + #p6 { background-color: rgba(10, 150, 50); } + #p7 { background-color: rgba(10, 125, 75); } + #p8 { background-color: rgba(10%,40%, 40%); } + #p9 { background-color: rgba(10%, 45%, 50%); } + #p10 { background-color: rgba(10%, 50%, 60%); } + </style> + </head> + <body> + <p id="p1">color</p> + <p id="p2">color</p> + <p id="p3">color</p> + <p id="p4">color</p> + <p id="p5">color</p> + <p id="p6">color</p> + <p id="p7">color</p> + <p id="p8">color</p> + <p id="p9">color</p> + <p id="p10">color</p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-font-loading.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-font-loading.idl new file mode 100644 index 0000000..5609101 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-font-loading.idl
@@ -0,0 +1,86 @@ +typedef (ArrayBuffer or ArrayBufferView) BinaryData; + +dictionary FontFaceDescriptors { + CSSOMString style = "normal"; + CSSOMString weight = "normal"; + CSSOMString stretch = "normal"; + CSSOMString unicodeRange = "U+0-10FFFF"; + CSSOMString variant = "normal"; + CSSOMString featureSettings = "normal"; + CSSOMString variationSettings = "normal"; + CSSOMString display = "auto"; +}; + +enum FontFaceLoadStatus { "unloaded", "loading", "loaded", "error" }; + +[Constructor(CSSOMString family, (CSSOMString or BinaryData) source, + optional FontFaceDescriptors descriptors), + Exposed=(Window,Worker)] +interface FontFace { + attribute CSSOMString family; + attribute CSSOMString style; + attribute CSSOMString weight; + attribute CSSOMString stretch; + attribute CSSOMString unicodeRange; + attribute CSSOMString variant; + attribute CSSOMString featureSettings; + attribute CSSOMString variationSettings; + attribute CSSOMString display; + + readonly attribute FontFaceLoadStatus status; + + Promise<FontFace> load(); + readonly attribute Promise<FontFace> loaded; +}; + +dictionary FontFaceSetLoadEventInit : EventInit { + sequence<FontFace> fontfaces = []; +}; + +[Constructor(CSSOMString type, optional FontFaceSetLoadEventInit eventInitDict), + Exposed=(Window,Worker)] +interface FontFaceSetLoadEvent : Event { + [SameObject] readonly attribute FrozenArray<FontFace> fontfaces; +}; + +enum FontFaceSetLoadStatus { "loading", "loaded" }; + +callback ForEachCallback = void (FontFace font, long index, FontFaceSet self); + +[Exposed=(Window,Worker), + Constructor(sequence<FontFace> initialFaces)] +interface FontFaceSet : EventTarget { + // FontFaceSet is Set-like! + setlike<FontFace>; + FontFaceSet add(FontFace font); + boolean delete(FontFace font); + void clear(); + + // events for when loading state changes + attribute EventHandler onloading; + attribute EventHandler onloadingdone; + attribute EventHandler onloadingerror; + + // check and start loads if appropriate + // and fulfill promise when all loads complete + Promise<sequence<FontFace>> load(CSSOMString font, optional CSSOMString text = " "); + + // return whether all fonts in the fontlist are loaded + // (does not initiate load if not available) + boolean check(CSSOMString font, optional CSSOMString text = " "); + + // async notification that font loading and layout operations are done + readonly attribute Promise<FontFaceSet> ready; + + // loading state, "loading" while one or more fonts loading, "loaded" otherwise + readonly attribute FontFaceSetLoadStatus status; +}; + +[Exposed=(Window,Worker), + NoInterfaceObject] +interface FontFaceSource { + readonly attribute FontFaceSet fonts; +}; + +Document implements FontFaceSource; +WorkerGlobalScope implements FontFaceSource;
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-merged-nodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-merged-nodes-expected.txt index f506e097..e183171 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-merged-nodes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-merged-nodes-expected.txt
@@ -2,5 +2,5 @@ Took heap snapshot Parsed snapshot SUCCESS: found leaking -SUCCESS: retaining path = [EventListener, InternalNode, HTMLDivElement, Window / file://, ] +SUCCESS: retaining path = [Detached EventListener, Detached InternalNode, Detached HTMLDivElement, Window / file://, ]
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt new file mode 100644 index 0000000..93e02dc --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt
@@ -0,0 +1,5 @@ +Test that all nodes from the detached DOM tree will be marked as detached. +Took heap snapshot +Parsed snapshot +SUCCESS: found 3 detached DIV elements +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js new file mode 100644 index 0000000..1c38b2b --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js
@@ -0,0 +1,23 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( + `Test that all nodes from the detached DOM tree will be marked as detached.`); + await session.evaluate(` + window.retaining_wrapper = document.createElement('div'); + var t = document.createElement('div'); + retaining_wrapper.appendChild(t); + t.appendChild(document.createElement('div')); + `); + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + var snapshot = await helper.takeHeapSnapshot(); + var divCount = 0; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.name() === 'Detached HTMLDivElement') + ++divCount; + } + if (divCount === 3) + testRunner.log('SUCCESS: found 3 detached DIV elements'); + else + return testRunner.fail('unexpected detached DIV count: ' + divCount); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe-expected.txt new file mode 100644 index 0000000..2ee17548 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe-expected.txt
@@ -0,0 +1,6 @@ +Test that a detached iframe will be marked as detached. +Took heap snapshot +Parsed snapshot +SUCCESS: found Leak +SUCCESS: detached iframe in retaining path +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe.js new file mode 100644 index 0000000..525087ae --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-iframe.js
@@ -0,0 +1,43 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( + `Test that a detached iframe will be marked as detached.`); + dp.Page.enable(); + session.evaluate(` + var frame = document.createElement('iframe'); + frame.src = 'data:text/html,<script>class Leak{}; var x = new Leak();<'+ + '/script>'; + document.body.appendChild(frame); + frame.addEventListener("load", function() { + var iframeWindow = this.contentWindow; + function retainingListener() { + // This is leaking the iframe. + console.log(iframeWindow); + } + document.body.addEventListener('click', retainingListener, true); + document.body.removeChild(frame); + }); + `); + await dp.Page.onceFrameStoppedLoading(); + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + var snapshot = await helper.takeHeapSnapshot(); + var node; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.className() === 'Leak') { + node = it.node; + break; + } + } + if (node) + testRunner.log('SUCCESS: found ' + node.name()); + else + return testRunner.fail('cannot find leaking node'); + + var retainers = helper.firstRetainingPath(node).map(node => node.name()); + + if (retainers.includes('Detached Window')) + testRunner.log('SUCCESS: detached iframe in retaining path'); + else + return testRunner.fail('no detached iframe in retaining path'); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe-expected.txt new file mode 100644 index 0000000..0cdd6fe --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe-expected.txt
@@ -0,0 +1,6 @@ +Test that an attached iframe is not marked as detached. +Took heap snapshot +Parsed snapshot +SUCCESS: found Leak +SUCCESS: no detached iframe in retaining path +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe.js new file mode 100644 index 0000000..d37947e --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe.js
@@ -0,0 +1,42 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( + `Test that an attached iframe is not marked as detached.`); + dp.Page.enable(); + session.evaluate(` + var frame = document.createElement('iframe'); + frame.src = 'data:text/html,<script>class Leak{}; var x = new Leak();<'+ + '/script>'; + document.body.appendChild(frame); + frame.addEventListener("load", function() { + var iframeWindow = this.contentWindow; + function retainingListener() { + // This is leaking the iframe. + console.log(iframeWindow); + } + document.body.addEventListener('click', retainingListener, true); + }); + `); + await dp.Page.onceFrameStoppedLoading(); + var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js'); + var helper = await Helper(testRunner, session); + var snapshot = await helper.takeHeapSnapshot(); + var node; + for (var it = snapshot._allNodes(); it.hasNext(); it.next()) { + if (it.node.className() === 'Leak') { + node = it.node; + break; + } + } + if (node) + testRunner.log('SUCCESS: found ' + node.name()); + else + return testRunner.fail('cannot find leaking node'); + + var retainers = helper.firstRetainingPath(node).map(node => node.name()); + + if (!retainers.includes('Detached Window')) + testRunner.log('SUCCESS: no detached iframe in retaining path'); + else + return testRunner.fail('unexpected detached iframe in retaining path'); + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text-control-intrinsic-widths-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text-control-intrinsic-widths-expected.txt index 951cef4..55c8c325 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text-control-intrinsic-widths-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text-control-intrinsic-widths-expected.txt
@@ -140,30 +140,30 @@ Andale Mono input -size=1 clientWidth=35 -size=2 clientWidth=40 -size=3 clientWidth=45 -size=4 clientWidth=50 -size=5 clientWidth=55 +size=1 clientWidth=8 +size=2 clientWidth=16 +size=3 clientWidth=24 +size=4 clientWidth=32 +size=5 clientWidth=40 size=10 clientWidth=80 -size=20 clientWidth=130 -size=50 clientWidth=280 -size=100 clientWidth=530 -size=500 clientWidth=2530 -size=1000 clientWidth=5030 +size=20 clientWidth=160 +size=50 clientWidth=400 +size=100 clientWidth=800 +size=500 clientWidth=4000 +size=1000 clientWidth=8000 textarea -cols=1 clientWidth=22 -cols=2 clientWidth=27 -cols=3 clientWidth=32 -cols=4 clientWidth=37 -cols=5 clientWidth=42 -cols=10 clientWidth=67 -cols=20 clientWidth=117 -cols=50 clientWidth=267 -cols=100 clientWidth=517 -cols=500 clientWidth=2517 -cols=1000 clientWidth=5017 +cols=1 clientWidth=25 +cols=2 clientWidth=33 +cols=3 clientWidth=41 +cols=4 clientWidth=49 +cols=5 clientWidth=57 +cols=10 clientWidth=97 +cols=20 clientWidth=177 +cols=50 clientWidth=417 +cols=100 clientWidth=817 +cols=500 clientWidth=4017 +cols=1000 clientWidth=8017 Arial input @@ -356,30 +356,30 @@ Webdings input -size=1 clientWidth=35 -size=2 clientWidth=40 -size=3 clientWidth=45 -size=4 clientWidth=50 -size=5 clientWidth=55 -size=10 clientWidth=80 -size=20 clientWidth=130 -size=50 clientWidth=280 -size=100 clientWidth=530 -size=500 clientWidth=2530 -size=1000 clientWidth=5030 +size=1 clientWidth=13 +size=2 clientWidth=26 +size=3 clientWidth=39 +size=4 clientWidth=52 +size=5 clientWidth=65 +size=10 clientWidth=130 +size=20 clientWidth=260 +size=50 clientWidth=650 +size=100 clientWidth=1300 +size=500 clientWidth=6500 +size=1000 clientWidth=13000 textarea -cols=1 clientWidth=22 -cols=2 clientWidth=27 -cols=3 clientWidth=32 -cols=4 clientWidth=37 -cols=5 clientWidth=42 -cols=10 clientWidth=67 -cols=20 clientWidth=117 -cols=50 clientWidth=267 -cols=100 clientWidth=517 -cols=500 clientWidth=2517 -cols=1000 clientWidth=5017 +cols=1 clientWidth=30 +cols=2 clientWidth=43 +cols=3 clientWidth=56 +cols=4 clientWidth=69 +cols=5 clientWidth=82 +cols=10 clientWidth=147 +cols=20 clientWidth=277 +cols=50 clientWidth=667 +cols=100 clientWidth=1317 +cols=500 clientWidth=6517 +cols=1000 clientWidth=13017 PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png index 2ea6c72..3cba6a5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png index 46a1f61..bc1a5dd 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index c796fc4..5ae5408 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/generic-system-ui-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/generic-system-ui-expected.txt index d1300a6..d38fe9d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/generic-system-ui-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/generic-system-ui-expected.txt
@@ -1,9 +1,9 @@ This text should use the system font. #system-ui: -"Arial" : 37 +"DejaVu Sans" : 37 This text should use the system font. #system-ui-20pt: -"Arial" : 37 +"DejaVu Sans" : 37
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png index 951b1ff..3700cba 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png index 9c3d202..44ba554 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png index 9c3d202..44ba554 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index b1797c3..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 4d8f4d9..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index a34a245..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 818104f8..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..3c308d6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..a29dedd3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png deleted file mode 100644 index 8f1bb8c7..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/webaudio/DynamicsCompressor/dynamicscompressor-clear-internal-state-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/webaudio/DynamicsCompressor/dynamicscompressor-clear-internal-state-expected.txt new file mode 100644 index 0000000..7ba628d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/webaudio/DynamicsCompressor/dynamicscompressor-clear-internal-state-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS # AUDIT TASK RUNNER STARTED. +PASS > [test] Validate Reduction Value of DynamicsCompressor after Disabling +FAIL X Math.abs(compressor.reduction) is not less than or equal to 0.048223. Got 5.246633529663086. assert_true: expected true got false +FAIL < [test] 1 out of 1 assertions were failed. assert_true: expected true got false +FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp index 091f93be..12d692f5 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp
@@ -5,7 +5,9 @@ #include "bindings/core/v8/V8EmbedderGraphBuilder.h" #include "bindings/core/v8/ActiveScriptWrappable.h" +#include "bindings/core/v8/V8GCController.h" #include "bindings/core/v8/V8Node.h" +#include "core/dom/Document.h" #include "platform/bindings/DOMWrapperMap.h" #include "platform/bindings/ScriptWrappable.h" #include "platform/bindings/ScriptWrappableVisitor.h" @@ -26,8 +28,70 @@ void V8EmbedderGraphBuilder::BuildEmbedderGraph() { isolate_->VisitHandlesWithClassIds(this); - VisitPendingActivities(); +// At this point we collected ScriptWrappables in three groups: +// attached, detached, and unknown. +#if DCHECK_IS_ON() + for (const WorklistItem& item : worklist_) { + DCHECK_EQ(DomTreeState::kAttached, item.node->GetDomTreeState()); + } + for (const WorklistItem& item : detached_worklist_) { + DCHECK_EQ(DomTreeState::kDetached, item.node->GetDomTreeState()); + } + for (const WorklistItem& item : unknown_worklist_) { + DCHECK_EQ(DomTreeState::kUnknown, item.node->GetDomTreeState()); + } +#endif + // We need to propagate attached/detached information to ScriptWrappables + // with the unknown state. The information propagates from a parent to + // a child as follows: + // - if the parent is attached, then the child is considered attached. + // - if the parent is detached and the child is unknown, then the child is + // considered detached. + // - if the parent is unknown, then the state of the child does not change. + // + // We need to organize DOM traversal in three stages to ensure correct + // propagation: + // 1) Traverse from the attached nodes. All nodes discovered in this stage + // will be marked as kAttached. + // 2) Traverse from the detached nodes. All nodes discovered in this stage + // will be marked as kDetached if they are not already marked as kAttached. + // 3) Traverse from the unknown nodes. This is needed only for edge recording. + // Stage 1: find transitive closure of the attached nodes. VisitTransitiveClosure(); + // Stage 2: find transitive closure of the detached nodes. + while (!detached_worklist_.empty()) { + auto item = detached_worklist_.back(); + detached_worklist_.pop_back(); + PushToWorklist(item); + } + VisitTransitiveClosure(); + // Stage 3: find transitive closure of the unknown nodes. + // Nodes reachable only via pending activities are treated as unknown. + VisitPendingActivities(); + while (!unknown_worklist_.empty()) { + auto item = unknown_worklist_.back(); + unknown_worklist_.pop_back(); + PushToWorklist(item); + } + VisitTransitiveClosure(); + DCHECK(worklist_.empty()); + DCHECK(detached_worklist_.empty()); + DCHECK(unknown_worklist_.empty()); +} + +V8EmbedderGraphBuilder::DomTreeState +V8EmbedderGraphBuilder::DomTreeStateFromWrapper( + uint16_t class_id, + v8::Local<v8::Object> v8_value) { + if (class_id != WrapperTypeInfo::kNodeClassId) + return DomTreeState::kUnknown; + Node* node = V8Node::ToImpl(v8_value); + Node* root = V8GCController::OpaqueRootForGC(isolate_, node); + if (root->isConnected() && + !node->GetDocument().MasterDocument().IsContextDestroyed()) { + return DomTreeState::kAttached; + } + return DomTreeState::kDetached; } void V8EmbedderGraphBuilder::VisitPersistentHandle( @@ -39,13 +103,25 @@ v8::Local<v8::Object> v8_value = v8::Local<v8::Object>::New( isolate_, v8::Persistent<v8::Object>::Cast(*value)); ScriptWrappable* traceable = ToScriptWrappable(v8_value); - if (traceable) { - Graph::Node* wrapper = GraphNode(v8_value); - Graph::Node* graph_node = - GraphNode(traceable, traceable->NameInHeapSnapshot(), wrapper); - // Visit traceable members. This will also add traceable => v8_value edge. - ParentScope parent(this, graph_node); - traceable->TraceWrappers(this); + if (!traceable) + return; + Graph::Node* wrapper = GraphNode(v8_value); + DomTreeState dom_tree_state = DomTreeStateFromWrapper(class_id, v8_value); + EmbedderNode* graph_node = GraphNode( + traceable, traceable->NameInHeapSnapshot(), wrapper, dom_tree_state); + const TraceWrapperDescriptor& wrapper_descriptor = + WrapperDescriptorFor<ScriptWrappable>(traceable); + WorklistItem item = ToWorklistItem(graph_node, wrapper_descriptor); + switch (graph_node->GetDomTreeState()) { + case DomTreeState::kAttached: + PushToWorklist(item); + break; + case DomTreeState::kDetached: + detached_worklist_.push_back(item); + break; + case DomTreeState::kUnknown: + unknown_worklist_.push_back(item); + break; } } @@ -64,13 +140,11 @@ // Add an edge from the current parent to this object. // Also push the object to the worklist in order to process its members. const void* traceable = wrapper_descriptor.base_object_payload; - Graph::Node* graph_node = GraphNode( - traceable, wrapper_descriptor.name_callback(traceable), nullptr); + EmbedderNode* graph_node = + GraphNode(traceable, wrapper_descriptor.name_callback(traceable), nullptr, + current_parent_->GetDomTreeState()); graph_->AddEdge(current_parent_, graph_node); - if (!visited_.Contains(traceable)) { - visited_.insert(traceable); - worklist_.push_back(ToWorklistItem(graph_node, wrapper_descriptor)); - } + PushToWorklist(ToWorklistItem(graph_node, wrapper_descriptor)); } void V8EmbedderGraphBuilder::Visit(DOMWrapperMap<ScriptWrappable>* wrapper_map, @@ -87,36 +161,48 @@ return graph_->V8Node(value); } -v8::EmbedderGraph::Node* V8EmbedderGraphBuilder::GraphNode( +V8EmbedderGraphBuilder::EmbedderNode* V8EmbedderGraphBuilder::GraphNode( Traceable traceable, const char* name, - v8::EmbedderGraph::Node* wrapper) const { + v8::EmbedderGraph::Node* wrapper, + DomTreeState dom_tree_state) const { auto iter = graph_node_.find(traceable); - if (iter != graph_node_.end()) + if (iter != graph_node_.end()) { + iter->value->UpdateDomTreeState(dom_tree_state); return iter->value; + } // Ownership of the new node is transferred to the graph_. // graph_node_.at(tracable) is valid for all BuildEmbedderGraph execution. - auto node = graph_->AddNode( - std::unique_ptr<Graph::Node>(new EmbedderNode(name, wrapper))); + auto raw_node = new EmbedderNode(name, wrapper, dom_tree_state); + EmbedderNode* node = static_cast<EmbedderNode*>( + graph_->AddNode(std::unique_ptr<Graph::Node>(raw_node))); graph_node_.insert(traceable, node); return node; } void V8EmbedderGraphBuilder::VisitPendingActivities() { // Ownership of the new node is transferred to the graph_. - Graph::Node* root = graph_->AddNode( - std::unique_ptr<Graph::Node>(new EmbedderRootNode("Pending activities"))); + EmbedderNode* root = + static_cast<EmbedderNode*>(graph_->AddNode(std::unique_ptr<Graph::Node>( + new EmbedderRootNode("Pending activities")))); ParentScope parent(this, root); ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate_, this); } V8EmbedderGraphBuilder::WorklistItem V8EmbedderGraphBuilder::ToWorklistItem( - Graph::Node* node, + EmbedderNode* node, const TraceWrapperDescriptor& wrapper_descriptor) const { return {node, wrapper_descriptor.base_object_payload, wrapper_descriptor.trace_wrappers_callback}; } +void V8EmbedderGraphBuilder::PushToWorklist(WorklistItem item) const { + if (!visited_.Contains(item.traceable)) { + visited_.insert(item.traceable); + worklist_.push_back(item); + } +} + void V8EmbedderGraphBuilder::VisitTransitiveClosure() { // Depth-first search. while (!worklist_.empty()) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h index f3ce7f54..eacc9a1 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h
@@ -34,24 +34,60 @@ const ScriptWrappable*) const final; private: + // Information about whether a node is attached to the main DOM tree + // or not. It is computed as follows: + // 1) A Document with IsContextDestroyed() = true is detached. + // 2) A Document with IsContextDestroyed() = false is attached. + // 3) A Node that is not connected to any Document is detached. + // 4) A Node that is connected to a detached Document is detached. + // 5) A Node that is connected to an attached Document is attached. + // 6) A ScriptWrappable that is reachable from an attached Node is + // attached. + // 7) A ScriptWrappable that is reachable from a detached Node is + // detached. + // 8) A ScriptWrappable that is not reachable from any Node is + // considered (conservatively) as attached. + // The unknown state applies to ScriptWrappables during graph + // traversal when we don't have reachability information yet. + enum class DomTreeState { kAttached, kDetached, kUnknown }; + + DomTreeState DomTreeStateFromWrapper(uint16_t class_id, + v8::Local<v8::Object> v8_value); + class EmbedderNode : public Graph::Node { public: - EmbedderNode(const char* name, Graph::Node* wrapper) - : name_(name), wrapper_(wrapper) {} + EmbedderNode(const char* name, + Graph::Node* wrapper, + DomTreeState dom_tree_state) + : name_(name), wrapper_(wrapper), dom_tree_state_(dom_tree_state) {} + DomTreeState GetDomTreeState() { return dom_tree_state_; } + void UpdateDomTreeState(DomTreeState parent_dom_tree_state) { + // If the child's state is unknown, then take the parent's state. + // If the parent is attached, then the child is also attached. + if (dom_tree_state_ == DomTreeState::kUnknown || + parent_dom_tree_state == DomTreeState::kAttached) { + dom_tree_state_ = parent_dom_tree_state; + } + } // Graph::Node overrides. const char* Name() override { return name_; } + const char* NamePrefix() override { + return dom_tree_state_ == DomTreeState::kDetached ? "Detached" : nullptr; + } size_t SizeInBytes() override { return 0; } Graph::Node* WrapperNode() override { return wrapper_; } private: const char* name_; Graph::Node* wrapper_; + DomTreeState dom_tree_state_; }; class EmbedderRootNode : public EmbedderNode { public: - explicit EmbedderRootNode(const char* name) : EmbedderNode(name, nullptr) {} + explicit EmbedderRootNode(const char* name) + : EmbedderNode(name, nullptr, DomTreeState::kUnknown) {} // Graph::Node override. bool IsRootNode() { return true; } }; @@ -60,7 +96,7 @@ STACK_ALLOCATED(); public: - ParentScope(V8EmbedderGraphBuilder* visitor, Graph::Node* parent) + ParentScope(V8EmbedderGraphBuilder* visitor, EmbedderNode* parent) : visitor_(visitor) { DCHECK_EQ(visitor->current_parent_, nullptr); visitor->current_parent_ = parent; @@ -72,28 +108,40 @@ }; struct WorklistItem { - Graph::Node* node; + EmbedderNode* node; Traceable traceable; TraceWrappersCallback trace_wrappers_callback; }; - WorklistItem ToWorklistItem(Graph::Node*, + WorklistItem ToWorklistItem(EmbedderNode*, const TraceWrapperDescriptor&) const; Graph::Node* GraphNode(const v8::Local<v8::Value>&) const; - Graph::Node* GraphNode(Traceable, - const char* name, - Graph::Node* wrapper) const; + EmbedderNode* GraphNode(Traceable, + const char* name, + Graph::Node* wrapper, + DomTreeState) const; void VisitPendingActivities(); void VisitTransitiveClosure(); + // Push the item to the default worklist if item.traceable was not + // already visited. + void PushToWorklist(WorklistItem) const; + v8::Isolate* isolate_; - Graph::Node* current_parent_; + EmbedderNode* current_parent_; mutable Graph* graph_; mutable HashSet<Traceable> visited_; - mutable HashMap<Traceable, Graph::Node*> graph_node_; + mutable HashMap<Traceable, EmbedderNode*> graph_node_; + // The default worklist that is used to visit transitive closure. mutable Deque<WorklistItem> worklist_; + // The worklist that collects detached Nodes during persistent handle + // iteration. + mutable Deque<WorklistItem> detached_worklist_; + // The worklist that collects ScriptWrappables with unknown information + // about attached/detached state during persistent handle iteration. + mutable Deque<WorklistItem> unknown_worklist_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index e5d77fd3..ba77372 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -7327,6 +7327,7 @@ // node_lists_ are traced in their corresponding NodeListsNodeData, keeping // them only alive for live nodes. Otherwise we would keep lists of dead // nodes alive that have not yet been invalidated. + visitor->TraceWrappers(dom_window_); visitor->TraceWrappers(imports_controller_); visitor->TraceWrappers(parser_); visitor->TraceWrappers(implementation_);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index f192aa9..26c27bc 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1566,7 +1566,7 @@ PendingSheetLayout pending_sheet_layout_; Member<LocalFrame> frame_; - Member<LocalDOMWindow> dom_window_; + TraceWrapperMember<LocalDOMWindow> dom_window_; TraceWrapperMember<HTMLImportsController> imports_controller_; // The document of creator browsing context for frame-less documents such as
diff --git a/third_party/WebKit/Source/core/editing/RenderedPosition.cpp b/third_party/WebKit/Source/core/editing/RenderedPosition.cpp index 98cf6da..35a8a66 100644 --- a/third_party/WebKit/Source/core/editing/RenderedPosition.cpp +++ b/third_party/WebKit/Source/core/editing/RenderedPosition.cpp
@@ -248,8 +248,21 @@ PrevLeafChild()->CaretRightmostOffset()); } +// Note: If the layout object has a scrolling contents layer, the selection +// will be relative to that. +static GraphicsLayer* GetGraphicsLayerBacking( + const LayoutObject& layout_object) { + const LayoutBoxModelObject& paint_invalidation_container = + layout_object.ContainerForPaintInvalidation(); + DCHECK(paint_invalidation_container.Layer()); + if (paint_invalidation_container.Layer()->GetCompositingState() == + kNotComposited) + return nullptr; + return paint_invalidation_container.Layer()->GraphicsLayerBacking( + &layout_object); +} + // Convert a local point into the coordinate system of backing coordinates. -// Also returns the backing layer if needed. static FloatPoint LocalToInvalidationBackingPoint( const LayoutPoint& local_point, const LayoutObject& layout_object) { @@ -270,26 +283,18 @@ PaintLayer::MapPointInPaintInvalidationContainerToBacking( paint_invalidation_container, container_point); - // Must not use the scrolling contents layer, so pass - // |paintInvalidationContainer|. - if (GraphicsLayer* graphics_layer = - paint_invalidation_container.Layer()->GraphicsLayerBacking( - &paint_invalidation_container)) + if (GraphicsLayer* graphics_layer = GetGraphicsLayerBacking(layout_object)) container_point.Move(-graphics_layer->OffsetFromLayoutObject()); - return container_point; -} + // Ensure the coordinates are in the scrolling contents space, if the object + // is a scroller. + if (paint_invalidation_container.UsesCompositedScrolling()) { + container_point.Move(paint_invalidation_container.Layer() + ->GetScrollableArea() + ->GetScrollOffset()); + } -static GraphicsLayer* GetGraphicsLayerBacking( - const LayoutObject& layout_object) { - const LayoutBoxModelObject& paint_invalidation_container = - layout_object.ContainerForPaintInvalidation(); - DCHECK(paint_invalidation_container.Layer()); - if (paint_invalidation_container.Layer()->GetCompositingState() == - kNotComposited) - return nullptr; - return paint_invalidation_container.Layer()->GraphicsLayerBacking( - &paint_invalidation_container); + return container_point; } std::pair<LayoutPoint, LayoutPoint> static GetLocalSelectionStartpoints(
diff --git a/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp b/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp index af07c01..e0137935 100644 --- a/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp +++ b/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp
@@ -10,37 +10,55 @@ #include "core/editing/testing/EditingTestBase.h" #include "core/frame/Settings.h" #include "core/html/forms/HTMLInputElement.h" +#include "core/layout/LayoutBox.h" +#include "core/paint/PaintLayerScrollableArea.h" #include "core/paint/compositing/CompositedSelection.h" +#include "platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { -class RenderedPositionTest : public EditingTestBase {}; +class RenderedPositionTest : public ::testing::WithParamInterface<bool>, + private ScopedRootLayerScrollingForTest, + public EditingTestBase { + public: + RenderedPositionTest() : ScopedRootLayerScrollingForTest(GetParam()) {} + void SetUp() override { + EditingTestBase::SetUp(); + GetPage().GetSettings().SetAcceleratedCompositingEnabled(true); + GetDocument().View()->SetParentVisible(true); + GetDocument().View()->SetSelfVisible(true); + LoadAhem(); + } -#if defined(OS_ANDROID) -#define MAYBE_ComputeCompositedSelection DISABLED_ComputeCompositedSelection -#else -#define MAYBE_ComputeCompositedSelection ComputeCompositedSelection -#endif -TEST_F(RenderedPositionTest, MAYBE_ComputeCompositedSelection) { - // Enable compositing. - GetPage().GetSettings().SetAcceleratedCompositingEnabled(true); - GetDocument().View()->SetParentVisible(true); - GetDocument().View()->SetSelfVisible(true); - GetDocument().View()->UpdateAllLifecyclePhases(); + void FocusAndSelectAll() { + HTMLInputElement* target = + ToHTMLInputElement(GetDocument().getElementById("target")); + DCHECK(target); + target->focus(); + Selection().SetSelection( + SelectionInDOMTree::Builder() + .SelectAllChildren(*target->InnerEditorElement()) + .Build(), + SetSelectionOptions::Builder().SetShouldShowHandle(true).Build()); + UpdateAllLifecyclePhases(); + } +}; - SetBodyContent( - "<input id=target width=20 value='test test test test test tes tes test'" - "style='width: 100px; height: 20px;'>"); - HTMLInputElement* target = - ToHTMLInputElement(GetDocument().getElementById("target")); - DCHECK(target); - target->focus(); - Selection().SetSelection( - SelectionInDOMTree::Builder() - .SelectAllChildren(*target->InnerEditorElement()) - .Build(), - SetSelectionOptions::Builder().SetShouldShowHandle(true).Build()); - UpdateAllLifecyclePhases(); +INSTANTIATE_TEST_CASE_P(All, RenderedPositionTest, ::testing::Bool()); + +TEST_P(RenderedPositionTest, ComputeCompositedSelection) { + SetBodyContent(R"HTML( + <!DOCTYPE html> + input { + font: 10px/1 Ahem; + padding: 0; + border: 0; + } + <input id=target width=20 value='test test test test test tes tes test' + style='width: 100px; height: 20px;'> + )HTML"); + + FocusAndSelectAll(); const CompositedSelection& composited_selection = RenderedPosition::ComputeCompositedSelection(Selection()); @@ -48,4 +66,115 @@ EXPECT_TRUE(composited_selection.end.hidden); } +TEST_P(RenderedPositionTest, PositionInScrollableRoot) { + SetBodyContent(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + height: 2000px; + width: 2000px; + } + input { + font: 10px/1 Ahem; + padding: 0; + border: 0; + width: 100px; + height: 20px; + position: absolute; + top: 900px; + left: 1000px; + } + </style> + <input id=target width=20 value='test test test test test tes tes test'> + )HTML"); + + FocusAndSelectAll(); + + ScrollableArea* root_scroller = GetDocument().View()->GetScrollableArea(); + root_scroller->SetScrollOffset(ScrollOffset(800, 500), kProgrammaticScroll); + ASSERT_EQ(ScrollOffset(800, 500), root_scroller->GetScrollOffset()); + + UpdateAllLifecyclePhases(); + + const CompositedSelection& composited_selection = + RenderedPosition::ComputeCompositedSelection(Selection()); + + // Top-left corner should be around (1000, 905) - 10px centered in 20px + // height. + EXPECT_EQ(FloatPoint(1000, 905), + composited_selection.start.edge_top_in_layer); + EXPECT_EQ(FloatPoint(1000, 915), + composited_selection.start.edge_bottom_in_layer); + EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer); + EXPECT_EQ(FloatPoint(1369, 915), + composited_selection.end.edge_bottom_in_layer); +} + +TEST_P(RenderedPositionTest, PositionInScroller) { + SetBodyContent(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + height: 2000px; + width: 2000px; + } + input { + font: 10px/1 Ahem; + padding: 0; + border: 0; + width: 100px; + height: 20px; + position: absolute; + top: 900px; + left: 1000px; + } + + #scroller { + width: 300px; + height: 300px; + position: absolute; + left: 300px; + top: 400px; + overflow: scroll; + border: 200px; + will-change: transform; + } + + #space { + width: 2000px; + height: 2000px; + } + </style> + <div id="scroller"> + <div id="space"></div> + <input id=target width=20 value='test test test test test tes tes test'> + </div> + )HTML"); + + FocusAndSelectAll(); + + Element* e = GetDocument().getElementById("scroller"); + PaintLayerScrollableArea* scroller = + ToLayoutBox(e->GetLayoutObject())->GetScrollableArea(); + scroller->SetScrollOffset(ScrollOffset(900, 800), kProgrammaticScroll); + ASSERT_EQ(ScrollOffset(900, 800), scroller->GetScrollOffset()); + + UpdateAllLifecyclePhases(); + + const CompositedSelection& composited_selection = + RenderedPosition::ComputeCompositedSelection(Selection()); + + // Top-left corner should be around (1000, 905) - 10px centered in 20px + // height. + EXPECT_EQ(FloatPoint(1000, 905), + composited_selection.start.edge_top_in_layer); + EXPECT_EQ(FloatPoint(1000, 915), + composited_selection.start.edge_bottom_in_layer); + EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer); + EXPECT_EQ(FloatPoint(1369, 915), + composited_selection.end.edge_bottom_in_layer); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp index 0aa806a..d232638 100644 --- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -6332,11 +6332,7 @@ blink::Node* layer_owner_node_for_start = V8Node::ToImplWithTypeCheck( v8::Isolate::GetCurrent(), expected_result.Get(0)); ASSERT_TRUE(layer_owner_node_for_start); - EXPECT_EQ(layer_owner_node_for_start->GetLayoutObject() - ->EnclosingLayer() - ->EnclosingLayerForPaintInvalidation() - ->GetCompositedLayerMapping() - ->MainGraphicsLayer() + EXPECT_EQ(GetExpectedLayerForSelection(layer_owner_node_for_start) ->PlatformLayer() ->Id(), select_start->layer_id); @@ -6351,11 +6347,7 @@ expected_result.Get(context, 5).ToLocalChecked()); ASSERT_TRUE(layer_owner_node_for_end); - EXPECT_EQ(layer_owner_node_for_end->GetLayoutObject() - ->EnclosingLayer() - ->EnclosingLayerForPaintInvalidation() - ->GetCompositedLayerMapping() - ->MainGraphicsLayer() + EXPECT_EQ(GetExpectedLayerForSelection(layer_owner_node_for_end) ->PlatformLayer() ->Id(), select_end->layer_id); @@ -6407,6 +6399,18 @@ RunTest(test_file); } + GraphicsLayer* GetExpectedLayerForSelection(blink::Node* node) const { + CompositedLayerMapping* clm = node->GetLayoutObject() + ->EnclosingLayer() + ->EnclosingLayerForPaintInvalidation() + ->GetCompositedLayerMapping(); + + // If the Node is a scroller, the selection will be relative to its + // scrolling contents layer. + return clm->ScrollingContentsLayer() ? clm->ScrollingContentsLayer() + : clm->MainGraphicsLayer(); + } + CompositedSelectionBoundsTestWebViewClient fake_selection_web_view_client_; CompositedSelectionBoundsTestLayerTreeView& fake_selection_layer_tree_view_; FrameTestHelpers::WebViewHelper web_view_helper_;
diff --git a/third_party/WebKit/Source/platform/OWNERS b/third_party/WebKit/Source/platform/OWNERS index 513ee139..d0f18a4 100644 --- a/third_party/WebKit/Source/platform/OWNERS +++ b/third_party/WebKit/Source/platform/OWNERS
@@ -21,8 +21,10 @@ vollick@chromium.org wangxianzhu@chromium.org -# In addition to the above, API_OWNERS are also adequate reviewers -# for adding / changing the status of a feature. +# Any API or core owner can also approve changes to runtime-enabled features. +# Please make sure to get a review from someone with expertise on the feature +# you are changing. per-file runtime_enabled_features.json5=file://third_party/WebKit/API_OWNERS +per-file runtime_enabled_features.json5=file://third_party/WebKit/Source/core/OWNERS # COMPONENT: Platform
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index 23630e9..1d81c18 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -835,6 +835,13 @@ if (caps_support.NeedsRunCaseSplitting()) { SplitUntilNextCaseChange(text_, &range_data->reshape_queue, current_queue_item, small_caps_behavior); + // Skip queue items generated by SplitUntilNextCaseChange that do not + // contribute to the shape result if the range_data restricts shaping to + // a substring. + if (range_data->start >= current_queue_item.start_index_ + + current_queue_item.num_characters_ || + range_data->end <= current_queue_item.start_index_) + continue; } } @@ -856,6 +863,7 @@ unsigned shape_end = std::min(range_data->end, current_queue_item.start_index_ + current_queue_item.num_characters_); + DCHECK_GT(shape_end, shape_start); CaseMappingHarfBuzzBufferFiller( case_map_intend, font_description.LocaleOrDefault(), range_data->buffer,
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp index 36c247a..d8173dd 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
@@ -391,6 +391,47 @@ EXPECT_EQ(result->Bounds(), composite_result->Bounds()); } +TEST_F(HarfBuzzShaperTest, RangeShapeSmallCaps) { + // Test passes if no assertion is hit of the ones below, but also the newly + // introduced one in HarfBuzzShaper::ShapeSegment: DCHECK_GT(shape_end, + // shape_start) is not hit. + FontDescription font_description; + font_description.SetVariantCaps(FontDescription::kSmallCaps); + font_description.SetComputedSize(12.0); + Font font(font_description); + font.Update(nullptr); + + // Shaping index 2 to 3 means that case splitting for small caps splits before + // character index 2 since the initial 'a' needs to be uppercased, but the + // space character does not need to be uppercased. This triggered + // crbug.com/817271. + String string(u"a aa"); + HarfBuzzShaper shaper(string.Characters16(), string.length()); + scoped_refptr<ShapeResult> result = + shaper.Shape(&font, TextDirection::kLtr, 2, 3); + EXPECT_EQ(1u, result->NumCharacters()); + + string = u"aa a"; + HarfBuzzShaper shaper_two(string.Characters16(), string.length()); + result = shaper_two.Shape(&font, TextDirection::kLtr, 3, 4); + EXPECT_EQ(1u, result->NumCharacters()); + + string = u"a aa"; + HarfBuzzShaper shaper_three(string.Characters16(), string.length()); + result = shaper_three.Shape(&font, TextDirection::kLtr, 1, 2); + EXPECT_EQ(1u, result->NumCharacters()); + + string = u"aa aa aa aa aa aa aa aa aa aa"; + HarfBuzzShaper shaper_four(string.Characters16(), string.length()); + result = shaper_four.Shape(&font, TextDirection::kLtr, 21, 23); + EXPECT_EQ(2u, result->NumCharacters()); + + string = u"aa aa aa aa aa aa aa aa aa aa"; + HarfBuzzShaper shaper_five(string.Characters16(), string.length()); + result = shaper_five.Shape(&font, TextDirection::kLtr, 27, 29); + EXPECT_EQ(2u, result->NumCharacters()); +} + TEST_F(HarfBuzzShaperTest, ShapeVerticalMixed) { font_description.SetOrientation(FontOrientation::kVerticalMixed); font = Font(font_description); @@ -483,7 +524,7 @@ // Because all characters are at 0, the glyph bounds must be the char_width. // Allow being larger because accurate width requires re-measuring each glyph. EXPECT_GE(result->Bounds().MaxX(), char_width); - EXPECT_LE(result->Bounds().MaxX(), char_width * 1.1); + EXPECT_LE(result->Bounds().MaxX(), char_width * 1.2); } TEST_F(HarfBuzzShaperTest, NegativeLetterSpacingToNegative) {
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 822343d..ae4c4109 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
@@ -196,7 +196,7 @@ if is_swarming_task and not include_swarming_tasks: continue is_cq = 'user_agent:cq' in result.get('tags', []) - is_experimental = result.get('experimental') + is_experimental = 'cq_experimental:true' in result.get('tags', []) if cq_only and not (is_cq and not is_experimental): continue build_to_status[self._build(result)] = self._try_job_status(result)
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 1879d21..9b4ce350 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
@@ -288,26 +288,60 @@ 'url': None, }, { + 'builder_name': 'cq-b', + 'experimental': False, + 'result': None, + 'status': 'SCHEDULED', + 'tags': ['cq_experimental:false', 'user_agent:cq'], + 'url': None, + }, + { + 'builder_name': 'cq-c', + 'experimental': True, + 'result': None, + 'status': 'SCHEDULED', + 'tags': ['cq_experimental:false', 'user_agent:cq'], + 'url': None, + }, + { 'builder_name': 'cq-a-experimental', 'experimental': True, 'result': None, 'status': 'SCHEDULED', - 'tags': ['user_agent:cq'], + 'tags': ['cq_experimental:true', 'user_agent:cq'], 'url': None, }, { - 'builder_name': 'other', + 'builder_name': 'cq-b-experimental', + 'experimental': False, + 'result': None, + 'status': 'SCHEDULED', + 'tags': ['cq_experimental:true', 'user_agent:cq'], + 'url': None, + }, + { + 'builder_name': 'other-a', 'experimental': False, 'status': 'SCHEDULED', 'result': None, 'tags': ['user_agent:git_cl_try'], 'url': None, }, + { + 'builder_name': 'other-b', + 'experimental': False, + 'status': 'SCHEDULED', + 'result': None, + 'tags': ['is_experimental:false', 'user_agent:git_cl_try'], + 'url': None, + }, ] self.assertEqual( git_cl.latest_try_jobs(cq_only=True), { Build('cq-a'): TryJobStatus('SCHEDULED'), + Build('cq-b'): TryJobStatus('SCHEDULED'), + Build('cq-c'): TryJobStatus('SCHEDULED'), }) def test_latest_try_jobs(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py index e09d305..c7477fd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
@@ -390,10 +390,10 @@ # TODO(sergeyu): Rename these files, they can be used on platforms # other than Android. host_device_tuples.append( - (self._build_path('content_shell_test_fonts/android_main_fonts.xml'), + (self._build_path('test_fonts/android_main_fonts.xml'), device_path('android_main_fonts.xml'))) host_device_tuples.append( - (self._build_path('content_shell_test_fonts/android_fallback_fonts.xml'), + (self._build_path('test_fonts/android_fallback_fonts.xml'), device_path('android_fallback_fonts.xml'))) for font_file in self._get_font_files(): host_device_tuples.append(
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index 509e384..5bf6360 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -69,7 +69,7 @@ MS_TRUETYPE_FONTS_PACKAGE = 'ttf-mscorefonts-installer' # Path relative to the build directory. -CONTENT_SHELL_FONTS_DIR = "content_shell_test_fonts" +CONTENT_SHELL_FONTS_DIR = "test_fonts" FONT_FILES = [ [[MS_TRUETYPE_FONTS_DIR], 'Arial.ttf', MS_TRUETYPE_FONTS_PACKAGE],
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/fuchsia.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/fuchsia.py index d69a2296..727aba6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/fuchsia.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/fuchsia.py
@@ -159,11 +159,11 @@ self._target.RunCommand(['mkdir', '/system/fonts']) self._target.PutFile( - os.path.join(build_path, 'content_shell_test_fonts', 'android_main_fonts.xml'), + os.path.join(build_path, 'test_fonts', 'android_main_fonts.xml'), FONTS_DEVICE_PATH + '/fonts.xml') self._target.PutFile( - os.path.join(build_path, 'content_shell_test_fonts', 'android_fallback_fonts.xml'), + os.path.join(build_path, 'test_fonts', 'android_fallback_fonts.xml'), FONTS_DEVICE_PATH + '/fonts_fallback.xml') self._target.PutFiles(fonts, FONTS_DEVICE_PATH)
diff --git a/third_party/content_shell_fonts/.gitignore b/third_party/content_shell_fonts/.gitignore deleted file mode 100644 index a871776..0000000 --- a/third_party/content_shell_fonts/.gitignore +++ /dev/null
@@ -1,2 +0,0 @@ -content_shell_test_fonts/ -content_shell_test_fonts.tar.gz
diff --git a/third_party/content_shell_fonts/BUILD.gn b/third_party/content_shell_fonts/BUILD.gn deleted file mode 100644 index a1ddd95b..0000000 --- a/third_party/content_shell_fonts/BUILD.gn +++ /dev/null
@@ -1,21 +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. - -copy("content_shell_fonts") { - sources = [ - "LICENSE", - "content_shell_test_fonts/DejaVuSans.ttf", - "content_shell_test_fonts/Garuda.ttf", - "content_shell_test_fonts/Lohit-Devanagari.ttf", - "content_shell_test_fonts/Lohit-Gurmukhi.ttf", - "content_shell_test_fonts/Lohit-Tamil.ttf", - "content_shell_test_fonts/MuktiNarrow.ttf", - "content_shell_test_fonts/NotoSansCJKjp-Regular.otf", - "content_shell_test_fonts/NotoSansKhmer-Regular.ttf", - ] - - outputs = [ - "${root_build_dir}/content_shell_test_fonts/{{source_file_part}}", - ] -}
diff --git a/third_party/content_shell_fonts/OWNERS b/third_party/content_shell_fonts/OWNERS deleted file mode 100644 index aa56044..0000000 --- a/third_party/content_shell_fonts/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -dpranke@chromium.org -drott@chromium.org
diff --git a/third_party/content_shell_fonts/content_shell_test_fonts.tar.gz.sha1 b/third_party/content_shell_fonts/content_shell_test_fonts.tar.gz.sha1 deleted file mode 100644 index bd62a83..0000000 --- a/third_party/content_shell_fonts/content_shell_test_fonts.tar.gz.sha1 +++ /dev/null
@@ -1 +0,0 @@ -eea1fc91877797451ff7cff29e49a3e15e1d9ee1 \ No newline at end of file
diff --git a/third_party/fontconfig/fontconfig.gni b/third_party/fontconfig/fontconfig.gni index 3ea4dd2a..0965f9fe 100644 --- a/third_party/fontconfig/fontconfig.gni +++ b/third_party/fontconfig/fontconfig.gni
@@ -7,5 +7,5 @@ assert(is_linux) declare_args() { - use_bundled_fontconfig = is_chromecast || is_desktop_linux + use_bundled_fontconfig = is_linux }
diff --git a/third_party/test_fonts/.gitignore b/third_party/test_fonts/.gitignore new file mode 100644 index 0000000..53122f6 --- /dev/null +++ b/third_party/test_fonts/.gitignore
@@ -0,0 +1,2 @@ +test_fonts/ +test_fonts.tar.gz
diff --git a/third_party/test_fonts/BUILD.gn b/third_party/test_fonts/BUILD.gn new file mode 100644 index 0000000..8015ac5f --- /dev/null +++ b/third_party/test_fonts/BUILD.gn
@@ -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. + +copy("test_fonts") { + sources = [ + "LICENSE", + "test_fonts/DejaVuSans-Bold.ttf", + "test_fonts/DejaVuSans.ttf", + "test_fonts/Garuda.ttf", + "test_fonts/Lohit-Devanagari.ttf", + "test_fonts/Lohit-Gurmukhi.ttf", + "test_fonts/Lohit-Tamil.ttf", + "test_fonts/MuktiNarrow.ttf", + "test_fonts/NotoSansCJKjp-Regular.otf", + "test_fonts/NotoSansKhmer-Regular.ttf", + ] + + outputs = [ + "${root_build_dir}/test_fonts/{{source_file_part}}", + ] +}
diff --git a/third_party/content_shell_fonts/LICENSE b/third_party/test_fonts/LICENSE similarity index 99% rename from third_party/content_shell_fonts/LICENSE rename to third_party/test_fonts/LICENSE index 9b24d45..9a11b1e19 100644 --- a/third_party/content_shell_fonts/LICENSE +++ b/third_party/test_fonts/LICENSE
@@ -448,6 +448,7 @@ -------------------------------------------------------------------------------- The Vera Bitstream License applies to the following files: +DejaVuSans-Bold.ttf DejaVuSans.ttf
diff --git a/third_party/test_fonts/OWNERS b/third_party/test_fonts/OWNERS new file mode 100644 index 0000000..d300591 --- /dev/null +++ b/third_party/test_fonts/OWNERS
@@ -0,0 +1,3 @@ +dpranke@chromium.org +drott@chromium.org +thomasanderson@chromium.org
diff --git a/third_party/content_shell_fonts/README.chromium b/third_party/test_fonts/README.chromium similarity index 65% rename from third_party/content_shell_fonts/README.chromium rename to third_party/test_fonts/README.chromium index efce03a..f1cc479 100644 --- a/third_party/content_shell_fonts/README.chromium +++ b/third_party/test_fonts/README.chromium
@@ -1,11 +1,11 @@ -Name: content_shell_fonts +Name: test_fonts URL: https://pagure.io/lohit, http://www.nongnu.org/freebangfont/downloads.html#mukti, https://dejavu-fonts.github.io/Download.html Version: unknown License: SIL OPEN FONT LICENSE, GPL v2, Bitstream Vera Fonts Copyright Security Critical: no Description: -A collection of fonts in the content_shell_fonts directory distributed in a +A collection of fonts in the test_fonts directory distributed in a cloud storage bucket in order to ease running layout test under multiple Linux distributions. @@ -13,23 +13,22 @@ 1. Download fonts from their source repositories, see "Font Origins" below, build them if necessary. -2. Copy the necessary files to ./content_shell_test_fonts +2. Copy the necessary files to ./test_fonts 3. Verify that the licenses are correctly referenced in LICENSE (See the section headers in the LICENSE file: When adding a new license, add a dashed line, list the new font files that it applies to, and copy and paste the additional license below.) -4. Update the `//third_party/content_shell_fonts/` BUILD.gn target to include - all the current fonts and their license files. +4. Update the `//third_party/test_fonts/` BUILD.gn target to include all the + current fonts and their license files. 5. Run the `upload_to_google_storage.py` (from depot_tools) script to upload - the files. You must do this in the //third_party/content_shell_fonts directory. - To do this, execute: - $ upload_to_google_storage.py --archive -b chromium-fonts content_shell_test_fonts -6. Add all the font_bundle.tar.gz.sha1 file to the chromium src repository, - by executing the following command: - $ git add ./third_party/content_shell_fonts/content_shell_test_fonts.tar.gz.sha1 -7. (optional) Modify loaded kSystemFontsForFontconfig and - kCloudStorageSyncedFonts lists in fontconfig_util_linux.cc . Also update - FONT_FILES in third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py . + the files. You must do this in the //third_party/test_fonts directory. To + do this, execute: + $ upload_to_google_storage.py --archive -b chromium-fonts test_fonts +6. Add all the font_bundle.tar.gz.sha1 file to the chromium src repository, by + executing the following command: + $ git add ./third_party/test_fonts/test_fonts.tar.gz.sha1 +7. (optional) Update FONT_FILES in + third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py . If you need access to the chromium-fonts bucket, contact Chrome infra. For details, please refer to
diff --git a/third_party/test_fonts/test_fonts.tar.gz.sha1 b/third_party/test_fonts/test_fonts.tar.gz.sha1 new file mode 100644 index 0000000..ec364f4108 --- /dev/null +++ b/third_party/test_fonts/test_fonts.tar.gz.sha1
@@ -0,0 +1 @@ +9c1ff266a05e3b8523de198f62dabb9a881ab28f \ No newline at end of file
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index aa5dc7b3..7444f33 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -413,6 +413,8 @@ 'Battor Agent Linux': 'release_bot', 'Battor Agent Mac': 'release_bot', 'Battor Agent Win': 'release_bot', + 'Mac Builder FYI': 'official_goma', + 'Win Builder FYI': 'official_goma_x86', }, 'chromium.swarm': {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 237ccbb..29b988a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -44823,6 +44823,9 @@ </enum> <enum name="VAVDAH264DecoderFailure"> + <obsolete> + Deprecated as of 4/2015, partially replaced by VAVDADecoderFailure. + </obsolete> <int value="0" label="FRAME_MBS_ONLY_FLAG_NOT_ONE"/> <int value="1" label="GAPS_IN_FRAME_NUM"/> <int value="2" label="MID_STREAM_RESOLUTION_CHANGE"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 27b67e9..4c0efb2e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2192,6 +2192,15 @@ </summary> </histogram> +<histogram name="Apps.AppListHide.InputLatency" units="ms"> + <owner>wutao@chromium.org</owner> + <summary> + Elapsed time from the input event to hide the launcher UI. This is logged + each time the launcher is dismissed by pressing search key, clicking shelf + button, or focusing out side of the launcher. + </summary> +</histogram> + <histogram name="Apps.AppListHowEnabled" enum="AppListEnableSource"> <owner>tapted@chromium.org</owner> <summary> @@ -2289,6 +2298,15 @@ </summary> </histogram> +<histogram name="Apps.AppListShow.InputLatency" units="ms"> + <owner>wutao@chromium.org</owner> + <summary> + Elapsed time from the input event to show the launcher UI. This is logged + each time the app list is shown by pressing search key, clicking shelf + button, or swiping from shelf. + </summary> +</histogram> + <histogram name="Apps.AppListShowSource" enum="AppListShowSource"> <owner>newcomer@chromium.org</owner> <summary> @@ -36862,6 +36880,16 @@ </summary> </histogram> +<histogram name="Media.VaapiWrapper.VADisplayStateInitializeSuccess" + enum="BooleanSuccess"> + <owner>acourbot@chromium.org</owner> + <owner>mcasas@chromium.org</owner> + <summary> + Whether the call to VaapiWrapper's VADisplayState::Initialize() succeeded or + not. + </summary> +</histogram> + <histogram name="Media.VAJDA.DecoderFailure" enum="VAJDADecoderFailure"> <owner>kcwu@chromium.org</owner> <summary> @@ -36883,6 +36911,14 @@ </summary> </histogram> +<histogram name="Media.VAVDA.VaapiWrapperCreationSuccess" enum="BooleanSuccess"> + <owner>acourbot@chromium.org</owner> + <owner>mcasas@chromium.org</owner> + <summary> + Whether the creation of VaapiWrapper succeeded or not inside VaVDA. + </summary> +</histogram> + <histogram name="Media.VAVDAH264.DecoderFailure" enum="VAVDAH264DecoderFailure"> <obsolete> Deprecated as of 4/2015, partially replaced by Media.VAVDA.DecoderFailure. @@ -79288,6 +79324,21 @@ </summary> </histogram> +<histogram name="Search.ContextualSearch.Ranker.FeaturesAvailable" + enum="Boolean"> + <owner>donnd@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary> + Logs that the UX has entered a state where features are available to be + recorded to Ranker. A value of true indicates that the available features + include outcomes, false if they are just features at inference-time. Use to + correlate with what actually gets recorded in the Search. + ContextualSearch.Ranker.Recorded histogram. Recorded when a tap gesture is + recognized that might trigger our UX (for pure features), and when the UX is + actually shown (for outcomes). Implemented for Android. + </summary> +</histogram> + <histogram name="Search.ContextualSearch.Ranker.Model.Status" enum="RankerModelStatus"> <owner>hamelphi@google.com</owner>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 6b0126d..3edb90f 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -294,7 +294,7 @@ swarming=[ { 'gpu': '8086:1616', - 'os': 'Windows-10-16299.248', + 'os': 'Windows-10', 'pool': 'Chrome-perf', 'device_ids': [ 'build117-b1', 'build118-b1', @@ -308,7 +308,7 @@ swarming=[ { 'gpu': '102b:0534', - 'os': 'Windows-10-10240', + 'os': 'Windows-10', 'pool': 'Chrome-perf', 'device_ids': [ 'build132-m1', 'build133-m1',
diff --git a/tools/traffic_annotation/auditor/BUILD.gn b/tools/traffic_annotation/auditor/BUILD.gn index df52f36..c2a22d03 100644 --- a/tools/traffic_annotation/auditor/BUILD.gn +++ b/tools/traffic_annotation/auditor/BUILD.gn
@@ -69,6 +69,7 @@ "//net:traffic_annotation", "//third_party/libxml", "//third_party/protobuf:protobuf_full", + "//third_party/re2", ] }
diff --git a/tools/traffic_annotation/auditor/DEPS b/tools/traffic_annotation/auditor/DEPS index cc1e04b..2e35345 100644 --- a/tools/traffic_annotation/auditor/DEPS +++ b/tools/traffic_annotation/auditor/DEPS
@@ -2,4 +2,5 @@ "+components/policy/proto", "+third_party/libxml", "+third_party/protobuf/src/google", + "+third_party/re2", ]
diff --git a/tools/traffic_annotation/auditor/auditor_result.cc b/tools/traffic_annotation/auditor/auditor_result.cc index 85bbded9..320a884d 100644 --- a/tools/traffic_annotation/auditor/auditor_result.cc +++ b/tools/traffic_annotation/auditor/auditor_result.cc
@@ -28,7 +28,8 @@ type == AuditorResult::Type::ERROR_MISSING_TAG_USED || type == AuditorResult::Type::ERROR_NO_ANNOTATION || type == AuditorResult::Type::ERROR_MISSING_SECOND_ID || - type == AuditorResult::Type::ERROR_DIRECT_ASSIGNMENT); + type == AuditorResult::Type::ERROR_DIRECT_ASSIGNMENT || + type == AuditorResult::Type::ERROR_TEST_ANNOTATION); if (!message.empty()) details_.push_back(message); }; @@ -163,6 +164,10 @@ "files (like jumbo), rerun the auditor using --all-files switch.", details_[0].c_str()); + case AuditorResult::Type::ERROR_TEST_ANNOTATION: + return base::StringPrintf("Annotation for tests is used in '%s:%i'.", + file_path_.c_str(), line_); + default: return std::string(); }
diff --git a/tools/traffic_annotation/auditor/auditor_result.h b/tools/traffic_annotation/auditor/auditor_result.h index 996921c..51c60d32 100644 --- a/tools/traffic_annotation/auditor/auditor_result.h +++ b/tools/traffic_annotation/auditor/auditor_result.h
@@ -43,7 +43,8 @@ ERROR_DIRECT_ASSIGNMENT, // A value is directly assigned to a mutable // annotation or annotation instialized with // list expresssion. - ERROR_ANNOTATIONS_XML_UPDATE // Annotations XML requires update. + ERROR_ANNOTATIONS_XML_UPDATE, // Annotations XML requires update. + ERROR_TEST_ANNOTATION, // Annotation for tests is used. }; static const int kNoCodeLineSpecified;
diff --git a/tools/traffic_annotation/auditor/instance.cc b/tools/traffic_annotation/auditor/instance.cc index a930834..086ed130 100644 --- a/tools/traffic_annotation/auditor/instance.cc +++ b/tools/traffic_annotation/auditor/instance.cc
@@ -164,7 +164,8 @@ if (unique_id_hash_code == TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code || unique_id_hash_code == PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code) { - return AuditorResult(AuditorResult::Type::RESULT_IGNORE); + return AuditorResult(AuditorResult::Type::ERROR_TEST_ANNOTATION, "", + file_path, line_number); } // Process undefined tags.
diff --git a/tools/traffic_annotation/auditor/safe_list.txt b/tools/traffic_annotation/auditor/safe_list.txt index 93bf3ff..cd4c10ef 100644 --- a/tools/traffic_annotation/auditor/safe_list.txt +++ b/tools/traffic_annotation/auditor/safe_list.txt
@@ -2,7 +2,9 @@ # anntotation auditor. Refer to AuditorException::ExceptionType in # 'tools/traffic_annotation/auditor/traffic_annotation_auditor.h' for types of # exceptions. -all,tools +# Use * as wildcard for zero or more characters. +all,tools/* missing,net/url_request/url_fetcher.cc missing,net/url_request/url_request_context.cc -direct_assignment,download::ProtoConversions::EntryFromProto@components/download/internal/background_service/proto_conversions.cc \ No newline at end of file +direct_assignment,download::ProtoConversions::EntryFromProto@components/download/internal/background_service/proto_conversions.cc +test_annotation,*test*,*fuzzer*,*mock*,*fake*,net/quic/chromium/quic_chromium_client_session_peer.cc \ No newline at end of file
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index de66aa9..ff75bdc 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -18,6 +18,7 @@ #include "build/build_config.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "third_party/re2/src/re2/re2.h" #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h" #include "tools/traffic_annotation/auditor/traffic_annotation_id_checker.h" @@ -307,8 +308,8 @@ const std::vector<std::string>& safe_list = safe_list_[static_cast<int>(exception_type)]; - for (const std::string& ignore_path : safe_list) { - if (!strncmp(file_path.c_str(), ignore_path.c_str(), ignore_path.length())) + for (const std::string& ignore_pattern : safe_list) { + if (re2::RE2::FullMatch(file_path, ignore_pattern)) return true; } @@ -365,12 +366,24 @@ if (block_type == "ANNOTATION") { AnnotationInstance new_annotation; result = new_annotation.Deserialize(lines, current, end_line); - if (result.IsOK()) { - extracted_annotations_.push_back(new_annotation); - } else if (result.type() == AuditorResult::Type::ERROR_MISSING_TAG_USED && - IsSafeListed(result.file_path(), - AuditorException::ExceptionType::MISSING)) { - result = AuditorResult(AuditorResult::Type::RESULT_IGNORE); + switch (result.type()) { + case AuditorResult::Type::RESULT_OK: + extracted_annotations_.push_back(new_annotation); + break; + case AuditorResult::Type::ERROR_MISSING_TAG_USED: + if (IsSafeListed(result.file_path(), + AuditorException::ExceptionType::MISSING)) { + result = AuditorResult(AuditorResult::Type::RESULT_IGNORE); + } + break; + case AuditorResult::Type::ERROR_TEST_ANNOTATION: + if (IsSafeListed(result.file_path(), + AuditorException::ExceptionType::TEST_ANNOTATION)) { + result = AuditorResult(AuditorResult::Type::RESULT_IGNORE); + } + break; + default: + break; } } else if (block_type == "CALL") { CallInstance new_call; @@ -418,37 +431,56 @@ bool TrafficAnnotationAuditor::LoadSafeList() { base::FilePath safe_list_file = base::MakeAbsoluteFilePath(source_path_.Append(kSafeListPath)); - std::string file_content; - if (base::ReadFileToString(safe_list_file, &file_content)) { - base::RemoveChars(file_content, "\r", &file_content); - std::vector<std::string> lines = base::SplitString( - file_content, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); - for (const std::string& line : lines) { - // Ignore comments and empty lines. - if (!line.length() || line[0] == '#') - continue; - size_t comma = line.find(','); - if (comma == std::string::npos) { - LOG(ERROR) << "Unexpected syntax in safe_list.txt, line: " << line; - return false; - } - AuditorException::ExceptionType exception_type; - if (AuditorException::TypeFromString(line.substr(0, comma), - &exception_type)) { - safe_list_[static_cast<int>(exception_type)].push_back( - line.substr(comma + 1, line.length() - comma - 1)); - } else { - LOG(ERROR) << "Unexpected type in safe_list.txt line: " << line; - return false; - } - } - safe_list_loaded_ = true; - return true; + std::string file_content; + if (!base::ReadFileToString(safe_list_file, &file_content)) { + LOG(ERROR) << "Could not read " << kSafeListPath.MaybeAsASCII(); + return false; } - LOG(ERROR) << "Could not read " << kSafeListPath.MaybeAsASCII(); - return false; + base::RemoveChars(file_content, "\r", &file_content); + std::vector<std::string> lines = base::SplitString( + file_content, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + + for (const std::string& line : lines) { + // Ignore comments and empty lines. + if (!line.length() || line[0] == '#') + continue; + + std::vector<std::string> tokens = base::SplitString( + line, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + + // Expect a type and at least one value in each line. + if (tokens.size() < 2) { + LOG(ERROR) << "Unexpected syntax in safe_list.txt, line: " << line; + return false; + } + + AuditorException::ExceptionType exception_type; + if (!AuditorException::TypeFromString(tokens[0], &exception_type)) { + LOG(ERROR) << "Unexpected type in safe_list.txt line: " << line; + return false; + } + for (unsigned i = 1; i < tokens.size(); i++) { + // Convert the rest of the line into re2 patterns, making dots as fixed + // characters and asterisks as wildcards. + // Note that all file paths are converted to Linux style before checking. + if (!base::ContainsOnlyChars( + base::ToLowerASCII(tokens[i]), + "0123456789_abcdefghijklmnopqrstuvwxyz.*/:@")) { + LOG(ERROR) << "Unexpected character in safe_list.txt token: " + << tokens[i]; + return false; + } + std::string pattern; + base::ReplaceChars(tokens[i], ".", "[.]", &pattern); + base::ReplaceChars(pattern, "*", ".*", &pattern); + safe_list_[static_cast<int>(exception_type)].push_back(pattern); + } + } + + safe_list_loaded_ = true; + return true; } // static
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h index 55f16dda..62d6932e 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
@@ -20,7 +20,8 @@ ALL, // Ignore all errors (doesn't check the files at all). MISSING, // Ignore missing annotations. DIRECT_ASSIGNMENT, // Ignore direct assignment of annotation value. - EXCEPTION_TYPE_LAST = DIRECT_ASSIGNMENT + TEST_ANNOTATION, // Ignore usages of annotation for tests. + EXCEPTION_TYPE_LAST = TEST_ANNOTATION } type; static bool TypeFromString(const std::string& type_string, @@ -31,6 +32,8 @@ *type_value = ExceptionType::MISSING; } else if (type_string == "direct_assignment") { *type_value = ExceptionType::DIRECT_ASSIGNMENT; + } else if (type_string == "test_annotation") { + *type_value = ExceptionType::TEST_ANNOTATION; } else { return false; }
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc index 2a333e8..a074a8d 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
@@ -272,6 +272,18 @@ AuditorException::ExceptionType::MISSING)); EXPECT_TRUE(auditor().IsSafeListed("net/url_request/url_request_context.cc", AuditorException::ExceptionType::MISSING)); + + // Files having the word test in their full path can have annotation for + // tests. + EXPECT_FALSE( + auditor().IsSafeListed("net/url_request/url_fetcher.cc", + AuditorException::ExceptionType::TEST_ANNOTATION)); + EXPECT_TRUE( + auditor().IsSafeListed("chrome/browser/test_something.cc", + AuditorException::ExceptionType::TEST_ANNOTATION)); + EXPECT_TRUE( + auditor().IsSafeListed("test/send_something.cc", + AuditorException::ExceptionType::TEST_ANNOTATION)); } // Tests if annotation instances are corrrectly deserialized. @@ -292,7 +304,7 @@ AnnotationInstance::Type::ANNOTATION_COMPLETING}, {"good_partial_annotation.txt", AuditorResult::Type::RESULT_OK, AnnotationInstance::Type::ANNOTATION_PARTIAL}, - {"good_test_annotation.txt", AuditorResult::Type::RESULT_IGNORE}, + {"good_test_annotation.txt", AuditorResult::Type::ERROR_TEST_ANNOTATION}, {"missing_annotation.txt", AuditorResult::Type::ERROR_MISSING_TAG_USED}, {"no_annotation.txt", AuditorResult::Type::ERROR_NO_ANNOTATION}, {"fatal_annotation1.txt", AuditorResult::Type::ERROR_FATAL}, @@ -309,7 +321,7 @@ AnnotationInstance annotation; AuditorResult::Type result_type = Deserialize(test_case.file_name, &annotation); - EXPECT_EQ(result_type, test_case.result_type); + EXPECT_EQ(result_type, test_case.result_type) << test_case.file_name; if (result_type == AuditorResult::Type::RESULT_OK) EXPECT_EQ(annotation.type, test_case.type);
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc index 3413cfd7..c8c7cc34 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc
@@ -16,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "third_party/re2/src/re2/re2.h" namespace { @@ -142,9 +143,8 @@ for (const std::string& file_path : git_files_) { if (!strncmp(file_path.c_str(), directory_name.c_str(), name_length)) { bool ignore = false; - for (const std::string& ignore_path : ignore_list) { - if (!strncmp(file_path.c_str(), ignore_path.c_str(), - ignore_path.length())) { + for (const std::string& ignore_pattern : ignore_list) { + if (re2::RE2::FullMatch(file_path.c_str(), ignore_pattern)) { ignore = true; break; }
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 0a9687d..1bb5f1c6 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -252,6 +252,7 @@ <item id="web_history_expire_between_dates" hash_code="126122632" type="1" second_id="110307337" content_hash_code="34304787" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/history_service.cc"/> <item id="web_history_query" hash_code="17400350" type="1" second_id="110307337" content_hash_code="36075147" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/browsing_history_service.cc"/> <item id="web_history_service" hash_code="110307337" type="2" content_hash_code="16140045" os_list="linux,windows" semantics_fields="1,5" policy_fields="-1,3" file_path="components/history/core/browser/web_history_service.cc"/> + <item id="webrtc_event_log_uploader" hash_code="24186190" type="0" content_hash_code="107123816" os_list="linux,windows" file_path="chrome/browser/media/webrtc/webrtc_event_log_uploader.cc"/> <item id="webrtc_log_upload" hash_code="62443804" type="0" content_hash_code="33661169" os_list="linux,windows" file_path="chrome/browser/media/webrtc/webrtc_log_uploader.cc"/> <item id="webrtc_peer_connection" hash_code="63497370" type="0" content_hash_code="60553259" os_list="linux,windows" file_path="content/renderer/media/webrtc/peer_connection_dependency_factory.cc"/> <item id="websocket_basic_stream" hash_code="51586722" type="0" content_hash_code="68121427" os_list="linux,windows" file_path="net/websockets/websocket_basic_stream.cc"/>
diff --git a/ui/app_list/app_list_metrics.h b/ui/app_list/app_list_metrics.h index 0f3fd2d..b38ebbd 100644 --- a/ui/app_list/app_list_metrics.h +++ b/ui/app_list/app_list_metrics.h
@@ -13,6 +13,16 @@ class SearchModel; class SearchResult; +// The UMA histogram that logs the input latency from input event to the +// representation time of the shown launcher UI. +constexpr char kAppListShowInputLatencyHistogram[] = + "Apps.AppListShow.InputLatency"; + +// The UMA histogram that logs the input latency from input event to the +// representation time of the dismissed launcher UI. +constexpr char kAppListHideInputLatencyHistogram[] = + "Apps.AppListHide.InputLatency"; + void RecordFolderShowHideAnimationSmoothness(int actual_frames, int ideal_duration_ms, float refresh_rate);
diff --git a/ui/app_list/vector_icons/ic_arrow_up.1x.icon b/ui/app_list/vector_icons/ic_arrow_up.1x.icon index d28822f..40d0ce7 100644 --- a/ui/app_list/vector_icons/ic_arrow_up.1x.icon +++ b/ui/app_list/vector_icons/ic_arrow_up.1x.icon
@@ -9,5 +9,4 @@ LINE_TO, 0, 7.66f, LINE_TO, 6, 2, R_LINE_TO, 6, 5.66f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_arrow_up.icon b/ui/app_list/vector_icons/ic_arrow_up.icon index 5f8b186..91c3daf 100644 --- a/ui/app_list/vector_icons/ic_arrow_up.icon +++ b/ui/app_list/vector_icons/ic_arrow_up.icon
@@ -9,5 +9,4 @@ LINE_TO, 0, 16.33f, LINE_TO, 12, 5, R_LINE_TO, 12, 11.33f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_instant.1x.icon b/ui/app_list/vector_icons/ic_badge_instant.1x.icon index 77d71b1..664ec0f 100644 --- a/ui/app_list/vector_icons/ic_badge_instant.1x.icon +++ b/ui/app_list/vector_icons/ic_badge_instant.1x.icon
@@ -18,5 +18,4 @@ CUBIC_TO, 8.86f, 5, 9, 5.14f, 9, 5.31f, CUBIC_TO, 9, 5.38f, 8.98f, 5.44f, 8.94f, 5.49f, LINE_TO, 5.36f, 11, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_instant.icon b/ui/app_list/vector_icons/ic_badge_instant.icon index f88d166..59349c6 100644 --- a/ui/app_list/vector_icons/ic_badge_instant.icon +++ b/ui/app_list/vector_icons/ic_badge_instant.icon
@@ -18,5 +18,4 @@ CUBIC_TO, 17.72f, 9.99f, 18, 10.27f, 18, 10.61f, CUBIC_TO, 18.01f, 10.76f, 17.95f, 10.88f, 17.88f, 10.99f, LINE_TO, 10.73f, 22, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_play.1x.icon b/ui/app_list/vector_icons/ic_badge_play.1x.icon index 9fd281b..d5325b0 100644 --- a/ui/app_list/vector_icons/ic_badge_play.1x.icon +++ b/ui/app_list/vector_icons/ic_badge_play.1x.icon
@@ -33,5 +33,4 @@ LINE_TO, 1, 10.15f, CUBIC_TO, 1, 10.28f, 1.1f, 10.34f, 1.19f, 10.24f, LINE_TO, 5.5f, 5.93f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_play.icon b/ui/app_list/vector_icons/ic_badge_play.icon index 77e62cd..b3c4c7b 100644 --- a/ui/app_list/vector_icons/ic_badge_play.icon +++ b/ui/app_list/vector_icons/ic_badge_play.icon
@@ -36,5 +36,4 @@ LINE_TO, 3, 20.43f, CUBIC_TO, 3, 20.69f, 3.19f, 20.81f, 3.38f, 20.62f, LINE_TO, 12, 12, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_rating.1x.icon b/ui/app_list/vector_icons/ic_badge_rating.1x.icon index 06b859c3..d7a8302 100644 --- a/ui/app_list/vector_icons/ic_badge_rating.1x.icon +++ b/ui/app_list/vector_icons/ic_badge_rating.1x.icon
@@ -13,5 +13,4 @@ LINE_TO, 1, 4.81f, LINE_TO, 3.73f, 7.3f, LINE_TO, 2.91f, 11, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_badge_rating.icon b/ui/app_list/vector_icons/ic_badge_rating.icon index 90938ee..4c0d253a7 100644 --- a/ui/app_list/vector_icons/ic_badge_rating.icon +++ b/ui/app_list/vector_icons/ic_badge_rating.icon
@@ -13,5 +13,4 @@ LINE_TO, 2, 9.62f, R_LINE_TO, 5.46f, 4.98f, LINE_TO, 5.82f, 22, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_bookmark.1x.icon b/ui/app_list/vector_icons/ic_bookmark.1x.icon index 9d81207..7c77a3c 100644 --- a/ui/app_list/vector_icons/ic_bookmark.1x.icon +++ b/ui/app_list/vector_icons/ic_bookmark.1x.icon
@@ -13,5 +13,4 @@ LINE_TO, 2, 7.34f, R_LINE_TO, 3.82f, 3.49f, LINE_TO, 4.67f, 16, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_bookmark.icon b/ui/app_list/vector_icons/ic_bookmark.icon index f8a846f..4f5ae02 100644 --- a/ui/app_list/vector_icons/ic_bookmark.icon +++ b/ui/app_list/vector_icons/ic_bookmark.icon
@@ -13,5 +13,4 @@ LINE_TO, 3, 14.67f, R_LINE_TO, 8.19f, 6.97f, LINE_TO, 8.73f, 32, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_close.1x.icon b/ui/app_list/vector_icons/ic_close.1x.icon index 3a5801a..55c4b63 100644 --- a/ui/app_list/vector_icons/ic_close.1x.icon +++ b/ui/app_list/vector_icons/ic_close.1x.icon
@@ -15,5 +15,4 @@ LINE_TO, 17.59f, 19, LINE_TO, 19, 17.59f, LINE_TO, 13.41f, 12, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_close.icon b/ui/app_list/vector_icons/ic_close.icon index a4e83b22..67d7220 100644 --- a/ui/app_list/vector_icons/ic_close.icon +++ b/ui/app_list/vector_icons/ic_close.icon
@@ -15,5 +15,4 @@ LINE_TO, 35.18f, 38, LINE_TO, 38, 35.18f, LINE_TO, 26.82f, 24, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_domain.1x.icon b/ui/app_list/vector_icons/ic_domain.1x.icon index da781731..502a38f 100644 --- a/ui/app_list/vector_icons/ic_domain.1x.icon +++ b/ui/app_list/vector_icons/ic_domain.1x.icon
@@ -22,5 +22,4 @@ LINE_TO, 10, 3, LINE_TO, 10, 6, LINE_TO, 13, 6, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_domain.icon b/ui/app_list/vector_icons/ic_domain.icon index 0a41747..d56e9a9 100644 --- a/ui/app_list/vector_icons/ic_domain.icon +++ b/ui/app_list/vector_icons/ic_domain.icon
@@ -22,5 +22,4 @@ LINE_TO, 20, 6, LINE_TO, 20, 13, LINE_TO, 26, 13, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_equal.1x.icon b/ui/app_list/vector_icons/ic_equal.1x.icon index 58c4f05..11ec410 100644 --- a/ui/app_list/vector_icons/ic_equal.1x.icon +++ b/ui/app_list/vector_icons/ic_equal.1x.icon
@@ -14,5 +14,4 @@ R_V_LINE_TO, 2, H_LINE_TO, 4, R_V_LINE_TO, -2, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ui/app_list/vector_icons/ic_equal.icon b/ui/app_list/vector_icons/ic_equal.icon index 6f22451..4988a87 100644 --- a/ui/app_list/vector_icons/ic_equal.icon +++ b/ui/app_list/vector_icons/ic_equal.icon
@@ -14,5 +14,4 @@ R_V_LINE_TO, 3, H_LINE_TO, 9, R_V_LINE_TO, -3, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ui/app_list/vector_icons/ic_google_black.1x.icon b/ui/app_list/vector_icons/ic_google_black.1x.icon index dd91373..f712169 100644 --- a/ui/app_list/vector_icons/ic_google_black.1x.icon +++ b/ui/app_list/vector_icons/ic_google_black.1x.icon
@@ -17,5 +17,4 @@ CUBIC_TO, 16.12f, 18, 17.54f, 15.57f, 17.81f, 14, LINE_TO, 12, 14, LINE_TO, 12, 10, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_google_black.icon b/ui/app_list/vector_icons/ic_google_black.icon index 6e55988..3e7b050d 100644 --- a/ui/app_list/vector_icons/ic_google_black.icon +++ b/ui/app_list/vector_icons/ic_google_black.icon
@@ -16,5 +16,4 @@ CUBIC_TO, 32.23f, 36, 35.09f, 31.14f, 35.62f, 28, LINE_TO, 24, 28, LINE_TO, 24, 20, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_google_color.1x.icon b/ui/app_list/vector_icons/ic_google_color.1x.icon index 317fe5c6..4cf472c1 100644 --- a/ui/app_list/vector_icons/ic_google_color.1x.icon +++ b/ui/app_list/vector_icons/ic_google_color.1x.icon
@@ -46,5 +46,4 @@ CUBIC_TO, 8.22f, 2, 4.77f, 4.25f, 3.09f, 7.52f, LINE_TO, 6.49f, 10.1f, CUBIC_TO, 7.3f, 7.74f, 9.55f, 5.98f, 12.2f, 5.98f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_google_color.icon b/ui/app_list/vector_icons/ic_google_color.icon index 564966d..ca9fe70 100644 --- a/ui/app_list/vector_icons/ic_google_color.icon +++ b/ui/app_list/vector_icons/ic_google_color.icon
@@ -46,5 +46,4 @@ R_CUBIC_TO, 3, 0, 5.7f, 1, 7.8f, 3, R_LINE_TO, 5.8f, -5.7f, CUBIC_TO, 34.5f, 6, 29.9f, 4, 24.4f, 4, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_history.1x.icon b/ui/app_list/vector_icons/ic_history.1x.icon index b9695ccf..dca7a78 100644 --- a/ui/app_list/vector_icons/ic_history.1x.icon +++ b/ui/app_list/vector_icons/ic_history.1x.icon
@@ -22,5 +22,4 @@ LINE_TO, 8.2f, 9.8f, LINE_TO, 8.2f, 5, LINE_TO, 9.4f, 5, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_history.icon b/ui/app_list/vector_icons/ic_history.icon index 8adbe31f..9890851 100644 --- a/ui/app_list/vector_icons/ic_history.icon +++ b/ui/app_list/vector_icons/ic_history.icon
@@ -22,5 +22,4 @@ LINE_TO, 16.5f, 19.5f, LINE_TO, 16.5f, 10.5f, LINE_TO, 18.75f, 10.5f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_mic_black.1x.icon b/ui/app_list/vector_icons/ic_mic_black.1x.icon index 24b28ac..72ec88f 100644 --- a/ui/app_list/vector_icons/ic_mic_black.1x.icon +++ b/ui/app_list/vector_icons/ic_mic_black.1x.icon
@@ -21,5 +21,4 @@ LINE_TO, 13, 18.72f, CUBIC_TO, 16.28f, 18.24f, 19, 15.42f, 19, 12, LINE_TO, 17.3f, 12, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_mic_black.icon b/ui/app_list/vector_icons/ic_mic_black.icon index ca365a0..08371f1 100644 --- a/ui/app_list/vector_icons/ic_mic_black.icon +++ b/ui/app_list/vector_icons/ic_mic_black.icon
@@ -20,5 +20,4 @@ LINE_TO, 26, 36.44f, CUBIC_TO, 32.56f, 35.48f, 38, 29.84f, 38, 23, LINE_TO, 34.6f, 23, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_search.1x.icon b/ui/app_list/vector_icons/ic_search.1x.icon index 8babbf81..1cf4f35 100644 --- a/ui/app_list/vector_icons/ic_search.1x.icon +++ b/ui/app_list/vector_icons/ic_search.1x.icon
@@ -22,5 +22,4 @@ CUBIC_TO, 2.83f, 4.67f, 4.67f, 2.83f, 6.95f, 2.83f, CUBIC_TO, 9.22f, 2.83f, 11.06f, 4.67f, 11.06f, 6.95f, CUBIC_TO, 11.06f, 9.22f, 9.22f, 11.06f, 6.95f, 11.06f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_search.icon b/ui/app_list/vector_icons/ic_search.icon index 53ea5541..44b16812 100644 --- a/ui/app_list/vector_icons/ic_search.icon +++ b/ui/app_list/vector_icons/ic_search.icon
@@ -23,5 +23,4 @@ CUBIC_TO, 7.97f, 10.96f, 10.96f, 7.97f, 14.66f, 7.97f, CUBIC_TO, 18.36f, 7.97f, 21.35f, 10.96f, 21.35f, 14.66f, CUBIC_TO, 21.35f, 18.36f, 18.36f, 21.35f, 14.66f, 21.35f, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_search_engine_not_google.1x.icon b/ui/app_list/vector_icons/ic_search_engine_not_google.1x.icon index 5606e25c..a0e8629d 100644 --- a/ui/app_list/vector_icons/ic_search_engine_not_google.1x.icon +++ b/ui/app_list/vector_icons/ic_search_engine_not_google.1x.icon
@@ -22,5 +22,4 @@ CUBIC_TO, 5, 7.01f, 7.01f, 5, 9.5f, 5, CUBIC_TO, 11.99f, 5, 14, 7.01f, 14, 9.5f, CUBIC_TO, 14, 11.99f, 11.99f, 14, 9.5f, 14, -CLOSE, -END +CLOSE
diff --git a/ui/app_list/vector_icons/ic_search_engine_not_google.icon b/ui/app_list/vector_icons/ic_search_engine_not_google.icon index 3fd6c52c..4577140 100644 --- a/ui/app_list/vector_icons/ic_search_engine_not_google.icon +++ b/ui/app_list/vector_icons/ic_search_engine_not_google.icon
@@ -21,5 +21,4 @@ CUBIC_TO, 10, 14.02f, 14.02f, 10, 19, 10, CUBIC_TO, 23.98f, 10, 28, 14.02f, 28, 19, CUBIC_TO, 28, 23.98f, 23.98f, 28, 19, 28, -CLOSE, -END +CLOSE
diff --git a/ui/events/keycodes/platform_key_map_win.cc b/ui/events/keycodes/platform_key_map_win.cc index d7ecacc..fd694a98 100644 --- a/ui/events/keycodes/platform_key_map_win.cc +++ b/ui/events/keycodes/platform_key_map_win.cc
@@ -279,7 +279,7 @@ // TODO(crbug.com/25503): Controls Control+Alt vs AltGraph disambiguation. const base::Feature kFixAltGraphModifier{"FixAltGraph", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; } // anonymous namespace
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index d268ffd..e0f776f 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -603,8 +603,6 @@ "image/image_unittest_util.h", "image/image_unittest_util_ios.mm", "image/image_unittest_util_mac.mm", - "test/fontconfig_util_linux.cc", - "test/fontconfig_util_linux.h", "test/gfx_util.cc", "test/gfx_util.h", "test/icc_profiles.cc", @@ -629,10 +627,6 @@ deps += [ "//third_party:freetype_harfbuzz" ] } - - if (is_linux) { - deps += [ "//third_party/fontconfig" ] - } } test("gfx_unittests") {
diff --git a/ui/gfx/font_render_params_linux_unittest.cc b/ui/gfx/font_render_params_linux_unittest.cc index 34732ed..583932f 100644 --- a/ui/gfx/font_render_params_linux_unittest.cc +++ b/ui/gfx/font_render_params_linux_unittest.cc
@@ -4,14 +4,16 @@ #include "ui/gfx/font_render_params.h" +#include <fontconfig/fontconfig.h> + #include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "base/macros.h" +#include "base/test/fontconfig_util_linux.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/font.h" #include "ui/gfx/linux_font_delegate.h" -#include "ui/gfx/test/fontconfig_util_linux.h" namespace gfx { @@ -60,7 +62,6 @@ class FontRenderParamsTest : public testing::Test { public: FontRenderParamsTest() { - SetUpFontconfig(); CHECK(temp_dir_.CreateUniqueTempDir()); original_font_delegate_ = LinuxFontDelegate::instance(); LinuxFontDelegate::SetInstance(&test_font_delegate_); @@ -70,7 +71,17 @@ ~FontRenderParamsTest() override { LinuxFontDelegate::SetInstance( const_cast<LinuxFontDelegate*>(original_font_delegate_)); - TearDownFontconfig(); + } + + void SetUp() override { + // Fontconfig should already be set up by the test runner. + DCHECK(FcConfigGetCurrent()); + } + + void TearDown() override { + // We might have made a mess introducing new fontconfig settings. Reset the + // state of fontconfig for the next test. + base::SetUpFontconfig(); } protected: @@ -83,7 +94,6 @@ }; TEST_F(FontRenderParamsTest, Default) { - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + @@ -91,36 +101,36 @@ // match (since this is the style generally used in // /etc/fonts/conf.d). kFontconfigMatchFontHeader + - CreateFontconfigEditStanza("antialias", "bool", "true") + - CreateFontconfigEditStanza("autohint", "bool", "true") + - CreateFontconfigEditStanza("hinting", "bool", "true") + - CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + - CreateFontconfigEditStanza("rgba", "const", "rgb") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigEditStanza("autohint", "bool", "true") + + base::CreateFontconfigEditStanza("hinting", "bool", "true") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + + base::CreateFontconfigEditStanza("rgba", "const", "rgb") + kFontconfigMatchFooter + // Add a font match for Arial. Since it specifies a family, it - // shouldn't - // take effect when querying default settings. + // shouldn't take effect when querying default settings. kFontconfigMatchFontHeader + - CreateFontconfigTestStanza("family", "eq", "string", "Arial") + - CreateFontconfigEditStanza("antialias", "bool", "true") + - CreateFontconfigEditStanza("autohint", "bool", "false") + - CreateFontconfigEditStanza("hinting", "bool", "true") + - CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + - CreateFontconfigEditStanza("rgba", "const", "none") + + base::CreateFontconfigTestStanza("family", "eq", "string", "Arial") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigEditStanza("autohint", "bool", "false") + + base::CreateFontconfigEditStanza("hinting", "bool", "true") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + + base::CreateFontconfigEditStanza("rgba", "const", "none") + kFontconfigMatchFooter + // Add font matches for fonts between 10 and 20 points or pixels. - // Since - // they specify sizes, they also should not affect the defaults. + // Since they specify sizes, they also should not affect the defaults. kFontconfigMatchFontHeader + - CreateFontconfigTestStanza("size", "more_eq", "double", "10.0") + - CreateFontconfigTestStanza("size", "less_eq", "double", "20.0") + - CreateFontconfigEditStanza("antialias", "bool", "false") + + base::CreateFontconfigTestStanza("size", "more_eq", "double", + "10.0") + + base::CreateFontconfigTestStanza("size", "less_eq", "double", + "20.0") + + base::CreateFontconfigEditStanza("antialias", "bool", "false") + kFontconfigMatchFooter + kFontconfigMatchFontHeader + - CreateFontconfigTestStanza("pixel_size", "more_eq", "double", - "10.0") + - CreateFontconfigTestStanza("pixel_size", "less_eq", "double", - "20.0") + - CreateFontconfigEditStanza("antialias", "bool", "false") + + base::CreateFontconfigTestStanza("pixel_size", "more_eq", "double", + "10.0") + + base::CreateFontconfigTestStanza("pixel_size", "less_eq", "double", + "20.0") + + base::CreateFontconfigEditStanza("antialias", "bool", "false") + kFontconfigMatchFooter + kFontconfigFileFooter)); FontRenderParams params = GetFontRenderParams( @@ -135,21 +145,21 @@ } TEST_F(FontRenderParamsTest, Size) { - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); - ASSERT_TRUE(LoadConfigDataIntoFontconfig( + ASSERT_TRUE(base::LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("antialias", "bool", "true") + - CreateFontconfigEditStanza("hinting", "bool", "true") + - CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + - CreateFontconfigEditStanza("rgba", "const", "none") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigEditStanza("hinting", "bool", "true") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + + base::CreateFontconfigEditStanza("rgba", "const", "none") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") + - CreateFontconfigEditStanza("antialias", "bool", "false") + + base::CreateFontconfigTestStanza("pixelsize", "less_eq", "double", + "10") + + base::CreateFontconfigEditStanza("antialias", "bool", "false") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("size", "more_eq", "double", "20") + - CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + - CreateFontconfigEditStanza("rgba", "const", "rgb") + + base::CreateFontconfigTestStanza("size", "more_eq", "double", "20") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + + base::CreateFontconfigEditStanza("rgba", "const", "rgb") + kFontconfigMatchFooter + kFontconfigFileFooter)); // The defaults should be used when the supplied size isn't matched by the @@ -179,22 +189,21 @@ } TEST_F(FontRenderParamsTest, Style) { - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); // Load a config that disables subpixel rendering for bold text and disables // hinting for italic text. ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("antialias", "bool", "true") + - CreateFontconfigEditStanza("hinting", "bool", "true") + - CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + - CreateFontconfigEditStanza("rgba", "const", "rgb") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigEditStanza("hinting", "bool", "true") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + + base::CreateFontconfigEditStanza("rgba", "const", "rgb") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("weight", "eq", "const", "bold") + - CreateFontconfigEditStanza("rgba", "const", "none") + + base::CreateFontconfigTestStanza("weight", "eq", "const", "bold") + + base::CreateFontconfigEditStanza("rgba", "const", "none") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("slant", "eq", "const", "italic") + - CreateFontconfigEditStanza("hinting", "bool", "false") + + base::CreateFontconfigTestStanza("slant", "eq", "const", "italic") + + base::CreateFontconfigEditStanza("hinting", "bool", "false") + kFontconfigMatchFooter + kFontconfigFileFooter)); FontRenderParamsQuery query; @@ -230,10 +239,10 @@ ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("antialias", "bool", "false") + + base::CreateFontconfigEditStanza("antialias", "bool", "false") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("scalable", "eq", "bool", "true") + - CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigTestStanza("scalable", "eq", "bool", "true") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + kFontconfigMatchFooter + kFontconfigFileFooter)); // Check that we specifically ask how scalable fonts should be rendered. @@ -243,15 +252,15 @@ } TEST_F(FontRenderParamsTest, UseBitmaps) { - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); // Load a config that enables embedded bitmaps for fonts <= 10 pixels. ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("embeddedbitmap", "bool", "false") + + base::CreateFontconfigEditStanza("embeddedbitmap", "bool", "false") + kFontconfigMatchFooter + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") + - CreateFontconfigEditStanza("embeddedbitmap", "bool", "true") + + base::CreateFontconfigTestStanza("pixelsize", "less_eq", "double", + "10") + + base::CreateFontconfigEditStanza("embeddedbitmap", "bool", "true") + kFontconfigMatchFooter + kFontconfigFileFooter)); FontRenderParamsQuery query; @@ -269,10 +278,10 @@ ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("antialias", "bool", "false") + - CreateFontconfigEditStanza("hinting", "bool", "false") + - CreateFontconfigEditStanza("hintstyle", "const", "hintnone") + - CreateFontconfigEditStanza("rgba", "const", "rgb") + + base::CreateFontconfigEditStanza("antialias", "bool", "false") + + base::CreateFontconfigEditStanza("hinting", "bool", "false") + + base::CreateFontconfigEditStanza("hintstyle", "const", "hintnone") + + base::CreateFontconfigEditStanza("rgba", "const", "rgb") + kFontconfigMatchFooter + kFontconfigFileFooter)); // Full hinting should be forced. See the comment in GetFontRenderParams() for @@ -318,7 +327,7 @@ ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + kFontconfigMatchPatternHeader + - CreateFontconfigEditStanza("antialias", "bool", "true") + + base::CreateFontconfigEditStanza("antialias", "bool", "true") + kFontconfigMatchFooter + kFontconfigFileFooter)); // The subpixel rendering setting from the delegate should make it through. @@ -328,7 +337,9 @@ } TEST_F(FontRenderParamsTest, NoFontconfigMatch) { - // Don't load a Fontconfig configuration. + // A default configuration was set up globally. Reset it to a blank config. + FcConfigSetCurrent(FcConfigCreate()); + FontRenderParams system_params; system_params.antialiasing = true; system_params.hinting = FontRenderParams::HINTING_MEDIUM; @@ -352,8 +363,6 @@ TEST_F(FontRenderParamsTest, MissingFamily) { // With Arial and Verdana installed, request (in order) Helvetica, Arial, and // Verdana and check that Arial is returned. - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); - ASSERT_TRUE(LoadSystemFontIntoFontconfig("verdana.ttf")); FontRenderParamsQuery query; query.families.push_back("Helvetica"); query.families.push_back("Arial"); @@ -365,15 +374,13 @@ TEST_F(FontRenderParamsTest, SubstituteFamily) { // Configure Fontconfig to use Verdana for both Helvetica and Arial. - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); - ASSERT_TRUE(LoadSystemFontIntoFontconfig("verdana.ttf")); ASSERT_TRUE(LoadConfigDataIntoFontconfig( temp_dir_.GetPath(), std::string(kFontconfigFileHeader) + - CreateFontconfigAliasStanza("Helvetica", "Verdana") + + base::CreateFontconfigAliasStanza("Helvetica", "Verdana") + kFontconfigMatchPatternHeader + - CreateFontconfigTestStanza("family", "eq", "string", "Arial") + - CreateFontconfigEditStanza("family", "string", "Verdana") + + base::CreateFontconfigTestStanza("family", "eq", "string", "Arial") + + base::CreateFontconfigEditStanza("family", "string", "Verdana") + kFontconfigMatchFooter + kFontconfigFileFooter)); FontRenderParamsQuery query;
diff --git a/ui/gfx/paint_vector_icon.cc b/ui/gfx/paint_vector_icon.cc index 2669ca3..171bc56 100644 --- a/ui/gfx/paint_vector_icon.cc +++ b/ui/gfx/paint_vector_icon.cc
@@ -42,12 +42,14 @@ // Helper that simplifies iterating over a sequence of PathElements. class PathParser { public: - PathParser(const PathElement* path_elements) - : path_elements_(path_elements) {} + PathParser(const PathElement* path_elements, size_t path_size) + : path_elements_(path_elements), path_size_(path_size) {} ~PathParser() {} void Advance() { command_index_ += GetArgumentCount() + 1; } + bool HasCommandsRemaining() const { return command_index_ < path_size_; } + CommandType CurrentCommand() const { return path_elements_[command_index_].command; } @@ -103,7 +105,6 @@ case FLIPS_IN_RTL: case TRANSITION_FROM: case TRANSITION_TO: - case END: return 0; } @@ -112,7 +113,8 @@ } const PathElement* path_elements_; - int command_index_ = 0; + size_t path_size_; + size_t command_index_ = 0; DISALLOW_COPY_AND_ASSIGN(PathParser); }; @@ -149,7 +151,6 @@ RETURN_IF_IS(CLIP); RETURN_IF_IS(DISABLE_AA); RETURN_IF_IS(FLIPS_IN_RTL); - RETURN_IF_IS(END); #undef RETURN_IF_IS NOTREACHED() << "Unrecognized command: " << source; @@ -175,6 +176,7 @@ void PaintPath(Canvas* canvas, const PathElement* path_elements, + size_t path_size, int dip_size, SkColor color, const base::TimeDelta& elapsed_time) { @@ -188,8 +190,8 @@ bool flips_in_rtl = false; CommandType previous_command_type = NEW_PATH; - for (PathParser parser(path_elements); parser.CurrentCommand() != END; - parser.Advance()) { + for (PathParser parser(path_elements, path_size); + parser.HasCommandsRemaining(); parser.Advance()) { auto arg = [&parser](int i) { return parser.GetArgument(i); }; const CommandType command_type = parser.CurrentCommand(); auto start_new_path = [&paths]() { @@ -430,10 +432,6 @@ flags_array.pop_back(); break; } - - case END: - NOTREACHED(); - break; } previous_command_type = command_type; @@ -481,7 +479,7 @@ if (!data_.badge_icon.is_empty()) PaintVectorIcon(canvas, data_.badge_icon, size_.width(), data_.color); } else { - PaintPath(canvas, path_.data(), size_.width(), data_.color, + PaintPath(canvas, path_.data(), path_.size(), size_.width(), data_.color, base::TimeDelta()); } } @@ -562,20 +560,13 @@ SkColor color, const base::TimeDelta& elapsed_time) { DCHECK(!icon.is_empty()); - if (icon.rep) { + if (icon.rep) DCHECK(icon.rep->path_size > 0); - DCHECK_EQ(END, icon.rep->path[icon.rep->path_size - 1].command) - << icon.name; - } - if (icon.rep_1x) { + if (icon.rep_1x) DCHECK(icon.rep_1x->path_size > 0); - DCHECK_EQ(END, icon.rep_1x->path[icon.rep_1x->path_size - 1].command) - << icon.name; - } - const PathElement* path = (canvas->image_scale() == 1.f && icon.rep_1x) - ? icon.rep_1x->path - : icon.rep->path; - PaintPath(canvas, path, dip_size, color, elapsed_time); + const VectorIconRep* rep = + (canvas->image_scale() == 1.f && icon.rep_1x) ? icon.rep_1x : icon.rep; + PaintPath(canvas, rep->path, rep->path_size, dip_size, color, elapsed_time); } ImageSkia CreateVectorIcon(const IconDescription& params) { @@ -620,8 +611,8 @@ base::TimeDelta GetDurationOfAnimation(const VectorIcon& icon) { base::TimeDelta last_motion; - for (PathParser parser(icon.rep->path); parser.CurrentCommand() != END; - parser.Advance()) { + for (PathParser parser(icon.rep->path, icon.rep->path_size); + parser.HasCommandsRemaining(); parser.Advance()) { if (parser.CurrentCommand() != TRANSITION_END) continue;
diff --git a/ui/gfx/paint_vector_icon_unittest.cc b/ui/gfx/paint_vector_icon_unittest.cc index 3b5a9f4c..1188c35e 100644 --- a/ui/gfx/paint_vector_icon_unittest.cc +++ b/ui/gfx/paint_vector_icon_unittest.cc
@@ -43,14 +43,9 @@ Canvas canvas(recorder.beginRecording(100, 100), 1.0f); const PathElement elements[] = { - MOVE_TO, 4, 5, - LINE_TO, 10, 11, - CLOSE, + MOVE_TO, 4, 5, LINE_TO, 10, 11, CLOSE, // This move should use (4, 5) as the start point rather than (10, 11). - R_MOVE_TO, 20, 21, - R_LINE_TO, 50, 51, - END, - }; + R_MOVE_TO, 20, 21, R_LINE_TO, 50, 51}; const VectorIconRep icon_rep = {elements, arraysize(elements)}; const VectorIcon icon = {&icon_rep}; @@ -79,16 +74,19 @@ // Create a 20x20 square icon which has FLIPS_IN_RTL, and CANVAS_DIMENSIONS // are twice as large as |canvas|. - const PathElement elements[] = { - CANVAS_DIMENSIONS, 2 * canvas_size, - FLIPS_IN_RTL, - MOVE_TO, 10, 10, - R_H_LINE_TO, 20, - R_V_LINE_TO, 20, - R_H_LINE_TO, -20, - CLOSE, - END, - }; + const PathElement elements[] = {CANVAS_DIMENSIONS, + 2 * canvas_size, + FLIPS_IN_RTL, + MOVE_TO, + 10, + 10, + R_H_LINE_TO, + 20, + R_V_LINE_TO, + 20, + R_H_LINE_TO, + -20, + CLOSE}; const VectorIconRep icon_rep = {elements, arraysize(elements)}; const VectorIcon icon = {&icon_rep}; PaintVectorIcon(&canvas, icon, canvas_size, color);
diff --git a/ui/gfx/platform_font_linux_unittest.cc b/ui/gfx/platform_font_linux_unittest.cc index f677ba4..3953a6a 100644 --- a/ui/gfx/platform_font_linux_unittest.cc +++ b/ui/gfx/platform_font_linux_unittest.cc
@@ -13,7 +13,6 @@ #include "ui/gfx/font.h" #include "ui/gfx/font_render_params.h" #include "ui/gfx/linux_font_delegate.h" -#include "ui/gfx/test/fontconfig_util_linux.h" namespace gfx { @@ -62,7 +61,6 @@ class PlatformFontLinuxTest : public testing::Test { public: PlatformFontLinuxTest() { - SetUpFontconfig(); original_font_delegate_ = LinuxFontDelegate::instance(); LinuxFontDelegate::SetInstance(&test_font_delegate_); } @@ -71,7 +69,6 @@ LinuxFontDelegate::SetInstance( const_cast<LinuxFontDelegate*>(original_font_delegate_)); PlatformFontLinux::ReloadDefaultFont(); - TearDownFontconfig(); } protected: @@ -87,9 +84,6 @@ // Test that PlatformFontLinux's default constructor initializes the instance // with the correct parameters. TEST_F(PlatformFontLinuxTest, DefaultFont) { - ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf")); - ASSERT_TRUE(LoadSystemFontIntoFontconfig("times_new_roman.ttf")); - #if defined(OS_CHROMEOS) PlatformFontLinux::SetDefaultFontDescription("Arial,Times New Roman,13px"); #else
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index ee8ac5b..7c1fcfdd 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -4369,13 +4369,13 @@ } { SCOPED_TRACE("TextDoesntClip Left Side"); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) || \ +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) || \ defined(ARCH_CPU_MIPS_FAMILY) - // TODO(dschuyler): On Windows, Chrome OS, and Mac smoothing draws to the - // left of text. This appears to be a preexisting issue that wasn't - // revealed by the prior unit tests. RenderText currently only uses - // origins and advances and ignores bounding boxes so cannot account for - // under- and over-hang. + // TODO(dschuyler): On Windows, Chrome OS, Linux, and Mac smoothing draws + // to the left of text. This appears to be a preexisting issue that + // wasn't revealed by the prior unit tests. RenderText currently only + // uses origins and advances and ignores bounding boxes so cannot account + // for under- and over-hang. rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize, kTestSize - 1, string_size.height()); #else @@ -4385,13 +4385,13 @@ } { SCOPED_TRACE("TextDoesntClip Right Side"); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) || \ +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) || \ defined(ARCH_CPU_MIPS_FAMILY) - // TODO(dschuyler): On Windows, Chrome OS, and Mac smoothing draws to the - // right of text. This appears to be a preexisting issue that wasn't - // revealed by the prior unit tests. RenderText currently only uses - // origins and advances and ignores bounding boxes so cannot account for - // under- and over-hang. + // TODO(dschuyler): On Windows, Chrome OS, Linux, and Mac smoothing draws + // to the right of text. This appears to be a preexisting issue that + // wasn't revealed by the prior unit tests. RenderText currently only + // uses origins and advances and ignores bounding boxes so cannot account + // for under- and over-hang. rect_buffer.EnsureSolidRect(SK_ColorWHITE, kTestSize + string_size.width() + 1, kTestSize, kTestSize - 1,
diff --git a/ui/gfx/test/fontconfig_util_linux.cc b/ui/gfx/test/fontconfig_util_linux.cc deleted file mode 100644 index 4afd735..0000000 --- a/ui/gfx/test/fontconfig_util_linux.cc +++ /dev/null
@@ -1,193 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/test/fontconfig_util_linux.h" - -#include <fontconfig/fontconfig.h> - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" - -namespace gfx { - -const char* const kSystemFontsForFontconfig[] = { - "/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf", - "/usr/share/fonts/opentype/ipafont-gothic/ipagp.ttf", - "/usr/share/fonts/opentype/ipafont-mincho/ipam.ttf", - "/usr/share/fonts/opentype/ipafont-mincho/ipamp.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Arial_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Courier_New.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Georgia_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Impact.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold_Italic.ttf", - "/usr/share/fonts/truetype/msttcorefonts/Verdana_Italic.ttf", -}; - -const size_t kNumSystemFontsForFontconfig = - arraysize(kSystemFontsForFontconfig); - -const char* const kCloudStorageSyncedFonts[] = { - // The DejaVuSans font is used by the css2.1 tests. - "DejaVuSans.ttf", - "Garuda.ttf", - "Lohit-Devanagari.ttf", - "Lohit-Tamil.ttf", - "Lohit-Gurmukhi.ttf", - "MuktiNarrow.ttf", - "NotoSansCJKjp-Regular.otf", - "NotoSansKhmer-Regular.ttf"}; - -const size_t kNumCloudStorageSyncedFonts = arraysize(kCloudStorageSyncedFonts); - -void SetUpFontconfig() { - FcInit(); - - // A primer on undocumented FcConfig reference-counting: - // - // - FcConfigCreate() creates a config with a refcount of 1. - // - FcConfigReference() increments a config's refcount. - // - FcConfigDestroy() decrements a config's refcount, deallocating the - // config when the count reaches 0. - // - FcConfigSetCurrent() calls FcConfigDestroy() on the old config, and - // calls FcConfigReference() on the new config. - FcConfig* config = FcConfigCreate(); - FcConfigBuildFonts(config); - CHECK(FcConfigSetCurrent(config)); -} - -void TearDownFontconfig() { - FcFini(); -} - -bool LoadFontIntoFontconfig(const base::FilePath& path) { - if (!base::PathExists(path)) { - LOG(ERROR) << "You are missing " << path.value() << ". Try re-running " - << "build/install-build-deps.sh. " - << "Please make sure that " - << "third_party/content_shell_fonts/ has downloaded " - << "and extracted the content_shell_test_fonts." - << "Also see " - << "https://chromium.googlesource.com/chromium/src/+/master/" - << "docs/layout_tests_linux.md"; - return false; - } - - if (!FcConfigAppFontAddFile( - NULL, reinterpret_cast<const FcChar8*>(path.value().c_str()))) { - LOG(ERROR) << "Failed to load font " << path.value(); - return false; - } - - return true; -} - -bool LoadSystemFontIntoFontconfig(const std::string& basename) { - for (size_t i = 0; i < kNumSystemFontsForFontconfig; ++i) { - base::FilePath path(kSystemFontsForFontconfig[i]); - if (base::EqualsCaseInsensitiveASCII(path.BaseName().value(), basename)) - return LoadFontIntoFontconfig(path); - } - LOG(ERROR) << "Unable to find system font named " << basename; - return false; -} - -bool LoadCloudStorageSyncedFontIntoFontConfig(const std::string& fontfilename) { - base::FilePath content_shell_test_fonts_path; - PathService::Get(base::DIR_MODULE, &content_shell_test_fonts_path); - // See third_party/content_shell_test_fonts/ for information how these fonts - // are synced. Target directory out/<buildDir>/content_shell_test_fonts needs - // to match what is specified as the target in - // third_party/content_shell_test_fonts/BUILD.gn as output directory. - base::FilePath font_file_path = - content_shell_test_fonts_path - .Append(FILE_PATH_LITERAL("content_shell_test_fonts")) - .Append(FILE_PATH_LITERAL(fontfilename)); - return LoadFontIntoFontconfig(font_file_path); -} - -bool LoadConfigFileIntoFontconfig(const base::FilePath& path) { - // Unlike other FcConfig functions, FcConfigParseAndLoad() doesn't default to - // the current config when passed NULL. So that's cool. - if (!FcConfigParseAndLoad(FcConfigGetCurrent(), - reinterpret_cast<const FcChar8*>(path.value().c_str()), FcTrue)) { - LOG(ERROR) << "Fontconfig failed to load " << path.value(); - return false; - } - return true; -} - -bool LoadConfigDataIntoFontconfig(const base::FilePath& temp_dir, - const std::string& data) { - base::FilePath path; - if (!CreateTemporaryFileInDir(temp_dir, &path)) { - PLOG(ERROR) << "Unable to create temporary file in " << temp_dir.value(); - return false; - } - if (base::WriteFile(path, data.data(), data.size()) != - static_cast<int>(data.size())) { - PLOG(ERROR) << "Unable to write config data to " << path.value(); - return false; - } - return LoadConfigFileIntoFontconfig(path); -} - -std::string CreateFontconfigEditStanza(const std::string& name, - const std::string& type, - const std::string& value) { - return base::StringPrintf( - " <edit name=\"%s\" mode=\"assign\">\n" - " <%s>%s</%s>\n" - " </edit>\n", - name.c_str(), type.c_str(), value.c_str(), type.c_str()); -} - -std::string CreateFontconfigTestStanza(const std::string& name, - const std::string& op, - const std::string& type, - const std::string& value) { - return base::StringPrintf( - " <test name=\"%s\" compare=\"%s\" qual=\"any\">\n" - " <%s>%s</%s>\n" - " </test>\n", - name.c_str(), op.c_str(), type.c_str(), value.c_str(), type.c_str()); -} - -std::string CreateFontconfigAliasStanza(const std::string& original_family, - const std::string& preferred_family) { - return base::StringPrintf( - " <alias>\n" - " <family>%s</family>\n" - " <prefer><family>%s</family></prefer>\n" - " </alias>\n", - original_family.c_str(), preferred_family.c_str()); -} - -} // namespace gfx
diff --git a/ui/gfx/test/fontconfig_util_linux.h b/ui/gfx/test/fontconfig_util_linux.h deleted file mode 100644 index 96dfed7..0000000 --- a/ui/gfx/test/fontconfig_util_linux.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GFX_TEST_FONTCONFIG_UTIL_LINUX_H_ -#define UI_GFX_TEST_FONTCONFIG_UTIL_LINUX_H_ - -#include <stddef.h> - -#include <string> - -namespace base { -class FilePath; -} - -namespace gfx { - -// Array of paths to font files that are expected to exist on machines where -// tests are run. -extern const char* const kSystemFontsForFontconfig[]; -extern const size_t kNumSystemFontsForFontconfig; - -extern const char* const kCloudStorageSyncedFonts[]; -extern const size_t kNumCloudStorageSyncedFonts; - -// Initializes Fontconfig and creates and swaps in a new, empty config. -void SetUpFontconfig(); - -// Deinitializes Fontconfig. -void TearDownFontconfig(); - -// Loads the font file at |path| into the current config, returning true on -// success. -bool LoadFontIntoFontconfig(const base::FilePath& path); - -// Loads the first system font in kSystemFontsForFontconfig with a base filename -// of |basename|. Case is ignored. FcFontMatch() requires there to be at least -// one font present. -bool LoadSystemFontIntoFontconfig(const std::string& basename); - -// Loads a font named by |fontfilename|, taken from kCloudStorageSyncedFonts -// into the current config. Returns true on success, false if the font cannot be -// found from the set of cloud synced fonts. -bool LoadCloudStorageSyncedFontIntoFontConfig(const std::string& fontfilename); - -// Instructs Fontconfig to load |path|, an XML configuration file, into the -// current config, returning true on success. -bool LoadConfigFileIntoFontconfig(const base::FilePath& path); - -// Writes |data| to a file in |temp_dir| and passes it to -// LoadConfigFileIntoFontconfig(). -bool LoadConfigDataIntoFontconfig(const base::FilePath& temp_dir, - const std::string& data); - -// Returns a Fontconfig <edit> stanza. -std::string CreateFontconfigEditStanza(const std::string& name, - const std::string& type, - const std::string& value); - -// Returns a Fontconfig <test> stanza. -std::string CreateFontconfigTestStanza(const std::string& name, - const std::string& op, - const std::string& type, - const std::string& value); - -// Returns a Fontconfig <alias> stanza. -std::string CreateFontconfigAliasStanza(const std::string& original_family, - const std::string& preferred_family); - -} // namespace gfx - -#endif // UI_GFX_TEST_FONTCONFIG_UTIL_LINUX_H_
diff --git a/ui/gfx/vector_icon_types.h b/ui/gfx/vector_icon_types.h index e5f14b1..e03aa126 100644 --- a/ui/gfx/vector_icon_types.h +++ b/ui/gfx/vector_icon_types.h
@@ -63,9 +63,6 @@ // Parameters are delay (ms), duration (ms), and tween type // (gfx::Tween::Type). TRANSITION_END, - // Marks the end of the list of commands. TODO(estade): remove this sentinel - // value and rely on VectorIcon::path_size. - END }; // A POD that describes either a path command or an argument for it.
diff --git a/ui/gl/gl_image_ahardwarebuffer.h b/ui/gl/gl_image_ahardwarebuffer.h index b3ebd04..3170e0f 100644 --- a/ui/gl/gl_image_ahardwarebuffer.h +++ b/ui/gl/gl_image_ahardwarebuffer.h
@@ -6,6 +6,7 @@ #define UI_GL_GL_IMAGE_AHARDWAREBUFFER_H_ #include "base/macros.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_export.h" #include "ui/gl/gl_image_egl.h"
diff --git a/ui/gl/gl_image_egl.h b/ui/gl/gl_image_egl.h index b32e948..e014dc7 100644 --- a/ui/gl/gl_image_egl.h +++ b/ui/gl/gl_image_egl.h
@@ -5,9 +5,10 @@ #ifndef UI_GL_GL_IMAGE_EGL_H_ #define UI_GL_GL_IMAGE_EGL_H_ +#include <EGL/eglplatform.h> + #include "base/macros.h" #include "base/threading/thread_checker.h" -#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_export.h" #include "ui/gl/gl_image.h" @@ -35,12 +36,12 @@ // it is required to pass EGL_NO_CONTEXT. This allows to create an EGLImage // from an external resource. Then this EGLImage can be converted to a GL // texture. - bool Initialize(EGLContext context, - EGLenum target, - EGLClientBuffer buffer, + bool Initialize(void* context /* EGLContext */, + unsigned target /* EGLenum */, + void* buffer /* EGLClientBuffer */, const EGLint* attrs); - EGLImageKHR egl_image_; + void* egl_image_ /* EGLImageKHR */; const gfx::Size size_; base::ThreadChecker thread_checker_;
diff --git a/ui/gl/gl_image_native_pixmap_unittest.cc b/ui/gl/gl_image_native_pixmap_unittest.cc index 99a852db..a8639cb 100644 --- a/ui/gl/gl_image_native_pixmap_unittest.cc +++ b/ui/gl/gl_image_native_pixmap_unittest.cc
@@ -4,6 +4,7 @@ #include "ui/gl/gl_image_native_pixmap.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/test/gl_image_test_template.h" namespace gl {
diff --git a/ui/message_center/vector_icons/notification_close_button.1x.icon b/ui/message_center/vector_icons/notification_close_button.1x.icon index 2bea75d..8df1cab 100644 --- a/ui/message_center/vector_icons/notification_close_button.1x.icon +++ b/ui/message_center/vector_icons/notification_close_button.1x.icon
@@ -15,5 +15,4 @@ LINE_TO, 9.64f, 10.5f, LINE_TO, 10.5f, 9.64f, LINE_TO, 6.86f, 6, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/notification_close_button.icon b/ui/message_center/vector_icons/notification_close_button.icon index 5ce70e4..37b056a 100644 --- a/ui/message_center/vector_icons/notification_close_button.icon +++ b/ui/message_center/vector_icons/notification_close_button.icon
@@ -15,5 +15,4 @@ LINE_TO, 18.27f, 20, LINE_TO, 20, 18.27f, LINE_TO, 13.73f, 12, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/notification_expand_less.icon b/ui/message_center/vector_icons/notification_expand_less.icon index b30ee42..d15fce2a 100644 --- a/ui/message_center/vector_icons/notification_expand_less.icon +++ b/ui/message_center/vector_icons/notification_expand_less.icon
@@ -9,5 +9,4 @@ LINE_TO, 15, 11.31f, R_LINE_TO, -7, -6.89f, R_LINE_TO, -7, 6.89f, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/notification_expand_more.icon b/ui/message_center/vector_icons/notification_expand_more.icon index b779f5f..155f6b5 100644 --- a/ui/message_center/vector_icons/notification_expand_more.icon +++ b/ui/message_center/vector_icons/notification_expand_more.icon
@@ -9,5 +9,4 @@ LINE_TO, 15, 4.69f, R_LINE_TO, -7, 6.89f, R_LINE_TO, -7, -6.89f, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/notification_inline_reply.icon b/ui/message_center/vector_icons/notification_inline_reply.icon index e1286993..abb71d49 100644 --- a/ui/message_center/vector_icons/notification_inline_reply.icon +++ b/ui/message_center/vector_icons/notification_inline_reply.icon
@@ -9,5 +9,4 @@ LINE_TO, 10, 40.44f, LINE_TO, 64.29f, 48, LINE_TO, 10, 55.56f, -CLOSE, -END \ No newline at end of file +CLOSE
diff --git a/ui/message_center/vector_icons/notification_settings_button.1x.icon b/ui/message_center/vector_icons/notification_settings_button.1x.icon index d999691..8d4a4971 100644 --- a/ui/message_center/vector_icons/notification_settings_button.1x.icon +++ b/ui/message_center/vector_icons/notification_settings_button.1x.icon
@@ -50,5 +50,4 @@ CUBIC_TO, 6.83f, 4.5f, 7.5f, 5.17f, 7.5f, 6, CUBIC_TO, 7.5f, 6.83f, 6.83f, 7.5f, 6, 7.5f, LINE_TO, 6, 7.5f, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/notification_settings_button.icon b/ui/message_center/vector_icons/notification_settings_button.icon index ae7e26a..2f312ea9 100644 --- a/ui/message_center/vector_icons/notification_settings_button.icon +++ b/ui/message_center/vector_icons/notification_settings_button.icon
@@ -50,5 +50,4 @@ CUBIC_TO, 13.66f, 9, 15, 10.34f, 15, 12, CUBIC_TO, 15, 13.66f, 13.66f, 15, 12, 15, LINE_TO, 12, 15, -CLOSE, -END +CLOSE
diff --git a/ui/message_center/vector_icons/product.icon b/ui/message_center/vector_icons/product.icon index 97f8448b..7068cb2 100644 --- a/ui/message_center/vector_icons/product.icon +++ b/ui/message_center/vector_icons/product.icon
@@ -32,5 +32,4 @@ R_CUBIC_TO, 0, -7.73f, 6.27f, -14, 14, -14, R_CUBIC_TO, 7.73f, 0, 14, 6.27f, 14, 14, R_CUBIC_TO, 0, 7.73f, -6.27f, 14, -14, 14, -CLOSE, -END +CLOSE
diff --git a/ui/ozone/platform/headless/BUILD.gn b/ui/ozone/platform/headless/BUILD.gn index 6de5730..0637f8e 100644 --- a/ui/ozone/platform/headless/BUILD.gn +++ b/ui/ozone/platform/headless/BUILD.gn
@@ -20,6 +20,8 @@ "ozone_platform_headless.h", ] + defines = [ "OZONE_IMPLEMENTATION" ] + deps = [ "//base", "//skia",
diff --git a/ui/views/vector_icons/checkbox_active.icon b/ui/views/vector_icons/checkbox_active.icon index 199c3fd9..d9ffe03 100644 --- a/ui/views/vector_icons/checkbox_active.icon +++ b/ui/views/vector_icons/checkbox_active.icon
@@ -23,6 +23,4 @@ LINE_TO, 6.5f, 9, LINE_TO, 11.5f, 4.5f, LINE_TO, 12.5f, 5.5f, -CLOSE, - -END +CLOSE
diff --git a/ui/views/vector_icons/checkbox_normal.icon b/ui/views/vector_icons/checkbox_normal.icon index 0b1efe5..8ea38e01 100644 --- a/ui/views/vector_icons/checkbox_normal.icon +++ b/ui/views/vector_icons/checkbox_normal.icon
@@ -22,6 +22,4 @@ V_LINE_TO, 3.004f, CUBIC_TO, 14, 2.449f, 13.551f, 2, 12.996f, 2, LINE_TO, 12.996f, 2, -CLOSE, - -END +CLOSE
diff --git a/ui/views/vector_icons/menu_check.1x.icon b/ui/views/vector_icons/menu_check.1x.icon index 739f668..18d76177 100644 --- a/ui/views/vector_icons/menu_check.1x.icon +++ b/ui/views/vector_icons/menu_check.1x.icon
@@ -10,5 +10,4 @@ R_LINE_TO, 1.35f, 1.39f, R_LINE_TO, -8.55f, 8.78f, LINE_TO, 2, 9.22f, -CLOSE, -END +CLOSE
diff --git a/ui/views/vector_icons/menu_check.icon b/ui/views/vector_icons/menu_check.icon index c06a2cc..46f105a 100644 --- a/ui/views/vector_icons/menu_check.icon +++ b/ui/views/vector_icons/menu_check.icon
@@ -10,5 +10,4 @@ LINE_TO, 28, 9.59f, LINE_TO, 12.02f, 26, LINE_TO, 5, 18.78f, -CLOSE, -END +CLOSE
diff --git a/ui/views/vector_icons/menu_radio_empty.icon b/ui/views/vector_icons/menu_radio_empty.icon index 62ef2daec..047257b4 100644 --- a/ui/views/vector_icons/menu_radio_empty.icon +++ b/ui/views/vector_icons/menu_radio_empty.icon
@@ -4,5 +4,4 @@ CANVAS_DIMENSIONS, 32, CIRCLE, 16, 16, 14, -CIRCLE, 16, 16, 11, -END +CIRCLE, 16, 16, 11
diff --git a/ui/views/vector_icons/menu_radio_selected.icon b/ui/views/vector_icons/menu_radio_selected.icon index 0533b99b..5f94564c 100644 --- a/ui/views/vector_icons/menu_radio_selected.icon +++ b/ui/views/vector_icons/menu_radio_selected.icon
@@ -5,5 +5,4 @@ CANVAS_DIMENSIONS, 32, CIRCLE, 16, 16, 14, CIRCLE, 16, 16, 11, -CIRCLE, 16, 16, 7, -END +CIRCLE, 16, 16, 7
diff --git a/ui/views/vector_icons/radio_button_active.icon b/ui/views/vector_icons/radio_button_active.icon index 0533b99b..5f94564c 100644 --- a/ui/views/vector_icons/radio_button_active.icon +++ b/ui/views/vector_icons/radio_button_active.icon
@@ -5,5 +5,4 @@ CANVAS_DIMENSIONS, 32, CIRCLE, 16, 16, 14, CIRCLE, 16, 16, 11, -CIRCLE, 16, 16, 7, -END +CIRCLE, 16, 16, 7
diff --git a/ui/views/vector_icons/radio_button_normal.icon b/ui/views/vector_icons/radio_button_normal.icon index 62ef2daec..047257b4 100644 --- a/ui/views/vector_icons/radio_button_normal.icon +++ b/ui/views/vector_icons/radio_button_normal.icon
@@ -4,5 +4,4 @@ CANVAS_DIMENSIONS, 32, CIRCLE, 16, 16, 14, -CIRCLE, 16, 16, 11, -END +CIRCLE, 16, 16, 11
diff --git a/ui/views/vector_icons/submenu_arrow.1x.icon b/ui/views/vector_icons/submenu_arrow.1x.icon index c964eee..823fd4d 100644 --- a/ui/views/vector_icons/submenu_arrow.1x.icon +++ b/ui/views/vector_icons/submenu_arrow.1x.icon
@@ -8,5 +8,4 @@ R_LINE_TO, 5, -4, R_LINE_TO, -5, -4, R_V_LINE_TO, 8, -CLOSE, -END +CLOSE
diff --git a/ui/views/vector_icons/submenu_arrow.icon b/ui/views/vector_icons/submenu_arrow.icon index 2ebf8a3..74b764c 100644 --- a/ui/views/vector_icons/submenu_arrow.icon +++ b/ui/views/vector_icons/submenu_arrow.icon
@@ -8,5 +8,4 @@ R_LINE_TO, 11, -8, LINE_TO, 3, 0, R_V_LINE_TO, 16, -CLOSE, -END +CLOSE
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 1f9b269..cde45a41 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -72,8 +72,6 @@ namespace { -bool g_disable_activation_change_handling_ = false; - // This class provides functionality to create a top level widget to host a // child window. class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver { @@ -238,11 +236,6 @@ NULL; wm::CursorManager* DesktopNativeWidgetAura::cursor_manager_ = NULL; -// static -void DesktopNativeWidgetAura::DisableActivationChangeHandlingForTests() { - g_disable_activation_change_handling_ = true; -} - DesktopNativeWidgetAura::DesktopNativeWidgetAura( internal::NativeWidgetDelegate* delegate) : desktop_window_tree_host_(NULL), @@ -355,9 +348,6 @@ } void DesktopNativeWidgetAura::HandleActivationChanged(bool active) { - if (g_disable_activation_change_handling_) - return; - native_widget_delegate_->OnNativeWidgetActivationChanged(active); wm::ActivationClient* activation_client = wm::GetActivationClient(host_->window());
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 73b6a006..812a37da 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -100,10 +100,6 @@ // Overridden from internal::NativeWidgetPrivate: gfx::NativeWindow GetNativeWindow() const override; - // Forces HandleActivationChanged to do nothing, making Chrome-internal notion - // of focused and active windows independent from the OS. - static void DisableActivationChangeHandlingForTests(); - protected: // Overridden from internal::NativeWidgetPrivate: void InitNativeWidget(const Widget::InitParams& params) override;