diff --git a/DEPS b/DEPS index 00ef99c..7645272 100644 --- a/DEPS +++ b/DEPS
@@ -185,7 +185,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'b28ca6f38f9b637fd639be49546867e07bcaa0ac', + 'v8_revision': '4cde67a85fd4c29f78551e5aebca1fc8912876e8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -201,7 +201,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': 'fcb6cd6d22a279c076217dcbb3154106fa5fd5d9', + 'pdfium_revision': 'c3e55aa23f888aaf9334a3fd35c1f49a3179869c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -252,7 +252,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'b5315e84d143e54e0238299709f208d36e4b4e57', + 'devtools_frontend_revision': '564dcf4c071b93382616e9421610aa2ac655a833', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -312,7 +312,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '3003aa622b2fc452a66707922b99a64f89b84bce', + 'dawn_revision': '80880ee9985484d39355d2827ce5cb9343a07e91', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -544,7 +544,7 @@ }, 'src/ios/third_party/material_font_disk_loader_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '93acc021e3034898716028822cb802a3a816be7e', + 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '8e30188777b016182658fbaa0a4a020a48183224', 'condition': 'checkout_ios', }, @@ -690,7 +690,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/aapt2', - 'version': 'TM6ESkOFwhdEwjsIxbY3m6j7BIhg8mpY_X9Pg0nwb1AC', + 'version': 'LKH_DI44rZhQ4RkScMFQLGSJ4jZyuPcff0llITnq-i4C', }, ], 'condition': 'checkout_android', @@ -1571,7 +1571,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8f5aa560c98d070293830e4a9272957f5428263e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6b41dac7d03098e0482bf9cafa84c60683d20372', 'condition': 'checkout_src_internal', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 9857a9f..f64714a 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1824,6 +1824,7 @@ "session/session_controller_impl_unittest.cc", "shelf/back_button_unittest.cc", "shelf/home_button_unittest.cc", + "shelf/hotseat_widget_unittest.cc", "shelf/login_shelf_view_unittest.cc", "shelf/scrollable_shelf_view_unittest.cc", "shelf/shelf_application_menu_model_unittest.cc",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 79edc96..9f9a7477 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -530,7 +530,7 @@ // Hide app list UI initially to prevent app list from flashing in background // while the initial app window is being shown. - if (!last_target_visible_) + if (!last_target_visible_ && !ShouldHomeLauncherBeVisible()) presenter_.SetViewVisibility(false); else OnVisibilityChanged(true, last_visible_display_id_);
diff --git a/ash/public/cpp/assistant/assistant_state_base.cc b/ash/public/cpp/assistant/assistant_state_base.cc index c209503..adf9d9b2 100644 --- a/ash/public/cpp/assistant/assistant_state_base.cc +++ b/ash/public/cpp/assistant/assistant_state_base.cc
@@ -30,7 +30,10 @@ AssistantStateBase::AssistantStateBase() = default; -AssistantStateBase::~AssistantStateBase() = default; +AssistantStateBase::~AssistantStateBase() { + for (auto& observer : observers_) + observer.OnAssistantStateDestroyed(); +} std::string AssistantStateBase::ToString() const { std::stringstream result;
diff --git a/ash/public/cpp/assistant/assistant_state_base.h b/ash/public/cpp/assistant/assistant_state_base.h index ebbfb14..b929e472 100644 --- a/ash/public/cpp/assistant/assistant_state_base.h +++ b/ash/public/cpp/assistant/assistant_state_base.h
@@ -35,6 +35,7 @@ virtual void OnAssistantHotwordEnabled(bool enabled) {} virtual void OnAssistantLaunchWithMicOpen(bool launch_with_mic_open) {} virtual void OnAssistantNotificationEnabled(bool notification_enabled) {} + virtual void OnAssistantStateDestroyed() {} // mojom::AssistantStateObserver: void OnAssistantStatusChanged(mojom::AssistantState state) override {}
diff --git a/ash/shelf/hotseat_widget_unittest.cc b/ash/shelf/hotseat_widget_unittest.cc new file mode 100644 index 0000000..20d28fc --- /dev/null +++ b/ash/shelf/hotseat_widget_unittest.cc
@@ -0,0 +1,180 @@ +// Copyright (c) 2020 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 "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/test/app_list_test_helper.h" +#include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_app_button.h" +#include "ash/shelf/shelf_layout_manager.h" +#include "ash/shelf/shelf_test_util.h" +#include "ash/shelf/shelf_view.h" +#include "ash/shelf/shelf_view_test_api.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" +#include "base/test/scoped_feature_list.h" +#include "chromeos/constants/chromeos_features.h" +#include "ui/events/gesture_detection/gesture_configuration.h" +#include "ui/events/test/event_generator.h" +#include "ui/wm/core/window_util.h" + +namespace ash { + +namespace { +ShelfLayoutManager* GetShelfLayoutManager() { + return AshTestBase::GetPrimaryShelf()->shelf_layout_manager(); +} +} // namespace + +class HotseatWidgetTest + : public AshTestBase, + public testing::WithParamInterface<ShelfAutoHideBehavior> { + public: + HotseatWidgetTest() = default; + + // Performs a swipe up gesture to show an auto-hidden shelf. + void SwipeUpOnShelf() { + gfx::Rect display_bounds = + display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); + const gfx::Point start(display_bounds.bottom_center()); + const gfx::Point end(start + gfx::Vector2d(0, -80)); + const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100); + const int kNumScrollSteps = 4; + GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta, + kNumScrollSteps); + } + + void SwipeDownOnShelf() { + gfx::Point start(GetPrimaryShelf() + ->shelf_widget() + ->shelf_view_for_testing() + ->GetBoundsInScreen() + .top_center()); + const gfx::Point end(start + gfx::Vector2d(0, 40)); + const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100); + const int kNumScrollSteps = 4; + GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta, + kNumScrollSteps); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Used to test the Hotseat, ScrollabeShelf, and DenseShelf features. +INSTANTIATE_TEST_SUITE_P(All, + HotseatWidgetTest, + testing::Values(ShelfAutoHideBehavior::kNever, + ShelfAutoHideBehavior::kAlways)); + +// Tests that closing a window which was opened prior to entering tablet mode +// results in a kShown hotseat. +TEST_P(HotseatWidgetTest, ClosingLastWindowInTabletMode) { + GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); + std::unique_ptr<aura::Window> window = + AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); + // Activate the window and go to tablet mode. + wm::ActivateWindow(window.get()); + TabletModeControllerTestApi().EnterTabletMode(); + + // Close the window, the AppListView should be shown, and the hotseat should + // be kShown. + window->Hide(); + + EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); + GetAppListTestHelper()->CheckVisibility(true); +} + +// Tests that the hotseat is kShown when entering tablet mode with no windows. +TEST_P(HotseatWidgetTest, GoingToTabletModeNoWindows) { + GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); + TabletModeControllerTestApi().EnterTabletMode(); + + GetAppListTestHelper()->CheckVisibility(true); + EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); +} + +// Tests that the hotseat is kHidden when entering tablet mode with a window. +TEST_P(HotseatWidgetTest, GoingToTabletModeWithWindows) { + GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); + + std::unique_ptr<aura::Window> window = + AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); + // Activate the window and go to tablet mode. + wm::ActivateWindow(window.get()); + TabletModeControllerTestApi().EnterTabletMode(); + + EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); + GetAppListTestHelper()->CheckVisibility(false); +} + +// The in-app Hotseat should not be hidden automatically when the shelf context +// menu shows (https://crbug.com/1020388). +TEST_P(HotseatWidgetTest, InAppShelfShowingContextMenu) { + GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); + TabletModeControllerTestApi().EnterTabletMode(); + std::unique_ptr<aura::Window> window = + AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); + wm::ActivateWindow(window.get()); + EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible()); + + ShelfTestUtil::AddAppShortcut("app_id", TYPE_PINNED_APP); + + // Swipe up on the shelf to show the hotseat. + SwipeUpOnShelf(); + EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); + + ShelfViewTestAPI shelf_view_test_api( + GetPrimaryShelf()->shelf_widget()->shelf_view_for_testing()); + ShelfAppButton* app_icon = shelf_view_test_api.GetButton(0); + + // Accelerate the generation of the long press event. + ui::GestureConfiguration::GetInstance()->set_show_press_delay_in_ms(1); + ui::GestureConfiguration::GetInstance()->set_long_press_time_in_ms(1); + + // Press the icon enough long time to generate the long press event. + GetEventGenerator()->MoveTouch(app_icon->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->PressTouch(); + ui::GestureConfiguration* gesture_config = + ui::GestureConfiguration::GetInstance(); + const int long_press_delay_ms = gesture_config->long_press_time_in_ms() + + gesture_config->show_press_delay_in_ms(); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(long_press_delay_ms)); + run_loop.Run(); + GetEventGenerator()->ReleaseTouch(); + + // Expects that the hotseat's state is kExntended. + EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); + + // Ensures that the ink drop state is InkDropState::ACTIVATED before closing + // the menu. + app_icon->FireRippleActivationTimerForTest(); +} + +// Tests that a window that is created after going to tablet mode, then closed, +// results in a kShown hotseat. +TEST_P(HotseatWidgetTest, CloseLastWindowOpenedInTabletMode) { + GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); + TabletModeControllerTestApi().EnterTabletMode(); + + std::unique_ptr<aura::Window> window = + AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); + // Activate the window after entering tablet mode. + wm::ActivateWindow(window.get()); + + EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); + GetAppListTestHelper()->CheckVisibility(false); + + // Hide the window, the hotseat should be kShown, and the home launcher should + // be visible. + window->Hide(); + + EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); + GetAppListTestHelper()->CheckVisibility(true); +} + +} // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index e3d708c..6f87938 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -2148,7 +2148,10 @@ if (Shell::Get()->app_list_controller()->IsVisible()) return true; - return StartShelfDrag(gesture_in_screen); + return StartShelfDrag( + gesture_in_screen, + gfx::Vector2dF(gesture_in_screen.details().scroll_x_hint(), + scroll_y_hint)); } void ShelfLayoutManager::UpdateGestureDrag( @@ -2183,7 +2186,10 @@ void ShelfLayoutManager::StartMouseDrag(const ui::MouseEvent& mouse_in_screen) { float scroll_y_hint = mouse_in_screen.y() - last_mouse_drag_position_.y(); if (!StartAppListDrag(mouse_in_screen, scroll_y_hint)) - StartShelfDrag(mouse_in_screen); + StartShelfDrag( + mouse_in_screen, + gfx::Vector2dF(mouse_in_screen.x() - last_mouse_drag_position_.x(), + scroll_y_hint)); } void ShelfLayoutManager::UpdateMouseDrag( @@ -2304,8 +2310,8 @@ return true; } -bool ShelfLayoutManager::StartShelfDrag( - const ui::LocatedEvent& event_in_screen) { +bool ShelfLayoutManager::StartShelfDrag(const ui::LocatedEvent& event_in_screen, + const gfx::Vector2dF& scroll_hint) { // Disable the shelf dragging if the fullscreen app list is opened. if (Shell::Get()->app_list_controller()->IsVisible() && !IsTabletModeEnabled()) @@ -2343,6 +2349,13 @@ drag_amount_ = 0.f; } + // If the start location is above the shelf (e.g., on the extended hotseat), + // do not allow window drag when the hotseat is extended. + const gfx::Rect shelf_bounds = GetVisibleShelfBounds(); + allow_window_drag_on_extended_hotseat_ = + event_in_screen.location_f().y() >= shelf_bounds.y(); + + MaybeStartDragWindowFromShelf(event_in_screen, scroll_hint); return true; } @@ -2653,8 +2666,6 @@ if (hotseat_state() == HotseatState::kShown) return false; - gfx::PointF event_start_location = event_in_screen.location_f(); - // If hotseat is hidden when drag starts, do not start drag window if hotseat // hasn't been fully dragged up. if (hotseat_state() == HotseatState::kHidden) { @@ -2665,16 +2676,9 @@ if (drag_amount_ > full_drag_amount) return false; } else if (hotseat_state() == HotseatState::kExtended) { - // Window drag will not start until it's determined that the gesture is - // going up. The effective starting position will thus be the previous event - // location. - event_start_location -= scroll; - - // If the start location is above the shelf (e.g., on the extended hotseat), - // do not allow the drag. - const gfx::Rect shelf_bounds = GetVisibleShelfBounds(); - if (event_start_location.y() < shelf_bounds.y()) + if (!allow_window_drag_on_extended_hotseat_) return false; + // Do not start drag if it's a downward update event. if (scroll.y() >= 0) return false; @@ -2693,15 +2697,7 @@ return false; window_drag_controller_ = std::make_unique<DragWindowFromShelfController>( - window, event_start_location, hotseat_state()); - - // In extended state, the effective start location is the previous event, so - // send additional drag event, so the controller doesn't skip the current - // drag location. - if (hotseat_state() == HotseatState::kExtended) { - window_drag_controller_->Drag(event_in_screen.location_f(), scroll.x(), - scroll.y()); - } + window, event_in_screen.location_f(), hotseat_state()); return true; }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 96370f77..b526e89 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -502,7 +502,8 @@ bool IsDragAllowed() const; bool StartAppListDrag(const ui::LocatedEvent& event_in_screen, float scroll_y_hint); - bool StartShelfDrag(const ui::LocatedEvent& event_in_screen); + bool StartShelfDrag(const ui::LocatedEvent& event_in_screen, + const gfx::Vector2dF& scroll_hint); // Sets the Hotseat up to be dragged, if applicable. void MaybeSetupHotseatDrag(const ui::LocatedEvent& event_in_screen); void UpdateDrag(const ui::LocatedEvent& event_in_screen, @@ -692,6 +693,11 @@ // if the overview session is active. bool allow_fling_from_overview_to_home_ = false; + // Indicates whether shelf drag gesture can start window drag from shelf to + // overview or home when hotseat is in extended state (the window drag will + // only be allowed if drag started within shelf bounds). + bool allow_window_drag_on_extended_hotseat_ = false; + // Tracks whether the shelf is currently dimmed for inactivity. bool dimmed_for_inactivity_ = false;
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index a5d8345d..ba109ad 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -3372,69 +3372,6 @@ testing::Values(ShelfAutoHideBehavior::kNever, ShelfAutoHideBehavior::kAlways)); -// Tests that the hotseat is kShown when entering tablet mode with no windows. -TEST_P(HotseatShelfLayoutManagerTest, GoingToTabletModeNoWindows) { - GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); - TabletModeControllerTestApi().EnterTabletMode(); - - GetAppListTestHelper()->CheckVisibility(true); - EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); -} - -// Tests that the hotseat is kHidden when entering tablet mode with a window. -TEST_P(HotseatShelfLayoutManagerTest, GoingToTabletModeWithWindows) { - GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); - - std::unique_ptr<aura::Window> window = - AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); - // Activate the window and go to tablet mode. - wm::ActivateWindow(window.get()); - TabletModeControllerTestApi().EnterTabletMode(); - - EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); - GetAppListTestHelper()->CheckVisibility(false); -} - -// Tests that closing a window which was opened prior to entering tablet mode -// results in a kShown hotseat. -TEST_P(HotseatShelfLayoutManagerTest, ClosingLastWindowInTabletMode) { - GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); - std::unique_ptr<aura::Window> window = - AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); - // Activate the window and go to tablet mode. - wm::ActivateWindow(window.get()); - TabletModeControllerTestApi().EnterTabletMode(); - - // Close the window, the AppListView should be shown, and the hotseat should - // be kShown. - window->Hide(); - - EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); - GetAppListTestHelper()->CheckVisibility(true); -} - -// Tests that a window that is created after going to tablet mode, then closed, -// results in a kShown hotseat. -TEST_P(HotseatShelfLayoutManagerTest, CloseLastWindowOpenedInTabletMode) { - GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); - TabletModeControllerTestApi().EnterTabletMode(); - - std::unique_ptr<aura::Window> window = - AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); - // Activate the window after entering tablet mode. - wm::ActivateWindow(window.get()); - - EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state()); - GetAppListTestHelper()->CheckVisibility(false); - - // Hide the window, the hotseat should be kShown, and the home launcher should - // be visible. - window->Hide(); - - EXPECT_EQ(HotseatState::kShown, GetShelfLayoutManager()->hotseat_state()); - GetAppListTestHelper()->CheckVisibility(true); -} - // Tests that swiping up on an autohidden shelf shows the hotseat, and swiping // down hides it. TEST_F(HotseatShelfLayoutManagerTest, ShowingAndHidingAutohiddenShelf) { @@ -3546,52 +3483,6 @@ InAppShelfGestures::kSwipeUpToShow, 3); } -// The in-app Hotseat should not be hidden automatically when the shelf context -// menu shows (https://crbug.com/1020388). -TEST_P(HotseatShelfLayoutManagerTest, InAppShelfShowingContextMenu) { - GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); - TabletModeControllerTestApi().EnterTabletMode(); - std::unique_ptr<aura::Window> window = - AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); - wm::ActivateWindow(window.get()); - EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible()); - - ShelfTestUtil::AddAppShortcut("app_id", TYPE_PINNED_APP); - - // Swipe up on the shelf to show the hotseat. - SwipeUpOnShelf(); - EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); - - ShelfViewTestAPI shelf_view_test_api( - GetPrimaryShelf()->shelf_widget()->shelf_view_for_testing()); - ShelfAppButton* app_icon = shelf_view_test_api.GetButton(0); - - // Accelerate the generation of the long press event. - ui::GestureConfiguration::GetInstance()->set_show_press_delay_in_ms(1); - ui::GestureConfiguration::GetInstance()->set_long_press_time_in_ms(1); - - // Press the icon enough long time to generate the long press event. - GetEventGenerator()->MoveTouch(app_icon->GetBoundsInScreen().CenterPoint()); - GetEventGenerator()->PressTouch(); - ui::GestureConfiguration* gesture_config = - ui::GestureConfiguration::GetInstance(); - const int long_press_delay_ms = gesture_config->long_press_time_in_ms() + - gesture_config->show_press_delay_in_ms(); - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), - base::TimeDelta::FromMilliseconds(long_press_delay_ms)); - run_loop.Run(); - GetEventGenerator()->ReleaseTouch(); - - // Expects that the hotseat's state is kExntended. - EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); - - // Ensures that the ink drop state is InkDropState::ACTIVATED before closing - // the menu. - app_icon->FireRippleActivationTimerForTest(); -} - // Tests that swiping up on the hotseat does nothing. TEST_P(HotseatShelfLayoutManagerTest, SwipeUpOnHotseatBackgroundDoesNothing) { GetPrimaryShelf()->SetAutoHideBehavior(GetParam()); @@ -5563,6 +5454,46 @@ EXPECT_FALSE(IsWindowDragInProgress()); EXPECT_TRUE(window->transform().IsIdentity()); EndScroll(/*is_fling=*/false, 0.f); + + EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); +} + +// Test that gesture that starts within hotseat bounds, goes down to shelf, and +// start moving up does not start window drag (as upward swipe from hotseat does +// not start window drag either). +TEST_F(ShelfLayoutManagerWindowDraggingTest, + NoOpIfDragSTartsAboveShelfAndMovesToShelf) { + std::unique_ptr<aura::Window> window = + AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400)); + wm::ActivateWindow(window.get()); + + Shelf* shelf = GetPrimaryShelf(); + shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways); + SwipeUpOnShelf(); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state()); + + gfx::Rect hotseat_bounds = + GetShelfWidget()->hotseat_widget()->GetWindowBoundsInScreen(); + StartScroll(hotseat_bounds.CenterPoint()); + EXPECT_FALSE(IsWindowDragInProgress()); + EXPECT_TRUE(window->transform().IsIdentity()); + + const gfx::Vector2d vector_from_hotseat_to_shelf_center = + hotseat_bounds.CenterPoint() - + GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint(); + UpdateScroll(vector_from_hotseat_to_shelf_center.y()); + + EXPECT_FALSE(IsWindowDragInProgress()); + EXPECT_TRUE(window->transform().IsIdentity()); + + UpdateScroll(-vector_from_hotseat_to_shelf_center.y()); + EXPECT_FALSE(IsWindowDragInProgress()); + EXPECT_TRUE(window->transform().IsIdentity()); + + EndScroll(/*is_fling=*/false, 0.f); + EXPECT_FALSE(IsWindowDragInProgress()); + EXPECT_TRUE(window->transform().IsIdentity()); } // Tests that the MRU window can only be dragged window after the hotseat is
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index 8e3f42d..630c02f 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -319,19 +319,21 @@ return; } - // Don't close the bubble if the message center is gaining or losing - // activation. + // Don't close the bubble if the message center is gaining activation. if (features::IsUnifiedMessageCenterRefactorEnabled() && tray_->IsMessageCenterBubbleShown()) { views::Widget* message_center_widget = tray_->message_center_bubble()->GetBubbleWidget(); if (message_center_widget == - views::Widget::GetWidgetForNativeView(gained_active) || - (lost_active && - message_center_widget == - views::Widget::GetWidgetForNativeView(lost_active))) { + views::Widget::GetWidgetForNativeView(gained_active)) { return; } + + // If the message center is not visible, ignore activation changes. + // Otherwise, this may cause a crash when closing the dialog via + // accelerator. See crbug.com/1041174. + if (!message_center_widget->IsVisible()) + return; } tray_->CloseBubble();
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java index b8d77d3b..9a40c14 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
@@ -33,6 +33,8 @@ */ public abstract class ChildConnectionAllocator { private static final String TAG = "ChildConnAllocator"; + private static final String ZYGOTE_SUFFIX = "0"; + private static final String NON_ZYGOTE_SUFFIX = "1"; /** Factory interface. Used by tests to specialize created connections. */ @VisibleForTesting @@ -72,7 +74,7 @@ /* package */ final String mServiceClassName; /* package */ final boolean mBindToCaller; /* package */ final boolean mBindAsExternalService; - private final boolean mUseStrongBinding; + /* package */ final boolean mUseStrongBinding; /* package */ ConnectionFactory mConnectionFactory = new ConnectionFactoryImpl(); @@ -125,9 +127,19 @@ String serviceClassName, boolean bindToCaller, boolean bindAsExternalService, boolean useStrongBinding) { checkServiceExists(context, packageName, serviceClassName); + if (Build.VERSION.SDK_INT == 29) { + UserManager userManager = + (UserManager) ContextUtils.getApplicationContext().getSystemService( + Context.USER_SERVICE); + if (!ApiHelperForM.isSystemUser(userManager)) { + return new Android10WorkaroundAllocatorImpl(launcherHandler, freeSlotCallback, + packageName, serviceClassName, bindToCaller, bindAsExternalService, + useStrongBinding, MAX_VARIABLE_ALLOCATED); + } + } return new VariableSizeAllocatorImpl(launcherHandler, freeSlotCallback, packageName, - serviceClassName, bindToCaller, bindAsExternalService, useStrongBinding, - MAX_VARIABLE_ALLOCATED); + serviceClassName + ZYGOTE_SUFFIX, bindToCaller, bindAsExternalService, + useStrongBinding, MAX_VARIABLE_ALLOCATED); } /** @@ -149,7 +161,17 @@ boolean bindToCaller, boolean bindAsExternalService, boolean useStrongBinding, int maxAllocated) { return new VariableSizeAllocatorImpl(launcherHandler, freeSlotCallback, packageName, - serviceClassName + "0", bindToCaller, bindAsExternalService, useStrongBinding, + serviceClassName + ZYGOTE_SUFFIX, bindToCaller, bindAsExternalService, + useStrongBinding, maxAllocated); + } + + @VisibleForTesting + public static Android10WorkaroundAllocatorImpl createWorkaroundForTesting( + Handler launcherHandler, String packageName, Runnable freeSlotCallback, + String serviceClassName, boolean bindToCaller, boolean bindAsExternalService, + boolean useStrongBinding, int maxAllocated) { + return new Android10WorkaroundAllocatorImpl(launcherHandler, freeSlotCallback, packageName, + serviceClassName, bindToCaller, bindAsExternalService, useStrongBinding, maxAllocated); } @@ -171,9 +193,6 @@ final ChildProcessConnection.ServiceCallback serviceCallback) { assert isRunningOnLauncherThread(); - ChildProcessConnection connection = doAllocate(context, serviceBundle); - if (connection == null) return null; - // Wrap the service callbacks so that: // - we can intercept onChildProcessDied and clean-up connections // - the callbacks are actually posted so that this method will return before the callbacks @@ -238,8 +257,7 @@ } }; - connection.start(mUseStrongBinding, serviceCallbackWrapper); - return connection; + return doAllocate(context, serviceBundle, serviceCallbackWrapper); } /** Free connection allocated by this allocator. */ @@ -280,7 +298,8 @@ return mLauncherHandler.getLooper() == Looper.myLooper(); } - /* package */ abstract ChildProcessConnection doAllocate(Context context, Bundle serviceBundle); + /* package */ abstract ChildProcessConnection doAllocate(Context context, Bundle serviceBundle, + ChildProcessConnection.ServiceCallback serviceCallback); /* package */ abstract void doFree(ChildProcessConnection connection); /** Implementation class accessed directly by tests. */ @@ -307,7 +326,8 @@ } @Override - /* package */ ChildProcessConnection doAllocate(Context context, Bundle serviceBundle) { + /* package */ ChildProcessConnection doAllocate(Context context, Bundle serviceBundle, + ChildProcessConnection.ServiceCallback serviceCallback) { if (mFreeConnectionIndices.isEmpty()) { Log.d(TAG, "Ran out of services to allocate."); return null; @@ -322,6 +342,7 @@ mChildProcessConnections[slot] = connection; Log.d(TAG, "Allocator allocated and bound a connection, name: %s, slot: %d", mServiceClassName, slot); + connection.start(mUseStrongBinding, serviceCallback); return connection; } @@ -374,34 +395,37 @@ private final ArraySet<ChildProcessConnection> mAllocatedConnections = new ArraySet<>(); private int mNextInstance; - private static String getServiceSuffix() { - // Android Q has a bug in its app zygote implementation under secondary user (eg in a - // work profile). See crbug.com/1035432 for details. Disable using the app zygote in - // that case by using a non '0' suffix which is the only service entry that enables - // app zygote. - if (Build.VERSION.SDK_INT == 29) { - UserManager userManager = - (UserManager) ContextUtils.getApplicationContext().getSystemService( - Context.USER_SERVICE); - if (!ApiHelperForM.isSystemUser(userManager)) { - return "1"; - } - } - return "0"; - } - + // Note |serviceClassName| includes the service suffix. private VariableSizeAllocatorImpl(Handler launcherHandler, Runnable freeSlotCallback, String packageName, String serviceClassName, boolean bindToCaller, boolean bindAsExternalService, boolean useStrongBinding, int maxAllocated) { - super(launcherHandler, freeSlotCallback, packageName, - serviceClassName + getServiceSuffix(), bindToCaller, bindAsExternalService, - useStrongBinding); + super(launcherHandler, freeSlotCallback, packageName, serviceClassName, bindToCaller, + bindAsExternalService, useStrongBinding); assert maxAllocated > 0; mMaxAllocated = maxAllocated; } @Override - /* package */ ChildProcessConnection doAllocate(Context context, Bundle serviceBundle) { + /* package */ ChildProcessConnection doAllocate(Context context, Bundle serviceBundle, + ChildProcessConnection.ServiceCallback serviceCallback) { + ChildProcessConnection connection = allocate(context, serviceBundle); + if (connection == null) return null; + mAllocatedConnections.add(connection); + connection.start(mUseStrongBinding, serviceCallback); + return connection; + } + + /* package */ ChildProcessConnection tryAllocate(Context context, Bundle serviceBundle, + ChildProcessConnection.ServiceCallback serviceCallback) { + ChildProcessConnection connection = allocate(context, serviceBundle); + if (connection == null) return null; + boolean startResult = connection.tryStart(mUseStrongBinding, serviceCallback); + if (!startResult) return null; + mAllocatedConnections.add(connection); + return connection; + } + + private ChildProcessConnection allocate(Context context, Bundle serviceBundle) { if (mAllocatedConnections.size() >= mMaxAllocated) { Log.d(TAG, "Ran out of UIDs to allocate."); return null; @@ -413,13 +437,17 @@ mConnectionFactory.createConnection(context, serviceName, mBindToCaller, mBindAsExternalService, serviceBundle, instanceName); assert connection != null; - mAllocatedConnections.add(connection); return connection; } @Override /* package */ void doFree(ChildProcessConnection connection) { - mAllocatedConnections.remove(connection); + boolean result = mAllocatedConnections.remove(connection); + assert result; + } + + /* package */ boolean wasConnectionAllocated(ChildProcessConnection connection) { + return mAllocatedConnections.contains(connection); } @Override @@ -437,4 +465,76 @@ return mAllocatedConnections.size() > 0; } } + + /** + * Workaround allocator for Android 10 bug. + * Android 10 has a bug that UID used for non-primary user cannot be freed correctly, + * eventually exhausting the pool of UIDs for isolated services. There is a global pool of + * 1000 UIDs, and each app zygote has a smaller pool of 100; the bug appplies to both cases. + * The leaked UID in the app zygote pool are released when the zygote is killed; leaked UIDs in + * the global pool are released when the device is rebooted. So way to slightly delay until the + * device needs to be rebooted is to use up the app zygote pool first before using the + * non-zygote global pool. + */ + private static class Android10WorkaroundAllocatorImpl extends ChildConnectionAllocator { + private final VariableSizeAllocatorImpl mZygoteAllocator; + private final VariableSizeAllocatorImpl mNonZygoteAllocator; + + private Android10WorkaroundAllocatorImpl(Handler launcherHandler, Runnable freeSlotCallback, + String packageName, String serviceClassName, boolean bindToCaller, + boolean bindAsExternalService, boolean useStrongBinding, int maxAllocated) { + super(launcherHandler, freeSlotCallback, packageName, serviceClassName, bindToCaller, + bindAsExternalService, useStrongBinding); + mZygoteAllocator = new VariableSizeAllocatorImpl(launcherHandler, freeSlotCallback, + packageName, serviceClassName + ZYGOTE_SUFFIX, bindToCaller, + bindAsExternalService, useStrongBinding, maxAllocated); + mNonZygoteAllocator = new VariableSizeAllocatorImpl(launcherHandler, freeSlotCallback, + packageName, serviceClassName + NON_ZYGOTE_SUFFIX, bindToCaller, + bindAsExternalService, useStrongBinding, maxAllocated); + } + + @Override + /* package */ ChildProcessConnection doAllocate(Context context, Bundle serviceBundle, + ChildProcessConnection.ServiceCallback serviceCallback) { + ChildProcessConnection connection = + mZygoteAllocator.tryAllocate(context, serviceBundle, serviceCallback); + if (connection != null) return connection; + return mNonZygoteAllocator.doAllocate(context, serviceBundle, serviceCallback); + } + + @Override + /* package */ void doFree(ChildProcessConnection connection) { + if (mZygoteAllocator.wasConnectionAllocated(connection)) { + mZygoteAllocator.doFree(connection); + } else if (mNonZygoteAllocator.wasConnectionAllocated(connection)) { + mNonZygoteAllocator.doFree(connection); + } else { + assert false; + } + } + + @Override + public int getNumberOfServices() { + return -1; + } + + @Override + public int allocatedConnectionsCountForTesting() { + return mZygoteAllocator.allocatedConnectionsCountForTesting() + + mNonZygoteAllocator.allocatedConnectionsCountForTesting(); + } + + @Override + public boolean anyConnectionAllocated() { + return mZygoteAllocator.anyConnectionAllocated() + || mNonZygoteAllocator.anyConnectionAllocated(); + } + + @Override + public void setConnectionFactoryForTesting(ConnectionFactory connectionFactory) { + super.setConnectionFactoryForTesting(connectionFactory); + mZygoteAllocator.setConnectionFactoryForTesting(connectionFactory); + mNonZygoteAllocator.setConnectionFactoryForTesting(connectionFactory); + } + } }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java index dcf824b8..c688e9c 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -416,6 +416,27 @@ } } + // This is the same as start, but returns a boolean whether bind succeeded. Also on failure, + // no method is called on |serviceCallback| so the allocation can be tried again. This is + // package private and is meant to be used by Android10WorkaroundAllocatorImpl. See comment + // there for details. + boolean tryStart(boolean useStrongBinding, ServiceCallback serviceCallback) { + try { + TraceEvent.begin("ChildProcessConnection.tryStart"); + assert isRunningOnLauncherThread(); + assert mConnectionParams + == null : "setupConnection() called before start() in ChildProcessConnection."; + + if (!bind(useStrongBinding)) { + return false; + } + mServiceCallback = serviceCallback; + } finally { + TraceEvent.end("ChildProcessConnection.tryStart"); + } + return true; + } + /** * Call bindService again on this connection. This must be called while connection is already * bound. This is useful for controlling the recency of this connection, and also for updating
diff --git a/base/android/junit/src/org/chromium/base/process_launcher/ChildConnectionAllocatorTest.java b/base/android/junit/src/org/chromium/base/process_launcher/ChildConnectionAllocatorTest.java index 599fd0e..e5fd740 100644 --- a/base/android/junit/src/org/chromium/base/process_launcher/ChildConnectionAllocatorTest.java +++ b/base/android/junit/src/org/chromium/base/process_launcher/ChildConnectionAllocatorTest.java
@@ -138,6 +138,7 @@ private ChildConnectionAllocator.FixedSizeAllocatorImpl mAllocator; private ChildConnectionAllocator mVariableSizeAllocator; + private ChildConnectionAllocator mWorkaroundAllocator; @Before public void setUp() { @@ -153,6 +154,12 @@ true /* bindTocall */, false /* bindAsExternalService */, false /* useStrongBinding */, 10); mVariableSizeAllocator.setConnectionFactoryForTesting(mTestConnectionFactory); + + mWorkaroundAllocator = ChildConnectionAllocator.createWorkaroundForTesting(new Handler(), + TEST_PACKAGE_NAME, null /* freeSlotCallback */, "AllocatorTest", + true /* bindTocall */, false /* bindAsExternalService */, + false /* useStrongBinding */, 10); + mWorkaroundAllocator.setConnectionFactoryForTesting(mTestConnectionFactory); } @Test @@ -211,6 +218,16 @@ doTestQueueAllocation(mVariableSizeAllocator, freeConnectionCallback); } + @Test + @Feature({"ProcessManagement"}) + public void testQueueAllocationWorkaround() { + Runnable freeConnectionCallback = mock(Runnable.class); + mWorkaroundAllocator = ChildConnectionAllocator.createWorkaroundForTesting(new Handler(), + TEST_PACKAGE_NAME, freeConnectionCallback, "AllocatorTest", true /* bindToCaller */, + false /* bindAsExternalService */, false /* useStrongBinding */, 1); + doTestQueueAllocation(mWorkaroundAllocator, freeConnectionCallback); + } + private void doTestQueueAllocation( ChildConnectionAllocator allocator, Runnable freeConnectionCallback) { allocator.setConnectionFactoryForTesting(mTestConnectionFactory); @@ -303,6 +320,13 @@ @Test @Feature({"ProcessManagement"}) + public void testOnChildStartedCallbackWorkaround() { + runTestWithConnectionCallbacks(mWorkaroundAllocator, true /* onChildStarted */, + false /* onChildStartFailed */, false /* onChildProcessDied */); + } + + @Test + @Feature({"ProcessManagement"}) public void testOnChildStartFailedCallback() { runTestWithConnectionCallbacks(mAllocator, false /* onChildStarted */, true /* onChildStartFailed */, false /* onChildProcessDied */); @@ -317,6 +341,13 @@ @Test @Feature({"ProcessManagement"}) + public void testOnChildStartFailedCallbackWorkaround() { + runTestWithConnectionCallbacks(mWorkaroundAllocator, false /* onChildStarted */, + true /* onChildStartFailed */, false /* onChildProcessDied */); + } + + @Test + @Feature({"ProcessManagement"}) public void testOnChildProcessDiedCallback() { runTestWithConnectionCallbacks(mAllocator, false /* onChildStarted */, false /* onChildStartFailed */, true /* onChildProcessDied */); @@ -329,6 +360,13 @@ false /* onChildStartFailed */, true /* onChildProcessDied */); } + @Test + @Feature({"ProcessManagement"}) + public void testOnChildProcessDiedCallbackWorkaround() { + runTestWithConnectionCallbacks(mWorkaroundAllocator, false /* onChildStarted */, + false /* onChildStartFailed */, true /* onChildProcessDied */); + } + /** * Tests that the allocator clears the connection when it fails to bind/process dies. */ @@ -391,6 +429,12 @@ @Test @Feature({"ProcessManagement"}) + public void testFreeConnectionOnChildStartFailedWorkaround() { + testFreeConnection(mWorkaroundAllocator, FREE_CONNECTION_TEST_CALLBACK_START_FAILED); + } + + @Test + @Feature({"ProcessManagement"}) public void testFreeConnectionOnChildProcessDied() { testFreeConnection(mAllocator, FREE_CONNECTION_TEST_CALLBACK_PROCESS_DIED); } @@ -400,4 +444,10 @@ public void testFreeConnectionOnChildProcessDiedVariableSize() { testFreeConnection(mVariableSizeAllocator, FREE_CONNECTION_TEST_CALLBACK_PROCESS_DIED); } + + @Test + @Feature({"ProcessManagement"}) + public void testFreeConnectionOnChildProcessDiedWorkaround() { + testFreeConnection(mWorkaroundAllocator, FREE_CONNECTION_TEST_CALLBACK_PROCESS_DIED); + } }
diff --git a/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java b/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java index 419c3a0..cf0ff67 100644 --- a/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java +++ b/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java
@@ -4,8 +4,6 @@ package org.chromium.android.commands.unzip; -import org.chromium.base.Log; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -28,8 +26,7 @@ try { (new Unzip()).run(args); } catch (RuntimeException e) { - Log.e(TAG, "unzip failed", e); - System.err.println(e.toString()); + e.printStackTrace(); System.exit(1); } }
diff --git a/build/android/pylib/local/emulator/ini.py b/build/android/pylib/local/emulator/ini.py index eaa17e4..8b8f0e8 100644 --- a/build/android/pylib/local/emulator/ini.py +++ b/build/android/pylib/local/emulator/ini.py
@@ -9,6 +9,8 @@ ret = {} for line in ini_str.splitlines(): key, val = line.split('=', 1) + key = key.strip() + val = val.strip() if strict and key in ret: raise ValueError('Multiple entries present for key "%s"' % key) ret[key] = val @@ -22,8 +24,8 @@ def dumps(obj): ret = '' - for k, v in obj.iteritems(): - ret += '%s=%s\n' % (k, str(v)) + for k, v in sorted(obj.iteritems()): + ret += '%s = %s\n' % (k, str(v)) return ret
diff --git a/build/android/pylib/local/emulator/ini_test.py b/build/android/pylib/local/emulator/ini_test.py new file mode 100755 index 0000000..4bc9ddb --- /dev/null +++ b/build/android/pylib/local/emulator/ini_test.py
@@ -0,0 +1,68 @@ +#! /usr/bin/env python +# Copyright 2020 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. +"""Tests for ini.py.""" + +import textwrap +import unittest + +from pylib.local.emulator import ini + + +class IniTest(unittest.TestCase): + def testLoadsBasic(self): + ini_str = textwrap.dedent("""\ + foo.bar = 1 + foo.baz= example + bar.bad =/path/to/thing + """) + expected = { + 'foo.bar': '1', + 'foo.baz': 'example', + 'bar.bad': '/path/to/thing', + } + self.assertEqual(expected, ini.loads(ini_str)) + + def testLoadsStrictFailure(self): + ini_str = textwrap.dedent("""\ + foo.bar = 1 + foo.baz = example + bar.bad = /path/to/thing + foo.bar = duplicate + """) + with self.assertRaises(ValueError): + ini.loads(ini_str, strict=True) + + def testLoadsPermissive(self): + ini_str = textwrap.dedent("""\ + foo.bar = 1 + foo.baz = example + bar.bad = /path/to/thing + foo.bar = duplicate + """) + expected = { + 'foo.bar': 'duplicate', + 'foo.baz': 'example', + 'bar.bad': '/path/to/thing', + } + self.assertEqual(expected, ini.loads(ini_str, strict=False)) + + def testDumpsBasic(self): + ini_contents = { + 'foo.bar': '1', + 'foo.baz': 'example', + 'bar.bad': '/path/to/thing', + } + # ini.dumps is expected to dump to string alphabetically + # by key. + expected = textwrap.dedent("""\ + bar.bad = /path/to/thing + foo.bar = 1 + foo.baz = example + """) + self.assertEqual(expected, ini.dumps(ini_contents)) + + +if __name__ == '__main__': + unittest.main()
diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni index 754bb914..5ced459 100644 --- a/build/config/c++/c++.gni +++ b/build/config/c++/c++.gni
@@ -12,7 +12,9 @@ # is not supported. use_custom_libcxx = is_fuchsia || is_android || is_mac || (is_ios && !use_xcode_clang) || - (is_win && is_clang) || is_linux + (is_win && is_clang) || + (is_linux && + (!is_chromeos || default_toolchain != "//build/toolchain/cros:target")) # Use libc++ instead of stdlibc++ when using the host_cpu toolchain, even if # use_custom_libcxx is false. This is useful for cross-compiles where a custom
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 9db0ea45..18758e2 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -140,7 +140,7 @@ def GetVisualStudioVersion(): """Return best available version of Visual Studio. """ - supported_versions = MSVS_VERSIONS.keys() + supported_versions = list(MSVS_VERSIONS.keys()) # VS installed in depot_tools for Googlers if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))):
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc index 8b2f09c..1cd55fe 100644 --- a/cc/metrics/frame_sequence_tracker.cc +++ b/cc/metrics/frame_sequence_tracker.cc
@@ -466,13 +466,11 @@ DCHECK(!is_inside_frame_) << TRACKER_DCHECK_MSG; is_inside_frame_ = true; - DCHECK_EQ(last_started_impl_sequence_, 0u) << TRACKER_DCHECK_MSG; - DCHECK_EQ(last_processed_impl_sequence_, 0u) << TRACKER_DCHECK_MSG; - if (args.type == viz::BeginFrameArgs::NORMAL) impl_frames_.insert(args.frame_id); #endif + DCHECK_EQ(last_started_impl_sequence_, 0u) << TRACKER_DCHECK_MSG; last_started_impl_sequence_ = args.frame_id.sequence_number; if (reset_all_state_) { begin_impl_frame_data_ = {}; @@ -506,19 +504,24 @@ TRACKER_TRACE_STREAM << "B(" << begin_main_frame_data_.previous_sequence << "," << args.frame_id.sequence_number << ")"; - if (ShouldIgnoreSequence(args.frame_id.sequence_number)) + if (first_received_main_sequence_ && + first_received_main_sequence_ > args.frame_id.sequence_number) { return; + } + + if (!first_received_main_sequence_ && + ShouldIgnoreSequence(args.frame_id.sequence_number)) { + return; + } #if DCHECK_IS_ON() if (args.type == viz::BeginFrameArgs::NORMAL) { - DCHECK(impl_frames_.contains(args.frame_id)); + DCHECK(impl_frames_.contains(args.frame_id)) << TRACKER_DCHECK_MSG; } #endif - // TODO(sad, xidachen): This DCHECK needs to be turned on, but the synthesized - // BeginMainFrame notifications from LayerTreeHostImpl needs to be removed - // first. - // DCHECK_EQ(awaiting_main_response_sequence_, 0u) << TRACKER_DCHECK_MSG; + DCHECK_EQ(awaiting_main_response_sequence_, 0u) << TRACKER_DCHECK_MSG; + last_processed_main_sequence_latency_ = 0; awaiting_main_response_sequence_ = args.frame_id.sequence_number; UpdateTrackedFrameData(&begin_main_frame_data_, args.frame_id.source_id, @@ -542,11 +545,15 @@ TRACKER_TRACE_STREAM << "E(" << args.frame_id.sequence_number << ")"; if (first_received_main_sequence_ && args.frame_id.sequence_number >= first_received_main_sequence_) { - // TODO(sad, xidachen): This DCHECK needs to be turned on, but the - // synthesized BeginMainFrame notifications from LayerTreeHostImpl needs to - // be removed first. - // DCHECK_EQ(awaiting_main_response_sequence_, - // args.frame_id.sequence_number) << TRACKER_DCHECK_MSG; + if (awaiting_main_response_sequence_) { + DCHECK_EQ(awaiting_main_response_sequence_, args.frame_id.sequence_number) + << TRACKER_DCHECK_MSG; + } + DCHECK_EQ(last_processed_main_sequence_latency_, 0u) << TRACKER_DCHECK_MSG; + last_processed_main_sequence_ = args.frame_id.sequence_number; + last_processed_main_sequence_latency_ = + std::max(last_started_impl_sequence_, last_processed_impl_sequence_) - + args.frame_id.sequence_number; awaiting_main_response_sequence_ = 0; } } @@ -591,6 +598,7 @@ if (!ShouldIgnoreBeginFrameSource(origin_args.frame_id.source_id) && main_changes_after_sequence_started && main_changes_include_new_changes && !main_change_had_no_damage) { + submitted_frame_had_new_main_content_ = true; TRACKER_TRACE_STREAM << "S(" << origin_args.frame_id.sequence_number << ")"; last_submitted_main_sequence_ = origin_args.frame_id.sequence_number; @@ -628,6 +636,13 @@ return; } + if (compositor_frame_submitted_ && submitted_frame_had_new_main_content_ && + last_processed_main_sequence_latency_) { + // If a compositor frame was submitted with new content from the + // main-thread, then make sure the latency gets accounted for. + main_throughput().frames_expected += last_processed_main_sequence_latency_; + } + // It is possible that the compositor claims there was no damage from the // compositor, but before the frame ends, it submits a compositor frame (e.g. // with some damage from main). In such cases, the compositor is still @@ -649,15 +664,17 @@ } frame_had_no_compositor_damage_ = false; compositor_frame_submitted_ = false; + submitted_frame_had_new_main_content_ = false; + last_processed_main_sequence_latency_ = 0; #if DCHECK_IS_ON() DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG; - DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_) - << TRACKER_DCHECK_MSG; is_inside_frame_ = false; #endif - last_started_impl_sequence_ = last_processed_impl_sequence_ = 0; + DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_) + << TRACKER_DCHECK_MSG; + last_started_impl_sequence_ = 0; } void FrameSequenceTracker::ReportFramePresented( @@ -791,11 +808,17 @@ if (last_no_main_damage_sequence_ == args.frame_id.sequence_number) return; - // TODO(sad, xidachen): This DCHECK needs to be turned on, but the synthesized - // BeginMainFrame notifications from LayerTreeHostImpl needs to be removed - // first. - // DCHECK_EQ(awaiting_main_response_sequence_, args.frame_id.sequence_number) - // << TRACKER_DCHECK_MSG; + // It is possible for |awaiting_main_response_sequence_| to be zero here if a + // commit had already happened before (e.g. B(x)E(x)N(x)). So check that case + // here. + // XXX: Add a DCHECK() at least to make sure that's what happened? + if (awaiting_main_response_sequence_) { + DCHECK_EQ(awaiting_main_response_sequence_, args.frame_id.sequence_number) + << TRACKER_DCHECK_MSG; + } else { + DCHECK_EQ(last_processed_main_sequence_, args.frame_id.sequence_number) + << TRACKER_DCHECK_MSG; + } awaiting_main_response_sequence_ = 0; DCHECK_GT(main_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG; @@ -826,7 +849,7 @@ if (frame_data->previous_sequence && frame_data->previous_source == source_id) { uint32_t current_latency = sequence_number - frame_data->previous_sequence; - DCHECK_GT(current_latency, 0u); + DCHECK_GT(current_latency, 0u) << TRACKER_DCHECK_MSG; frame_data->previous_sequence_delta = current_latency; } else { frame_data->previous_sequence_delta = 1;
diff --git a/cc/metrics/frame_sequence_tracker.h b/cc/metrics/frame_sequence_tracker.h index 3bb4df2c..0b53f1b 100644 --- a/cc/metrics/frame_sequence_tracker.h +++ b/cc/metrics/frame_sequence_tracker.h
@@ -399,6 +399,7 @@ // Keeps track of whether a CompositorFrame is submitted during the frame. bool compositor_frame_submitted_ = false; + bool submitted_frame_had_new_main_content_ = false; // Keeps track of whether the frame-states should be reset. bool reset_all_state_ = false; @@ -414,6 +415,9 @@ uint64_t last_started_impl_sequence_ = 0; uint64_t last_processed_impl_sequence_ = 0; + uint64_t last_processed_main_sequence_ = 0; + uint64_t last_processed_main_sequence_latency_ = 0; + #if DCHECK_IS_ON() bool is_inside_frame_ = false;
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc index adc9645..1109e04 100644 --- a/cc/metrics/frame_sequence_tracker_unittest.cc +++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -76,6 +76,8 @@ if (damage_type & kImplDamage) { if (!(damage_type & kMainDamage)) { collection_.NotifyMainFrameCausedNoDamage(args); + } else { + collection_.NotifyMainFrameProcessed(args); } uint32_t frame_token = NextFrameToken(); collection_.NotifySubmitFrame(frame_token, has_missing_content, @@ -196,6 +198,7 @@ case 'n': case 's': case 'e': + case 'E': ASSERT_EQ(*str, '(') << command; str = ParseNumber(++str, &sequence); ASSERT_EQ(*str, ')'); @@ -263,6 +266,11 @@ collection_.NotifyFrameEnd(CreateBeginFrameArgs(source_id, sequence)); break; + case 'E': + collection_.NotifyMainFrameProcessed( + CreateBeginFrameArgs(source_id, sequence)); + break; + case 'B': collection_.NotifyBeginMainFrame( CreateBeginFrameArgs(source_id, sequence)); @@ -563,14 +571,14 @@ // Start and submit the next frame, with no damage from main. auto args = CreateBeginFrameArgs(source, ++sequence); - StartImplAndMainFrames(args); + collection_.NotifyBeginImplFrame(args); frame_token = NextFrameToken(); - collection_.NotifyMainFrameCausedNoDamage(args); collection_.NotifySubmitFrame(frame_token, /*has_missing_content=*/false, viz::BeginFrameAck(args, true), first_args); collection_.NotifyFrameEnd(args); // Now, submit a frame with damage from main from |second_args|. + collection_.NotifyMainFrameProcessed(second_args); args = CreateBeginFrameArgs(source, ++sequence); StartImplAndMainFrames(args); frame_token = NextFrameToken(); @@ -604,6 +612,7 @@ // frame). auto second_args = CreateBeginFrameArgs(source, ++sequence); collection_.NotifyBeginImplFrame(second_args); + collection_.NotifyMainFrameProcessed(first_args); collection_.NotifyBeginMainFrame(second_args); uint32_t frame_token = NextFrameToken(); collection_.NotifySubmitFrame(frame_token, /*has_missing_content=*/false, @@ -730,4 +739,23 @@ EXPECT_EQ(ImplThroughput().frames_produced, 1u); } +// b(2417)B(0,2417)E(2417)n(2417)N(2417,2417) + +TEST_F(FrameSequenceTrackerTest, SequenceNumberReset) { + const char sequence[] = + "b(6)B(0,6)n(6)e(6)Rb(1)B(0,1)N(1,1)n(1)e(1)b(2)B(1,2)n(2)e(2)"; + GenerateSequence(sequence); + EXPECT_EQ(ImplThroughput().frames_expected, 0u); + EXPECT_EQ(MainThroughput().frames_expected, 1u); +} + +TEST_F(FrameSequenceTrackerTest, MainThroughputWithHighLatency) { + const char sequence[] = "b(1)B(0,1)n(1)e(1)b(2)E(1)s(1)S(1)e(2)P(1)"; + GenerateSequence(sequence); + EXPECT_EQ(ImplThroughput().frames_expected, 1u); + EXPECT_EQ(ImplThroughput().frames_produced, 1u); + EXPECT_EQ(MainThroughput().frames_expected, 2u); + EXPECT_EQ(MainThroughput().frames_produced, 1u); +} + } // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 67453e2..40fc476 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -363,8 +363,7 @@ } void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) { - if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME && - !begin_main_frame_sent_during_impl_) { + if (!begin_main_frame_sent_during_impl_) { begin_main_frame_sent_during_impl_ = true; frame_trackers_.NotifyBeginMainFrame(args); } @@ -2308,14 +2307,6 @@ // outside of begin-impl frame pipeline. Avoid notifying the trackers in such // cases. if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) { - if (!begin_main_frame_sent_during_impl_) { - frame_trackers_.NotifyBeginMainFrame( - current_begin_frame_tracker_.Current()); - if (!begin_main_frame_expected_during_impl_) { - frame_trackers_.NotifyMainFrameCausedNoDamage( - current_begin_frame_tracker_.Current()); - } - } frame_trackers_.NotifySubmitFrame( compositor_frame.metadata.frame_token, frame->has_missing_content, frame->begin_frame_ack, frame->origin_begin_main_frame_args); @@ -2681,12 +2672,7 @@ frame_trackers_.NotifyBeginImplFrame(args); begin_main_frame_expected_during_impl_ = client_->IsBeginMainFrameExpected(); - if (begin_main_frame_expected_during_impl_) { - begin_main_frame_sent_during_impl_ = true; - frame_trackers_.NotifyBeginMainFrame(args); - } else { - begin_main_frame_sent_during_impl_ = false; - } + begin_main_frame_sent_during_impl_ = false; if (is_likely_to_require_a_draw_) { // Optimistically schedule a draw. This will let us expect the tile manager
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 636d567..b04b885 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -252,6 +252,7 @@ CompletionEvent* completion, LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, + const viz::BeginFrameArgs& commit_args, bool hold_commit_for_activation) { TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToCommitOnImpl"); DCHECK(!commit_completion_event_); @@ -270,8 +271,7 @@ // But, we can avoid a PostTask in here. scheduler_->NotifyBeginMainFrameStarted(main_thread_start_time); - host_impl_->ReadyToCommit( - scheduler_->last_dispatched_begin_main_frame_args()); + host_impl_->ReadyToCommit(commit_args); commit_completion_event_ = std::make_unique<ScopedCompletionEvent>(completion);
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index 89e4b18..5457428f 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -61,6 +61,7 @@ void NotifyReadyToCommitOnImpl(CompletionEvent* completion, LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, + const viz::BeginFrameArgs& commit_args, bool hold_commit_for_activation); void SetSourceURL(ukm::SourceId source_id, const GURL& url); void ClearHistory();
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 16431892..b94a19c 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -340,6 +340,7 @@ base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl, base::Unretained(proxy_impl_.get()), &completion, layer_tree_host_, begin_main_frame_start_time, + begin_main_frame_state->begin_frame_args, hold_commit_for_activation)); completion.Wait(); }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 364c38d7..ba83db7 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -408,6 +408,7 @@ "//chrome/browser:sharing_send_message_result_generated_enum", "//chrome/browser/notifications/scheduler/public:jni_enums", "//chrome/browser/supervised_user/supervised_user_error_page:enums_srcjar", + "//chrome/browser/ui:cookie_controls_controller_status_javagen", "//chrome/browser/ui:tab_model_enums_java", "//components/autofill_assistant/browser:autofill_assistant_enums_java", "//components/browsing_data/core:browsing_data_utils_java", @@ -2769,6 +2770,7 @@ "java/src/org/chromium/chrome/browser/settings/privacy/BrowsingDataBridge.java", "java/src/org/chromium/chrome/browser/settings/privacy/BrowsingDataCounterBridge.java", "java/src/org/chromium/chrome/browser/settings/privacy/PrivacyPreferencesManager.java", + "java/src/org/chromium/chrome/browser/settings/website/CookieControlsBridge.java", "java/src/org/chromium/chrome/browser/settings/website/WebsitePreferenceBridge.java", "java/src/org/chromium/chrome/browser/sharing/SharingJNIBridge.java", "java/src/org/chromium/chrome/browser/sharing/SharingServiceProxy.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 2ddf877e..78166ca 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1323,6 +1323,7 @@ "java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java", "java/src/org/chromium/chrome/browser/prerender/ChromePrerenderService.java", "java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java", + "java/src/org/chromium/chrome/browser/previews/Previews.java", "java/src/org/chromium/chrome/browser/previews/PreviewsAndroidBridge.java", "java/src/org/chromium/chrome/browser/previews/PreviewsUma.java", "java/src/org/chromium/chrome/browser/printing/PrintShareActivity.java", @@ -1467,6 +1468,7 @@ "java/src/org/chromium/chrome/browser/settings/website/ContentSetting.java", "java/src/org/chromium/chrome/browser/settings/website/ContentSettingException.java", "java/src/org/chromium/chrome/browser/settings/website/ContentSettingsResources.java", + "java/src/org/chromium/chrome/browser/settings/website/CookieControlsBridge.java", "java/src/org/chromium/chrome/browser/settings/website/LocalStorageInfo.java", "java/src/org/chromium/chrome/browser/settings/website/LocationCategory.java", "java/src/org/chromium/chrome/browser/settings/website/ManageSpaceActivity.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 0c2f94c..80c9772 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -420,6 +420,7 @@ "javatests/src/org/chromium/chrome/browser/settings/privacy/PrivacyPreferencesManagerNativeTest.java", "javatests/src/org/chromium/chrome/browser/settings/search_engine/SearchEngineSettingsTest.java", "javatests/src/org/chromium/chrome/browser/settings/themes/ThemeSettingsFragmentTest.java", + "javatests/src/org/chromium/chrome/browser/settings/website/CookieControlsBridgeTest.java", "javatests/src/org/chromium/chrome/browser/settings/website/ManageSpaceActivityTest.java", "javatests/src/org/chromium/chrome/browser/settings/website/PermissionInfoTest.java", "javatests/src/org/chromium/chrome/browser/settings/website/SiteSettingsTest.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java index be380a6..af5fc5c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java
@@ -19,12 +19,10 @@ import android.support.v4.content.ContextCompat; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.widget.ImageViewCompat; -import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.PopupWindow; @@ -41,6 +39,7 @@ import org.chromium.chrome.browser.widget.ScrimView; import org.chromium.chrome.tab_ui.R; import org.chromium.components.browser_ui.widget.animation.Interpolators; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.interpolators.BakedBezierInterpolator; import java.lang.annotation.Retention; @@ -140,13 +139,10 @@ (int) context.getResources().getDimension(R.dimen.bottom_sheet_peek_height); mContainerParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - DisplayMetrics displayMetrics = new DisplayMetrics(); - ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getMetrics(displayMetrics); + DisplayAndroid display = DisplayAndroid.getNonMultiDisplay(context); // Screen height and width when in portrait mode. - mScreenHeight = Math.max(displayMetrics.heightPixels, displayMetrics.widthPixels); - mScreenWidth = Math.min(displayMetrics.heightPixels, displayMetrics.widthPixels); + mScreenHeight = Math.max(display.getDisplayHeight(), display.getDisplayWidth()); + mScreenWidth = Math.min(display.getDisplayHeight(), display.getDisplayWidth()); mComponentCallbacks = new ComponentCallbacks() { @Override @@ -837,4 +833,4 @@ static void setSourceRectCallbackForTesting(Callback<RectF> callback) { sSourceRectCallbackForTesting = callback; } -} \ No newline at end of file +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemView.java index 1ae39b75..1bacd62 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemView.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.tasks.tab_management; -import android.app.Activity; import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; @@ -19,7 +18,6 @@ import android.support.v4.view.ViewCompat; import android.support.v7.content.res.AppCompatResources; import android.util.AttributeSet; -import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -34,6 +32,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.browser.widget.ScrimView; import org.chromium.chrome.tab_ui.R; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.widget.ChromeImageView; /** @@ -193,9 +192,7 @@ } private void updateMargins(int orientation) { - DisplayMetrics displayMetrics = new DisplayMetrics(); - ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - int screenHeight = displayMetrics.heightPixels; + int screenHeight = DisplayAndroid.getNonMultiDisplay(getContext()).getDisplayHeight(); int dialogHeight = (int) mContext.getResources().getDimension(R.dimen.tab_grid_iph_dialog_height);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParentTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParentTest.java index ce504ec1..1e09caf 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParentTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParentTest.java
@@ -53,25 +53,28 @@ super.setUpTest(); TabFeatureUtilities.setIsTabToGtsAnimationEnabledForTesting(true); - mDummyParent = new FrameLayout(getActivity()); - mTabGridDialogParent = new TabGridDialogParent(getActivity(), mDummyParent); - mPopoupWindow = mTabGridDialogParent.getPopupWindowForTesting(); - FrameLayout tabGridDialogParentView = - mTabGridDialogParent.getTabGridDialogParentViewForTesting(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mDummyParent = new FrameLayout(getActivity()); + mTabGridDialogParent = new TabGridDialogParent(getActivity(), mDummyParent); + mPopoupWindow = mTabGridDialogParent.getPopupWindowForTesting(); + FrameLayout tabGridDialogParentView = + mTabGridDialogParent.getTabGridDialogParentViewForTesting(); - mTabGridDialogContainer = tabGridDialogParentView.findViewById(R.id.dialog_container_view); - mUngroupBar = mTabGridDialogContainer.findViewById(R.id.dialog_ungroup_bar); - mUngroupBarTextView = mUngroupBar.findViewById(R.id.dialog_ungroup_bar_text); - mContainerParams = (FrameLayout.LayoutParams) mTabGridDialogContainer.getLayoutParams(); - mAnimationCardView = mTabGridDialogParent.getAnimationCardViewForTesting(); - mBackgroundFrameView = tabGridDialogParentView.findViewById(R.id.dialog_frame); + mTabGridDialogContainer = + tabGridDialogParentView.findViewById(R.id.dialog_container_view); + mUngroupBar = mTabGridDialogContainer.findViewById(R.id.dialog_ungroup_bar); + mUngroupBarTextView = mUngroupBar.findViewById(R.id.dialog_ungroup_bar_text); + mContainerParams = (FrameLayout.LayoutParams) mTabGridDialogContainer.getLayoutParams(); + mAnimationCardView = mTabGridDialogParent.getAnimationCardViewForTesting(); + mBackgroundFrameView = tabGridDialogParentView.findViewById(R.id.dialog_frame); - mToolbarHeight = - (int) getActivity().getResources().getDimension(R.dimen.tab_group_toolbar_height); - mTopMargin = - (int) getActivity().getResources().getDimension(R.dimen.tab_grid_dialog_top_margin); - mSideMargin = (int) getActivity().getResources().getDimension( - R.dimen.tab_grid_dialog_side_margin); + mToolbarHeight = (int) getActivity().getResources().getDimension( + R.dimen.tab_group_toolbar_height); + mTopMargin = (int) getActivity().getResources().getDimension( + R.dimen.tab_grid_dialog_top_margin); + mSideMargin = (int) getActivity().getResources().getDimension( + R.dimen.tab_grid_dialog_side_margin); + }); } @Test
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemTest.java index 0d8ce755..e74ba47 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemTest.java
@@ -24,7 +24,6 @@ import android.os.Build; import android.support.test.espresso.NoMatchingRootException; import android.support.test.filters.MediumTest; -import android.util.DisplayMetrics; import android.view.ViewGroup; import android.widget.TextView; @@ -50,6 +49,8 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.test.util.UiRestriction; /** End-to-end tests for TabGridIphItem component. */ @@ -210,9 +211,8 @@ private void verifyDialogMargins(ChromeTabbedActivity cta, int orientation) { verifyIphDialogShowing(cta); - DisplayMetrics displayMetrics = new DisplayMetrics(); - cta.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - int screenHeight = displayMetrics.heightPixels; + int screenHeight = TestThreadUtils.runOnUiThreadBlockingNoException( + () -> DisplayAndroid.getNonMultiDisplay(cta).getDisplayHeight()); int dialogHeight = (int) cta.getResources().getDimension(R.dimen.tab_grid_iph_dialog_height); @@ -285,4 +285,4 @@ assertEquals(textSideMargin, realMargins.leftMargin); }); } -} \ No newline at end of file +}
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java index ec8ec02..15ba449 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java
@@ -62,26 +62,29 @@ @Override public void setUpTest() throws Exception { super.setUpTest(); - FrameLayout parentView = new FrameLayout(getActivity()); - mContentView = (TabListRecyclerView) LayoutInflater.from(getActivity()) - .inflate(R.layout.tab_list_recycler_view_layout, parentView, false); - mContentView.setLayoutManager(new GridLayoutManager(getActivity(), 2)); - mToolbarView = (TabGroupUiToolbarView) LayoutInflater.from(getActivity()) - .inflate(R.layout.bottom_tab_grid_toolbar, mContentView, false); - mTabGridDialogParent = - new TabGridDialogParent(getActivity(), new FrameLayout(getActivity())); - mTabGridDialogParentView = mTabGridDialogParent.getTabGridDialogParentViewForTesting(); - mLeftButton = mToolbarView.findViewById(R.id.toolbar_left_button); - mRightButton = mToolbarView.findViewById(R.id.toolbar_right_button); - mTitleTextView = mToolbarView.findViewById(R.id.title); - mMainContent = mToolbarView.findViewById(R.id.main_content); + TestThreadUtils.runOnUiThreadBlocking(() -> { + FrameLayout parentView = new FrameLayout(getActivity()); + mContentView = + (TabListRecyclerView) LayoutInflater.from(getActivity()) + .inflate(R.layout.tab_list_recycler_view_layout, parentView, false); + mContentView.setLayoutManager(new GridLayoutManager(getActivity(), 2)); + mToolbarView = (TabGroupUiToolbarView) LayoutInflater.from(getActivity()) + .inflate(R.layout.bottom_tab_grid_toolbar, mContentView, false); + mTabGridDialogParent = + new TabGridDialogParent(getActivity(), new FrameLayout(getActivity())); + mTabGridDialogParentView = mTabGridDialogParent.getTabGridDialogParentViewForTesting(); + mLeftButton = mToolbarView.findViewById(R.id.toolbar_left_button); + mRightButton = mToolbarView.findViewById(R.id.toolbar_right_button); + mTitleTextView = mToolbarView.findViewById(R.id.title); + mMainContent = mToolbarView.findViewById(R.id.main_content); - mModel = new PropertyModel(TabGridPanelProperties.ALL_KEYS); + mModel = new PropertyModel(TabGridPanelProperties.ALL_KEYS); - mMCP = PropertyModelChangeProcessor.create(mModel, - new TabGridPanelViewBinder.ViewHolder( - mToolbarView, mContentView, mTabGridDialogParent), - TabGridPanelViewBinder::bind); + mMCP = PropertyModelChangeProcessor.create(mModel, + new TabGridPanelViewBinder.ViewHolder( + mToolbarView, mContentView, mTabGridDialogParent), + TabGridPanelViewBinder::bind); + }); } @Test
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/AndroidVSyncHelper.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/AndroidVSyncHelper.java index 35da919f..6f8eb32 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/AndroidVSyncHelper.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/AndroidVSyncHelper.java
@@ -6,12 +6,12 @@ import android.content.Context; import android.view.Choreographer; -import android.view.WindowManager; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; +import org.chromium.ui.display.DisplayAndroidManager; /** * Helper class for interfacing with the Android Choreographer from native code. @@ -51,9 +51,7 @@ @CalledByNative private float getRefreshRate() { Context context = ContextUtils.getApplicationContext(); - WindowManager windowManager = - (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - return windowManager.getDefaultDisplay().getRefreshRate(); + return DisplayAndroidManager.getDefaultDisplayForContext(context).getRefreshRate(); } @NativeMethods
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java index 09aaa93..4bbf80d 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -67,6 +67,7 @@ import org.chromium.ui.base.PermissionCallback; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid; +import org.chromium.ui.display.DisplayAndroidManager; import org.chromium.ui.display.VirtualDisplayAndroid; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -395,7 +396,7 @@ // Get physical and pixel size of the display, which is needed by native // to dynamically calculate the content's resolution and window size. DisplayMetrics dm = new DisplayMetrics(); - mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(dm); + DisplayAndroidManager.getDefaultDisplayForContext(mActivity).getRealMetrics(dm); // We're supposed to be in landscape at this point, but it's possible for us to get here // before the change has fully propagated. In this case, the width and height are swapped, // which causes an incorrect display size to be used, and the page to appear zoomed in.
diff --git a/chrome/android/java/res/layout/start_top_toolbar.xml b/chrome/android/java/res/layout/start_top_toolbar.xml index d501dae..aeb43ac 100644 --- a/chrome/android/java/res/layout/start_top_toolbar.xml +++ b/chrome/android/java/res/layout/start_top_toolbar.xml
@@ -18,7 +18,7 @@ android:layout_centerVertical="true" android:layout_alignParentStart="true" android:paddingStart="16dp" - android:paddingEnd="16dp" + android:paddingEnd="8dp" android:thumb="@drawable/incognito_switch" android:track="@drawable/incognito_switch_track" android:visibility="gone"/> @@ -43,10 +43,17 @@ android:layout_width="wrap_content" android:layout_toStartOf="@+id/menu_anchor" android:layout_centerVertical="true" - android:paddingStart="16dp" - android:paddingEnd="16dp" + android:paddingStart="8dp" + android:paddingEnd="8dp" android:contentDescription="@string/accessibility_toolbar_btn_new_tab" /> + <include + layout="@layout/experimental_toolbar_button" + android:id="@+id/experimental_toolbar_button_start" + android:layout_toStartOf="@+id/menu_anchor" + style="@style/ToolbarButton" + android:visibility="gone" /> + <FrameLayout android:id="@+id/menu_anchor" android:layout_width="wrap_content"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index f862afe..8da8b55f 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -320,6 +320,10 @@ 24dp is needed to completely round the corners. --> <dimen name="modern_toolbar_background_corner_radius">24dp</dimen> + <!-- Start surface toolbar dimensions --> + <dimen name="start_surface_toolbar_button_padding_to_button">8dp</dimen> + <dimen name="start_surface_toolbar_button_padding_to_edge">16dp</dimen> + <!-- Omnibox suggestions --> <dimen name="omnibox_suggestion_height">60dp</dimen> <dimen name="omnibox_suggestion_answer_height">72dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 0ce3d5a..d23cdbbd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -2002,7 +2002,7 @@ } if (id == R.id.preferences_id) { - SettingsLauncher.getInstance().launchSettingsPage(this, null); + SettingsLauncher.getInstance().launchSettingsPage(this); RecordUserAction.record("MobileMenuSettings"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java index c4a17a0e..07e7414 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.browserservices.trustedwebactivityui.controller; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.customtabs.CloseButtonVisibilityManager; @@ -13,8 +14,8 @@ import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar.CustomTabTabObserver; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator; import org.chromium.chrome.browser.dependency_injection.ActivityScope; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.webapps.WebDisplayMode; import org.chromium.chrome.browser.webapps.WebappExtras; import org.chromium.components.security_state.ConnectionSecurityLevel; @@ -123,8 +124,7 @@ private @BrowserControlsState int computeBrowserControlsState(@Nullable Tab tab) { // Force browser controls to show when the security level is dangerous for consistency with // TabStateBrowserControlsVisibilityDelegate. - if (tab != null - && ((TabImpl) tab).getSecurityLevel() == ConnectionSecurityLevel.DANGEROUS) { + if (tab != null && getSecurityLevel(tab) == ConnectionSecurityLevel.DANGEROUS) { return BrowserControlsState.SHOWN; } @@ -139,4 +139,10 @@ private boolean isChildTab(@Nullable Tab tab) { return tab != null && tab.getParentId() != Tab.INVALID_TAB_ID; } + + @ConnectionSecurityLevel + @VisibleForTesting + int getSecurityLevel(Tab tab) { + return SecurityStateModel.getSecurityLevelForWebContents(tab.getWebContents()); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 34a09fa0..9a982f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -54,8 +54,8 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.page_info.PageInfoController; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.usage_stats.UsageStatsService; import org.chromium.chrome.browser.util.IntentUtils; @@ -366,10 +366,7 @@ return false; } - Tab tab = mTabProvider.getTab(); - if (tab != null && ((TabImpl) tab).isPreview()) { - return false; - } + if (Previews.isPreview(mTabProvider.getTab())) return false; String publisherUrlPackage = mConnection.getTrustedCdnPublisherUrlPackage(); return publisherUrlPackage != null
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java index 7b339eb..1e35418 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java
@@ -9,12 +9,11 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.dependency_injection.ActivityScope; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.components.security_state.ConnectionSecurityLevel; import javax.inject.Inject; @@ -65,7 +64,7 @@ @Override public void onDidAttachInterstitialPage(Tab tab) { - if (((TabImpl) tab).getSecurityLevel() != ConnectionSecurityLevel.DANGEROUS) return; + if (SecurityStateModel.isContentDangerous(tab.getWebContents())) return; mConnection.notifyNavigationEvent(mSessionToken, CustomTabsCallback.NAVIGATION_FAILED); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java index 5ec9d221..4b838ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java
@@ -22,12 +22,11 @@ import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler; import org.chromium.chrome.browser.share.ShareHelper; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHandle; @@ -180,7 +179,7 @@ @Override public void onDidAttachInterstitialPage(Tab tab) { - if (((TabImpl) tab).getSecurityLevel() != ConnectionSecurityLevel.DANGEROUS) return; + if (SecurityStateModel.isContentDangerous(tab.getWebContents())) return; resetPageLoadTracking(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java index a868bdfe..20e0add 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java
@@ -7,10 +7,13 @@ import static org.chromium.chrome.browser.ui.system.StatusBarColorController.DEFAULT_STATUS_BAR_COLOR; import static org.chromium.chrome.browser.ui.system.StatusBarColorController.UNDEFINED_STATUS_BAR_COLOR; +import androidx.annotation.VisibleForTesting; + import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarColorController; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarColorController.ToolbarColorType; import org.chromium.chrome.browser.dependency_injection.ActivityScope; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.system.StatusBarColorController; @@ -49,7 +52,7 @@ @ToolbarColorType int toolbarColorType = CustomTabToolbarColorController.computeToolbarColorType( - mIntentDataProvider, mUseTabThemeColor, tab); + mIntentDataProvider, mUseTabThemeColor, tab, () -> isPreview(tab)); switch (toolbarColorType) { case ToolbarColorType.THEME_COLOR: return UNDEFINED_STATUS_BAR_COLOR; @@ -60,4 +63,9 @@ } return DEFAULT_STATUS_BAR_COLOR; } + + @VisibleForTesting + boolean isPreview(Tab tab) { + return Previews.isPreview(tab); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java index 7452d36..9c8ced1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTaskDescriptionHelper.java
@@ -24,13 +24,13 @@ import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.lifecycle.NativeInitObserver; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabThemeColorHelper; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.chrome.browser.webapps.WebappExtras; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.NavigationHandle; import javax.inject.Inject; @@ -179,8 +179,7 @@ } private boolean hasSecurityWarningOrError(Tab tab) { - int securityLevel = ((TabImpl) tab).getSecurityLevel(); - return securityLevel == ConnectionSecurityLevel.DANGEROUS; + return SecurityStateModel.isContentDangerous(tab.getWebContents()); } }; mTabObserverRegistrar.registerActivityTabObserver(mIconTabObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java index 1ee962fd..8a3bdd0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java
@@ -19,12 +19,11 @@ import androidx.annotation.VisibleForTesting; import androidx.browser.customtabs.CustomTabsCallback; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabSelectionType; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.NavigationEntry; import org.chromium.net.NetError; @@ -126,7 +125,7 @@ @Override public void onDidAttachInterstitialPage(Tab tab) { - if (((TabImpl) tab).getSecurityLevel() != ConnectionSecurityLevel.DANGEROUS) return; + if (SecurityStateModel.isContentDangerous(tab.getWebContents())) return; notifyOnNavigationEvent(NAVIGATION_FAILED, getExtrasBundleForNavigationEvent(tab)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java index 004cd7c..7212f08 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
@@ -14,8 +14,8 @@ import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar.CustomTabTabObserver; import org.chromium.chrome.browser.dependency_injection.ActivityScope; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabThemeColorHelper; import org.chromium.chrome.browser.toolbar.ToolbarManager; @@ -43,6 +43,12 @@ int INTENT_TOOLBAR_COLOR = 2; } + /** + * Interface used to receive a predicate that tells if the current tab is in preview mode. + * This makes the {@link #computeToolbarColorType()} test-friendly. + */ + public interface BooleanFunction { boolean get(); } + private final BrowserServicesIntentDataProvider mIntentDataProvider; private final ChromeActivity mActivity; private final TabObserverRegistrar mTabObserverRegistrar; @@ -67,13 +73,12 @@ * surfaces with different values for {@link ToolbarColorType.DEFAULT_COLOR}. */ public static int computeToolbarColorType(BrowserServicesIntentDataProvider intentDataProvider, - boolean useTabThemeColor, @Nullable Tab tab) { + boolean useTabThemeColor, @Nullable Tab tab, BooleanFunction isPreview) { if (intentDataProvider.isOpenedByChrome()) { return (tab == null) ? ToolbarColorType.DEFAULT_COLOR : ToolbarColorType.THEME_COLOR; } - if (shouldUseDefaultThemeColorForFullscreen(intentDataProvider) - || (tab != null && ((TabImpl) tab).isPreview())) { + if (shouldUseDefaultThemeColorForFullscreen(intentDataProvider) || isPreview.get()) { return ToolbarColorType.DEFAULT_COLOR; } @@ -155,7 +160,8 @@ private int computeColor() { Tab tab = mTabProvider.getTab(); @ToolbarColorType - int toolbarColorType = computeToolbarColorType(mIntentDataProvider, mUseTabThemeColor, tab); + int toolbarColorType = computeToolbarColorType( + mIntentDataProvider, mUseTabThemeColor, tab, () -> Previews.isPreview(tab)); switch (toolbarColorType) { case ToolbarColorType.THEME_COLOR: assert tab != null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java index 51e676b1..b2472d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java
@@ -4,12 +4,9 @@ package org.chromium.chrome.browser.explore_sites; -import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Point; import android.view.LayoutInflater; import android.view.View; -import android.view.WindowManager; import android.widget.LinearLayout; import org.chromium.chrome.R; @@ -17,6 +14,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.PageTransition; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.mojom.WindowOpenDisposition; import java.util.List; @@ -61,11 +59,9 @@ // TODO(chili): Try to get this from view hierarchy. This gets called before the // mExploreSection is measured when opening ntp via 3 dot menu -> new tab, // causing a crash. Max width is set to tile grid max width. - Point screenSize = new Point(); - ((WindowManager) mExploreSection.getContext().getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getSize(screenSize); - int tileWidth = Math.min(screenSize.x, + int width = + DisplayAndroid.getNonMultiDisplay(mExploreSection.getContext()).getDisplayWidth(); + int tileWidth = Math.min(width, mExploreSection.getResources().getDimensionPixelSize( R.dimen.tile_grid_layout_max_width)) / MAX_TILES;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java index f15b561..fe9c8c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java
@@ -4,10 +4,7 @@ package org.chromium.chrome.browser.explore_sites; -import android.content.Context; import android.graphics.Bitmap; -import android.util.DisplayMetrics; -import android.view.WindowManager; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; @@ -15,6 +12,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.ui.display.DisplayAndroid; import java.util.ArrayList; import java.util.List; @@ -154,14 +152,8 @@ */ @CalledByNative static float getScaleFactorFromDevice() { - // Get DeviceMetrics from context. - DisplayMetrics metrics = new DisplayMetrics(); - ((WindowManager) ContextUtils.getApplicationContext().getSystemService( - Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getMetrics(metrics); - // Get density and return it. - return metrics.density; + return DisplayAndroid.getNonMultiDisplay(ContextUtils.getApplicationContext()) + .getDipScale(); } @NativeMethods
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java b/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java index 856df95..3e4fb583 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.feature_engagement; import android.Manifest; -import android.content.Context; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.database.Cursor; @@ -14,8 +13,6 @@ import android.provider.MediaStore; import android.provider.MediaStore.Images.Media; import android.support.v4.content.ContextCompat; -import android.util.DisplayMetrics; -import android.view.WindowManager; import androidx.annotation.VisibleForTesting; @@ -25,6 +22,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.PostTask; import org.chromium.content_public.browser.UiThreadTaskTraits; +import org.chromium.ui.display.DisplayAndroid; /** * This class detects screenshots by monitoring the screenshots directory on internal and external @@ -153,13 +151,10 @@ } // Check width and height. - DisplayMetrics displayMetrics = new DisplayMetrics(); - WindowManager windowManager = - (WindowManager) ContextUtils.getApplicationContext().getSystemService( - Context.WINDOW_SERVICE); - windowManager.getDefaultDisplay().getMetrics(displayMetrics); - int screenHeight = displayMetrics.heightPixels; - int screenWidth = displayMetrics.widthPixels; + DisplayAndroid display = + DisplayAndroid.getNonMultiDisplay(ContextUtils.getApplicationContext()); + int screenHeight = display.getDisplayWidth(); + int screenWidth = display.getDisplayHeight(); int imageHeight = Integer.parseInt(imageHeightString); int imageWidth = Integer.parseInt(imageWidthString);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java index e278aade..1552b85 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java
@@ -7,17 +7,16 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; -import org.chromium.base.ContextUtils; import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.init.ProcessInitializationHandler; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.content_public.browser.UiThreadTaskTraits; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -26,7 +25,6 @@ * the Chrome ToS so that we don't show the ToS string during our first run. */ public class ToSAckedReceiver extends BroadcastReceiver { - static final String TOS_ACKED_ACCOUNTS = "ToS acknowledged accounts"; static final String EXTRA_ACCOUNT_NAME = "TosAckedReceiver.account"; @Override @@ -38,13 +36,8 @@ String accountName = args.getString(EXTRA_ACCOUNT_NAME, null); if (accountName == null) return; - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - // Make sure to construct a new set so it can be modified safely. See crbug.com/568369. - Set<String> accounts = - new HashSet<String>(prefs.getStringSet(TOS_ACKED_ACCOUNTS, new HashSet<String>())); - accounts.add(accountName); - prefs.edit().remove(TOS_ACKED_ACCOUNTS).apply(); - prefs.edit().putStringSet(TOS_ACKED_ACCOUNTS, accounts).apply(); + SharedPreferencesManager prefs = SharedPreferencesManager.getInstance(); + prefs.addToStringSet(ChromePreferenceKeys.TOS_ACKED_ACCOUNTS, accountName); } /** @@ -54,9 +47,8 @@ public static boolean checkAnyUserHasSeenToS() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return false; - Set<String> toSAckedAccounts = - ContextUtils.getAppSharedPreferences().getStringSet( - TOS_ACKED_ACCOUNTS, null); + Set<String> toSAckedAccounts = SharedPreferencesManager.getInstance().readStringSet( + ChromePreferenceKeys.TOS_ACKED_ACCOUNTS, null); if (toSAckedAccounts == null || toSAckedAccounts.isEmpty()) return false; PostTask.runSynchronously(UiThreadTaskTraits.DEFAULT, () -> { ProcessInitializationHandler.getInstance().initializePreNative(); });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index c10593f..cd9e7b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -332,7 +332,6 @@ public static final String SEND_TAB_TO_SELF = "SyncSendTabToSelf"; public static final String SERVICE_MANAGER_FOR_DOWNLOAD = "ServiceManagerForDownload"; public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps"; - public static final String SETTINGS_MODERN_STATUS_BAR = "SettingsModernStatusBar"; public static final String SHARED_CLIPBOARD_UI = "SharedClipboardUI"; public static final String SHARING_QR_CODE_ANDROID = "SharingQrCodeAndroid"; public static final String SHOPPING_ASSIST = "ShoppingAssist";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java index cc8b622..01399b06 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java
@@ -65,6 +65,11 @@ initNavigationHandler( tab, createDelegate(tab), tab.getWebContents(), tab.isNativePage()); } + + @Override + public void onDestroyed(Tab tab) { + mTab = null; + } }; // We wouldn't hear about the first tab until the content changed or we switched tabs
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 74944e13..da378c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -42,7 +42,6 @@ import org.chromium.chrome.browser.payments.ui.SectionInformation; import org.chromium.chrome.browser.payments.ui.ShoppingCart; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.settings.MainPreferences; import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.Tab; @@ -2282,7 +2281,7 @@ return; } - SettingsLauncher.getInstance().launchSettingsPage(context, MainPreferences.class); + SettingsLauncher.getInstance().launchSettingsPage(context); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java index ea1ff1d..7d95bb80 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java
@@ -26,6 +26,7 @@ /* package */ class PaymentHandlerMediator extends WebContentsObserver implements BottomSheetObserver, PaymentHandlerToolbarObserver { private final PropertyModel mModel; + // Whenever invoked, invoked outside of the WebContentsObserver callbacks. private final Runnable mHider; // Postfixed with "Ref" to distinguish from mWebContent in WebContentsObserver. Although // referencing the same object, mWebContentsRef is preferable to WebContents here because @@ -33,6 +34,8 @@ // null. private final WebContents mWebContentsRef; private final PaymentHandlerUiObserver mPaymentHandlerUiObserver; + // Used to postpone execution of a callback to avoid destroy objects (e.g., WebContents) in + // their own methods. private final Handler mHandler = new Handler(); /** @@ -54,6 +57,14 @@ mPaymentHandlerUiObserver = observer; } + private void closeUIForInsecureNavigation() { + mHandler.post(() -> { + ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindowForInsecureNavigation( + mWebContentsRef); + mHider.run(); + }); + } + // BottomSheetObserver: @Override public void onSheetStateChanged(@SheetState int newState) { @@ -91,25 +102,23 @@ @Override public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) { if (!SslValidityChecker.isValidPageInPaymentHandlerWindow(mWebContentsRef)) { - ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindowForInsecureNavigation( - mWebContentsRef); - mHandler.post(mHider); + closeUIForInsecureNavigation(); } } @Override public void didAttachInterstitialPage() { - ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindowForInsecureNavigation( - mWebContentsRef); - mHandler.post(mHider); + closeUIForInsecureNavigation(); } @Override public void didFailLoad( boolean isMainFrame, int errorCode, String description, String failingUrl) { - // TODO(crbug.com/1017926): Respond to service worker with the net error. - ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContentsRef); - mHandler.post(mHider); + mHandler.post(() -> { + // TODO(crbug.com/1017926): Respond to service worker with the net error. + ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContentsRef); + mHider.run(); + }); } // PaymentHandlerToolbarObserver:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java index eb5f932b..aa62f1b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerView.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.thinwebview.ThinWebViewFactory; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContent; import org.chromium.components.embedder_support.view.ContentView; +import org.chromium.content_public.browser.RenderCoordinates; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.ActivityWindowAndroid; @@ -26,6 +27,7 @@ private final View mToolbarView; private final FrameLayout mContentView; private final ThinWebView mThinWebView; + private final WebContents mWebContents; private final Handler mReflowHandler = new Handler(); private final int mTabHeight; private final int mToolbarHeightPx; @@ -39,6 +41,7 @@ */ /* package */ PaymentHandlerView(ChromeActivity activity, WebContents webContents, ContentView webContentView, View toolbarView) { + mWebContents = webContents; mTabHeight = activity.getActivityTab().getView().getHeight(); mToolbarView = toolbarView; mToolbarHeightPx = @@ -107,7 +110,9 @@ @Override public int getVerticalScrollOffset() { - return 0; + return mWebContents == null + ? 0 + : RenderCoordinates.fromWebContents(mWebContents).getScrollYPixInt(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/previews/Previews.java b/chrome/android/java/src/org/chromium/chrome/browser/previews/Previews.java new file mode 100644 index 0000000..cfcdbc4d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/previews/Previews.java
@@ -0,0 +1,26 @@ +// Copyright 2019 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.previews; + +import org.chromium.chrome.browser.ssl.SecurityStateModel; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.content_public.browser.WebContents; + +/** + * Class for preview-related util methods. + */ +public final class Previews { + /** + * @param tab Tab object containing the WebContents. + * @return {@code true} if the page being displayed is a preview. + */ + public static boolean isPreview(Tab tab) { + if (tab == null || tab.isNativePage()) return false; + WebContents webContents = tab.getWebContents(); + return webContents != null && !webContents.isShowingInterstitialPage() + && !SecurityStateModel.isContentDangerous(webContents) + && PreviewsAndroidBridge.getInstance().shouldShowPreviewUI(webContents); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java index f158b056..b0ad47d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -30,7 +30,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.profiles.Profile; @@ -296,10 +295,6 @@ // On P+, the status bar color is set via the XML theme. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) return; - // Kill switch included due to past crashes when programmatically setting status bar color: - // https://crbug.com/880694. - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SETTINGS_MODERN_STATUS_BAR)) return; - if (UiUtils.isSystemUiThemingDisabled()) return; // Dark status icons only supported on M+.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java index 33b8db6..5953af8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java
@@ -38,6 +38,15 @@ } /** + * Launches the top-level settings page. + * + * @param context The current Activity, or an application context if no Activity is available. + */ + public void launchSettingsPage(Context context) { + launchSettingsPage(context, null); + } + + /** * Launches settings, either on the top-level page or on a subpage. * * @param context The current Activity, or an application context if no Activity is available.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/CookieControlsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/CookieControlsBridge.java new file mode 100644 index 0000000..e66c523 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/CookieControlsBridge.java
@@ -0,0 +1,72 @@ +// Copyright 2019 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.settings.website; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.content_public.browser.WebContents; + +/** + * Communicates between CookieControlsController (C++ backend) and PageInfoView (Java UI). + */ +public class CookieControlsBridge { + /** + * Interface for a class that wants to receive cookie updates from CookieControlsBridge. + */ + public interface CookieControlsView { + /** + * Called when the cookie blocking status for the current page changes. + * @param status An enum indicating the cookie blocking status. + */ + public void onCookieBlockingStatusChanged(@CookieControlsControllerStatus int status); + + /** + * Called when there is an update in the cookies that are currently being blocked. + * @param blockedCookies An integer indicating the number of cookies being blocked. + */ + public void onBlockedCookiesCountChanged(int blockedCookies); + } + + private long mNativeCookieControlsBridge; + private CookieControlsView mObserver; + + /** + * Initializes a CookieControlsBridge instance. + * @param observer An observer to call with updates from the cookie controller. + * @param webContents The WebContents instance to observe. + */ + public CookieControlsBridge(CookieControlsView observer, WebContents webContents) { + mObserver = observer; + mNativeCookieControlsBridge = + CookieControlsBridgeJni.get().init(CookieControlsBridge.this, webContents); + } + + /** + * Destroys the native counterpart of this class. + */ + public void destroy() { + if (mNativeCookieControlsBridge != 0) { + CookieControlsBridgeJni.get().destroy( + mNativeCookieControlsBridge, CookieControlsBridge.this); + mNativeCookieControlsBridge = 0; + } + } + + @CalledByNative + private void onCookieBlockingStatusChanged(@CookieControlsControllerStatus int status) { + mObserver.onCookieBlockingStatusChanged(status); + } + + @CalledByNative + private void onBlockedCookiesCountChanged(int blockedCookies) { + mObserver.onBlockedCookiesCountChanged(blockedCookies); + } + + @NativeMethods + interface Natives { + long init(CookieControlsBridge caller, WebContents webContents); + void destroy(long nativeCookieControlsBridge, CookieControlsBridge caller); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardShareActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardShareActivity.java index fc3776e..f959e65 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardShareActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardShareActivity.java
@@ -79,7 +79,7 @@ chromeSettingsButton.setVisibility(View.VISIBLE); chromeSettingsButton.setOnClickListener(view -> { SettingsLauncher.getInstance().launchSettingsPage( - ContextUtils.getApplicationContext(), null); + ContextUtils.getApplicationContext()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java b/chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java index 35218b96..a823479 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java
@@ -27,6 +27,10 @@ return SecurityStateModelJni.get().getSecurityLevelForWebContents(webContents); } + public static boolean isContentDangerous(WebContents webContents) { + return getSecurityLevelForWebContents(webContents) == ConnectionSecurityLevel.DANGEROUS; + } + /** * Returns whether to use a danger icon instead of an info icon in the URL bar for the WARNING * security level.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS index 913f8b5..28d1044 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -4,6 +4,8 @@ "+chrome/android/java/src/org/chromium/chrome/browser/TabHidingType.java", "+chrome/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java", "+chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java", + "+chrome/android/java/src/org/chromium/chrome/browser/previews/Previews.java", + "+chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java", "+chrome/android/java/src/org/chromium/chrome/browser/tab", "+chrome/android/java/src/org/chromium/chrome/browser/webapps/WebDisplayMode.java", "+chrome/browser/preferences", @@ -28,9 +30,7 @@ "+chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java", "+chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java", "+chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java", - "+chrome/android/java/src/org/chromium/chrome/browser/previews/PreviewsAndroidBridge.java", "+chrome/android/java/src/org/chromium/chrome/browser/rlz/RevenueStats.java", - "+chrome/android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java", "+chrome/android/java/src/org/chromium/chrome/browser/night_mode", "+chrome/android/public/profiles/java/src/org/chromium/chrome/browser/profiles/Profile.java", "+chrome/browser/util/android/java/src/org/chromium/chrome/browser/util/UrlConstants.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 8a9e7d8..80935d70 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -39,17 +39,14 @@ import org.chromium.chrome.browser.night_mode.NightModeUtils; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler; -import org.chromium.chrome.browser.previews.PreviewsAndroidBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.rlz.RevenueStats; -import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.tab.TabState.WebContentsState; import org.chromium.chrome.browser.tab.TabUma.TabCreationState; import org.chromium.chrome.browser.util.UrlConstants; import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.embedder_support.view.ContentView; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContents; @@ -724,23 +721,6 @@ } /** - * @return If the page being displayed is a Preview - */ - public boolean isPreview() { - return getWebContents() != null && !isNativePage() && !isShowingInterstitialPage() - && getSecurityLevel() != ConnectionSecurityLevel.DANGEROUS - && PreviewsAndroidBridge.getInstance().shouldShowPreviewUI(getWebContents()); - } - - /** - * @return The current {@link ConnectionSecurityLevel} for the tab. - */ - // TODO(tedchoc): Remove this and transition all clients to use LocationBarModel directly. - public int getSecurityLevel() { - return SecurityStateModel.getSecurityLevelForWebContents(getWebContents()); - } - - /** * @return Original url of the tab, which is the original url from DOMDistiller. */ public String getOriginalUrl() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java index b6a637a..5c785a36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java
@@ -10,10 +10,10 @@ import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.UrlConstants; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.ImeAdapter; import org.chromium.content_public.browser.ImeEventObserver; import org.chromium.content_public.browser.NavigationHandle; @@ -191,9 +191,8 @@ enableHidingBrowserControls &= !url.startsWith(UrlConstants.CHROME_URL_PREFIX); enableHidingBrowserControls &= !url.startsWith(UrlConstants.CHROME_NATIVE_URL_PREFIX); - int securityState = mTab.getSecurityLevel(); - enableHidingBrowserControls &= (securityState != ConnectionSecurityLevel.DANGEROUS); - + enableHidingBrowserControls &= + !SecurityStateModel.isContentDangerous(mTab.getWebContents()); enableHidingBrowserControls &= !SelectionPopupController.fromWebContents(webContents).isFocusedNodeEditable(); enableHidingBrowserControls &= !mTab.isShowingErrorPage();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabThemeColorHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabThemeColorHelper.java index ee00bba1..3a5fa73 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabThemeColorHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabThemeColorHelper.java
@@ -10,6 +10,8 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.UserData; +import org.chromium.chrome.browser.previews.Previews; +import org.chromium.chrome.browser.ssl.SecurityStateModel; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.security_state.ConnectionSecurityLevel; @@ -152,14 +154,15 @@ */ private boolean checkThemingAllowed() { // Do not apply the theme color if there are any security issues on the page. - final int securityLevel = mTab.getSecurityLevel(); + final int securityLevel = + SecurityStateModel.getSecurityLevelForWebContents(mTab.getWebContents()); return securityLevel != ConnectionSecurityLevel.DANGEROUS && securityLevel != ConnectionSecurityLevel.SECURE_WITH_POLICY_INSTALLED_CERT && (mTab.getActivity() == null || !mTab.getActivity().isTablet()) && (mTab.getActivity() == null || !mTab.getActivity().getNightModeStateProvider().isInNightMode()) && !mTab.isNativePage() && !mTab.isShowingInterstitialPage() && !mTab.isIncognito() - && !mTab.isPreview(); + && !Previews.isPreview(mTab); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java index 7129f75..cb70184 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java
@@ -70,7 +70,7 @@ @IdentityDiscState private int mState = IdentityDiscState.NONE; - private boolean mIsNTPVisible; + private boolean mShouldShowButton; /** * Creates IdentityDiscController object. @@ -98,23 +98,23 @@ } /** - * Shows/hides Identity Disc depending on whether NTP is visible. + * Shows/hides Identity Disc. */ void updateButtonState() { - updateButtonState(mIsNTPVisible); + updateButtonState(mShouldShowButton); } /** - * Shows/hides Identity Disc depending on whether NTP is visible. + * @param shouldShowButton Whether to show the Identity Disc. */ - void updateButtonState(boolean isNTPVisible) { - mIsNTPVisible = isNTPVisible; + void updateButtonState(boolean shouldShowButton) { + mShouldShowButton = shouldShowButton; String accountName = ChromeSigninController.get().getSignedInAccountName(); - boolean shouldShowIdentityDisc = isNTPVisible && accountName != null; + boolean canShowIdentityDisc = mShouldShowButton && accountName != null; @IdentityDiscState int oldState = mState; - mState = !shouldShowIdentityDisc + mState = !canShowIdentityDisc ? IdentityDiscState.NONE : mToolbarManager.isBottomToolbarVisible() ? IdentityDiscState.LARGE : IdentityDiscState.SMALL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java index 32ea61be..9456896 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils; import org.chromium.chrome.browser.omnibox.UrlBarData; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.previews.PreviewsAndroidBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ssl.SecurityStateModel; @@ -343,7 +344,7 @@ @Override public boolean isPreview() { - return hasTab() && ((TabImpl) mTab).isPreview(); + return hasTab() && Previews.isPreview(mTab); } @Override @@ -377,19 +378,25 @@ @VisibleForTesting @ConnectionSecurityLevel - static int getSecurityLevel(Tab tab, boolean isOfflinePage, @Nullable String publisherUrl) { + int getSecurityLevel(Tab tab, boolean isOfflinePage, @Nullable String publisherUrl) { if (tab == null || isOfflinePage) { return ConnectionSecurityLevel.NONE; } - int securityLevel = ((TabImpl) tab).getSecurityLevel(); if (publisherUrl != null) { - assert securityLevel != ConnectionSecurityLevel.DANGEROUS; + assert getSecurityLevelFromStateModel(tab.getWebContents()) + != ConnectionSecurityLevel.DANGEROUS; return (URI.create(publisherUrl).getScheme().equals(UrlConstants.HTTPS_SCHEME)) ? ConnectionSecurityLevel.SECURE : ConnectionSecurityLevel.WARNING; } - return securityLevel; + return getSecurityLevelFromStateModel(tab.getWebContents()); + } + + @VisibleForTesting + @ConnectionSecurityLevel + int getSecurityLevelFromStateModel(WebContents webContents) { + return SecurityStateModel.getSecurityLevelForWebContents(webContents); } @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java index b58585db..dcd52f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java
@@ -18,9 +18,9 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.FeatureUtilities; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; import org.chromium.chrome.browser.ui.widget.highlight.ViewHighlighter; @@ -66,13 +66,13 @@ - mDataSavedOnStartPageLoad; Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); if (dataSaved > 0L) tracker.notifyEvent(EventConstants.DATA_SAVED_ON_PAGE_LOAD); - if (((TabImpl) tab).isPreview()) { + if (Previews.isPreview(tab)) { tracker.notifyEvent(EventConstants.PREVIEWS_PAGE_LOADED); } if (tab.isUserInteractable()) { maybeShowDataSaverDetail(); if (dataSaved > 0L) maybeShowDataSaverMilestonePromo(); - if (((TabImpl) tab).isPreview()) maybeShowPreviewVerboseStatus(); + if (Previews.isPreview(tab)) maybeShowPreviewVerboseStatus(); } } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 98a9423e4..b87532b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -73,6 +73,7 @@ import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; +import org.chromium.chrome.browser.previews.Previews; import org.chromium.chrome.browser.previews.PreviewsAndroidBridge; import org.chromium.chrome.browser.previews.PreviewsUma; import org.chromium.chrome.browser.profiles.Profile; @@ -251,6 +252,9 @@ private int mCurrentOrientation; + @OverviewModeState + private int mOverviewModeState = OverviewModeState.NOT_SHOWN; + /** * Runnable for the home and search accelerator button when Start Surface home page is enabled. */ @@ -470,7 +474,7 @@ } // TODO(crbug.com/896476): Remove this. - if (((TabImpl) tab).isPreview()) { + if (Previews.isPreview(tab)) { // Some previews (like Client LoFi) are not fully decided until the page // finishes loading. If this is a preview, update the security icon which will // also update the verbose status view to make sure the "Lite" badge is @@ -604,7 +608,7 @@ mToolbar.onNavigatedToDifferentPage(); } - if (navigation.hasCommitted() && ((TabImpl) tab).isPreview()) { + if (navigation.hasCommitted() && Previews.isPreview(tab)) { // Some previews are not fully decided until the page commits. If this // is a preview, update the security icon which will also update the verbose // status view to make sure the "Lite" badge is displayed. @@ -735,7 +739,11 @@ @Override public void onOverviewModeStateChanged( @OverviewModeState int overviewModeState, boolean showTabSwitcherToolbar) { + assert FeatureUtilities.isStartSurfaceEnabled(); mToolbar.updateTabSwitcherToolbarState(showTabSwitcherToolbar); + mOverviewModeState = overviewModeState; + mIdentityDiscController.updateButtonState( + mOverviewModeState == OverviewModeState.SHOWN_HOMEPAGE); } @Override @@ -757,6 +765,7 @@ @Override public void onOverviewModeFinishedHiding() { mToolbar.onTabSwitcherTransitionFinished(); + updateButtonStatus(); } }; @@ -1880,8 +1889,12 @@ if (mToolbar.getMenuButtonWrapper() != null && !isBottomToolbarVisible()) { mToolbar.getMenuButtonWrapper().setVisibility(View.VISIBLE); } + + // TODO(crbug.com/1041475): Separate enabling the IdentityDiscController from enabling the + // ExperimentalButton. mIdentityDiscController.updateButtonState( - mLocationBarModel.getNewTabPageForCurrentTab() != null); + mLocationBarModel.getNewTabPageForCurrentTab() != null + || mOverviewModeState == OverviewModeState.SHOWN_HOMEPAGE); } private void updateBookmarkButtonStatus() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java index 41154771..31ad72d3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -4,9 +4,12 @@ package org.chromium.chrome.browser.toolbar.top; +import android.graphics.drawable.Drawable; import android.view.View; import android.view.ViewStub; +import androidx.annotation.StringRes; + import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.incognito.IncognitoUtils; @@ -113,6 +116,43 @@ mToolbarMediator.setOverviewModeBehavior(overviewModeBehavior); } + /** + * Enable the experimental toolbar button. + * @param onClickListener The {@link OnClickListener} to be called when the button is clicked. + * @param image The drawable to display for the button. + * @param contentDescriptionResId The resource id of the content description for the button. + */ + void enableExperimentalButton(View.OnClickListener onClickListener, Drawable image, + @StringRes int contentDescriptionResId) { + mToolbarMediator.enableIdentityDisc(onClickListener, image, contentDescriptionResId); + } + + /** + * Updates image displayed on experimental button. + * @param image The new image for the button. + */ + void updateExperimentalButtonImage(Drawable image) { + mToolbarMediator.updateIdentityDiscImage(image); + } + + /** + * Disable the experimental toolbar button. + */ + void disableExperimentalButton() { + mToolbarMediator.disableIdentityDisc(); + } + + /** + * Displays in-product help for experimental button. + * @param stringId The id of the string resource for the text that should be shown. + * @param accessibilityStringId The id of the string resource of the accessibility text. + * @param dismissedCallback The callback that will be called when in-product help is dismissed. + */ + void showIPHOnExperimentalButton(@StringRes int stringId, @StringRes int accessibilityStringId, + Runnable dismissedCallback) { + mToolbarMediator.showIPHOnIdentityDisc(stringId, accessibilityStringId, dismissedCallback); + } + void onNativeLibraryReady() { mToolbarMediator.onNativeLibraryReady(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java index 700e09a..003f273 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
@@ -7,6 +7,11 @@ import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.ACCESSIBILITY_ENABLED; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.APP_MENU_BUTTON_HELPER; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_DESCRIPTION; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IMAGE; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IPH; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IS_VISIBLE; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.INCOGNITO_STATE_PROVIDER; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IS_INCOGNITO; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IS_VISIBLE; @@ -15,8 +20,11 @@ import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.NEW_TAB_BUTTON_IS_VISIBLE; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.NEW_TAB_CLICK_HANDLER; +import android.graphics.drawable.Drawable; import android.view.View; +import androidx.annotation.StringRes; + import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; @@ -27,6 +35,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.toolbar.IncognitoStateProvider; +import org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IPHContainer; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver; @@ -43,6 +52,7 @@ @OverviewModeState private int mOverviewModeState; private boolean mIsGoogleSearchEngine; + private boolean mEnableIdentityDisc; StartSurfaceToolbarMediator(PropertyModel model) { mPropertyModel = model; @@ -93,10 +103,12 @@ @Override public void onTabModelSelected(TabModel newModel, TabModel oldModel) { mPropertyModel.set(IS_INCOGNITO, mTabModelSelector.isIncognitoSelected()); + updateIdentityDiscVisibility(); } }; } mPropertyModel.set(IS_INCOGNITO, mTabModelSelector.isIncognitoSelected()); + updateIdentityDiscVisibility(); mTabModelSelector.addObserver(mTabModelSelectorObserver); } @@ -131,6 +143,7 @@ mOverviewModeState = overviewModeState; updateNewTabButtonVisibility(); updateLogoVisibility(mIsGoogleSearchEngine); + updateIdentityDiscVisibility(); } @Override public void onOverviewModeFinishedShowing() { @@ -156,6 +169,35 @@ mPropertyModel.set(LOGO_IS_VISIBLE, shouldShowLogo); } + void enableIdentityDisc(View.OnClickListener onClickListener, Drawable image, + @StringRes int contentDescriptionResId) { + mEnableIdentityDisc = true; + mPropertyModel.set(IDENTITY_DISC_CLICK_HANDLER, onClickListener); + mPropertyModel.set(IDENTITY_DISC_IMAGE, image); + mPropertyModel.set(IDENTITY_DISC_DESCRIPTION, contentDescriptionResId); + updateIdentityDiscVisibility(); + } + + void updateIdentityDiscImage(Drawable image) { + mPropertyModel.set(IDENTITY_DISC_IMAGE, image); + } + + void disableIdentityDisc() { + mEnableIdentityDisc = false; + mPropertyModel.set(IDENTITY_DISC_IS_VISIBLE, false); + } + + void showIPHOnIdentityDisc(@StringRes int stringId, @StringRes int accessibilityStringId, + Runnable dismissedCallback) { + // Only show IPH if IdentityDisc is actually visible, otherwise dismiss. + if (mPropertyModel.get(IDENTITY_DISC_IS_VISIBLE)) { + mPropertyModel.set(IDENTITY_DISC_IPH, + new IPHContainer(stringId, accessibilityStringId, dismissedCallback)); + } else if (dismissedCallback != null) { + dismissedCallback.run(); + } + } + private void updateNewTabButtonVisibility() { // This toolbar is only shown for tab switcher when accessibility is enabled. Note that // OverviewListLayout will be shown as the tab switcher instead of the star surface. @@ -164,4 +206,10 @@ || AccessibilityUtil.isAccessibilityEnabled(); mPropertyModel.set(NEW_TAB_BUTTON_IS_VISIBLE, isShownTabswitcherState); } + + private void updateIdentityDiscVisibility() { + mPropertyModel.set(IDENTITY_DISC_IS_VISIBLE, + mOverviewModeState == OverviewModeState.SHOWN_HOMEPAGE && mEnableIdentityDisc + && !mTabModelSelector.isIncognitoSelected()); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java index f0e98d9..5910af2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java
@@ -4,8 +4,11 @@ package org.chromium.chrome.browser.toolbar.top; +import android.graphics.drawable.Drawable; import android.view.View; +import androidx.annotation.StringRes; + import org.chromium.chrome.browser.toolbar.IncognitoStateProvider; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.ui.modelutil.PropertyKey; @@ -13,6 +16,21 @@ /** List of the start surface toolbar properties. */ class StartSurfaceToolbarProperties { + public static class IPHContainer { + @StringRes + public final int stringId; + @StringRes + public final int accessibilityStringId; + public Runnable dismissedCallback; + + IPHContainer(@StringRes int stringId, @StringRes int accessibilityStringId, + Runnable dismissedCallback) { + this.stringId = stringId; + this.accessibilityStringId = accessibilityStringId; + this.dismissedCallback = dismissedCallback; + } + } + private StartSurfaceToolbarProperties() {} public static final PropertyModel @@ -24,6 +42,17 @@ public static final PropertyModel .WritableObjectPropertyKey<View.OnClickListener> NEW_TAB_CLICK_HANDLER = new PropertyModel.WritableObjectPropertyKey<View.OnClickListener>(); + public static final PropertyModel + .WritableObjectPropertyKey<View.OnClickListener> IDENTITY_DISC_CLICK_HANDLER = + new PropertyModel.WritableObjectPropertyKey<View.OnClickListener>(); + public static final PropertyModel.WritableObjectPropertyKey<Drawable> IDENTITY_DISC_IMAGE = + new PropertyModel.WritableObjectPropertyKey<Drawable>(); + public static final PropertyModel.WritableIntPropertyKey IDENTITY_DISC_DESCRIPTION = + new PropertyModel.WritableIntPropertyKey(); + public static final PropertyModel.WritableObjectPropertyKey<IPHContainer> IDENTITY_DISC_IPH = + new PropertyModel.WritableObjectPropertyKey<IPHContainer>(); + public static final PropertyModel.WritableBooleanPropertyKey IDENTITY_DISC_IS_VISIBLE = + new PropertyModel.WritableBooleanPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey IS_VISIBLE = new PropertyModel.WritableBooleanPropertyKey(); public static final PropertyModel.WritableBooleanPropertyKey LOGO_IS_VISIBLE = @@ -42,5 +71,7 @@ public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {APP_MENU_BUTTON_HELPER, NEW_TAB_CLICK_HANDLER, IS_VISIBLE, LOGO_IS_VISIBLE, IS_INCOGNITO, INCOGNITO_STATE_PROVIDER, ACCESSIBILITY_ENABLED, - MENU_IS_VISIBLE, NEW_TAB_BUTTON_IS_VISIBLE, BUTTONS_CLICKABLE}; + MENU_IS_VISIBLE, NEW_TAB_BUTTON_IS_VISIBLE, BUTTONS_CLICKABLE, + IDENTITY_DISC_IS_VISIBLE, IDENTITY_DISC_CLICK_HANDLER, IDENTITY_DISC_IMAGE, + IDENTITY_DISC_DESCRIPTION, IDENTITY_DISC_IPH}; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java index 6cd5a00..d8f75c43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java
@@ -7,17 +7,24 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.support.v7.content.res.AppCompatResources; import android.util.AttributeSet; import android.view.View; +import android.widget.ImageButton; import android.widget.RelativeLayout; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.toolbar.IncognitoStateProvider; import org.chromium.chrome.browser.toolbar.MenuButton; import org.chromium.chrome.browser.toolbar.NewTabButton; +import org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IPHContainer; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; +import org.chromium.chrome.browser.ui.widget.textbubble.TextBubble; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.components.browser_ui.styles.ChromeColors; @@ -27,6 +34,8 @@ private View mIncognitoSwitch; private MenuButton mMenuButton; private View mLogo; + @Nullable + private ImageButton mIdentityDiscButton; private int mPrimaryColor; private ColorStateList mLightIconTint; private ColorStateList mDarkIconTint; @@ -46,6 +55,13 @@ mIncognitoSwitch = findViewById(R.id.incognito_switch); mMenuButton = findViewById(R.id.menu_button_wrapper); mLogo = findViewById(R.id.logo); + mIdentityDiscButton = findViewById(R.id.experimental_toolbar_button_start); + + // Change padding in layout file programmatically, since padding in layout file can not be + // changed in ViewStub. + final int buttonPadding = getContext().getResources().getDimensionPixelOffset( + R.dimen.start_surface_toolbar_button_padding_to_button); + mIdentityDiscButton.setPadding(buttonPadding, 0, buttonPadding, 0); updatePrimaryColorAndTint(false); } @@ -100,6 +116,14 @@ */ void setMenuButtonVisibility(boolean isVisible) { mMenuButton.setVisibility(isVisible ? View.VISIBLE : View.GONE); + final int buttonPaddingLeft = getContext().getResources().getDimensionPixelOffset( + R.dimen.start_surface_toolbar_button_padding_to_button); + final int buttonPaddingRight = + (isVisible ? buttonPaddingLeft + : getContext().getResources().getDimensionPixelOffset( + R.dimen.start_surface_toolbar_button_padding_to_edge)); + mIdentityDiscButton.setPadding(buttonPaddingLeft, 0, buttonPaddingRight, 0); + mNewTabButton.setPadding(buttonPaddingLeft, 0, buttonPaddingRight, 0); } /** @@ -135,6 +159,52 @@ mNewTabButton.onAccessibilityStatusChanged(); } + /** + * @param isVisible Whether the identity disc is visible. + */ + void setIdentityDiscVisibility(boolean isVisible) { + mIdentityDiscButton.setVisibility(isVisible ? View.VISIBLE : View.GONE); + } + + /** + * Sets the {@link OnClickListener} that will be notified when the identity disc button is + * pressed. + * @param listener The callback that will be notified when the identity disc is pressed. + */ + void setIdentityDiscClickHandler(View.OnClickListener listener) { + mIdentityDiscButton.setOnClickListener(listener); + } + + /** + * Updates the image displayed on the identity disc button. + * @param image The new image for the button. + */ + void setIdentityDiscImage(Drawable image) { + mIdentityDiscButton.setImageDrawable(image); + } + + /** + * Updates idnetity disc content description. + * @param contentDescriptionResId The new description for the button. + */ + void setIdentityDiscContentDescription(@StringRes int contentDescriptionResId) { + mIdentityDiscButton.setContentDescription( + getContext().getResources().getString(contentDescriptionResId)); + } + + /** + * Show the IPH for the identity disc button. + */ + void showIPHOnIdentityDisc(IPHContainer iphContainer) { + TextBubble textBubble = new TextBubble(getContext(), mIdentityDiscButton, + iphContainer.stringId, iphContainer.accessibilityStringId, mIdentityDiscButton); + textBubble.setDismissOnTouchInteraction(true); + if (iphContainer.dismissedCallback != null) { + textBubble.addOnDismissListener(() -> { iphContainer.dismissedCallback.run(); }); + } + textBubble.show(); + } + private void updatePrimaryColorAndTint(boolean isIncognito) { int primaryColor = ChromeColors.getPrimaryBackgroundColor(getResources(), isIncognito); setBackgroundColor(primaryColor);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java index 5cf9299..9928553 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java
@@ -7,6 +7,11 @@ import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.ACCESSIBILITY_ENABLED; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.APP_MENU_BUTTON_HELPER; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_DESCRIPTION; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IMAGE; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IPH; +import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IS_VISIBLE; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.INCOGNITO_STATE_PROVIDER; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IS_INCOGNITO; import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IS_VISIBLE; @@ -24,24 +29,34 @@ class StartSurfaceToolbarViewBinder { public static void bind( PropertyModel model, StartSurfaceToolbarView view, PropertyKey propertyKey) { - if (propertyKey == APP_MENU_BUTTON_HELPER) { + if (propertyKey == ACCESSIBILITY_ENABLED) { + view.onAccessibilityStatusChanged(model.get(ACCESSIBILITY_ENABLED)); + } else if (propertyKey == APP_MENU_BUTTON_HELPER) { view.setAppMenuButtonHelper(model.get(APP_MENU_BUTTON_HELPER)); } else if (propertyKey == BUTTONS_CLICKABLE) { view.setButtonClickableState(model.get(BUTTONS_CLICKABLE)); - } else if (propertyKey == NEW_TAB_CLICK_HANDLER) { - view.setOnNewTabClickHandler(model.get(NEW_TAB_CLICK_HANDLER)); + } else if (propertyKey == IDENTITY_DISC_CLICK_HANDLER) { + view.setIdentityDiscClickHandler(model.get(IDENTITY_DISC_CLICK_HANDLER)); + } else if (propertyKey == IDENTITY_DISC_DESCRIPTION) { + view.setIdentityDiscContentDescription(model.get(IDENTITY_DISC_DESCRIPTION)); + } else if (propertyKey == IDENTITY_DISC_IMAGE) { + view.setIdentityDiscImage(model.get(IDENTITY_DISC_IMAGE)); + } else if (propertyKey == IDENTITY_DISC_IPH) { + view.showIPHOnIdentityDisc(model.get(IDENTITY_DISC_IPH)); + } else if (propertyKey == IDENTITY_DISC_IS_VISIBLE) { + view.setIdentityDiscVisibility(model.get(IDENTITY_DISC_IS_VISIBLE)); + } else if (propertyKey == INCOGNITO_STATE_PROVIDER) { + view.setIncognitoStateProvider(model.get(INCOGNITO_STATE_PROVIDER)); + } else if (propertyKey == IS_INCOGNITO) { + view.updateIncognito(model.get(IS_INCOGNITO)); } else if (propertyKey == IS_VISIBLE) { view.setVisibility(model.get(IS_VISIBLE) ? View.VISIBLE : View.GONE); } else if (propertyKey == LOGO_IS_VISIBLE) { view.setLogoVisibility(model.get(LOGO_IS_VISIBLE)); - } else if (propertyKey == IS_INCOGNITO) { - view.updateIncognito(model.get(IS_INCOGNITO)); - } else if (propertyKey == INCOGNITO_STATE_PROVIDER) { - view.setIncognitoStateProvider(model.get(INCOGNITO_STATE_PROVIDER)); - } else if (propertyKey == ACCESSIBILITY_ENABLED) { - view.onAccessibilityStatusChanged(model.get(ACCESSIBILITY_ENABLED)); } else if (propertyKey == MENU_IS_VISIBLE) { view.setMenuButtonVisibility(model.get(MENU_IS_VISIBLE)); + } else if (propertyKey == NEW_TAB_CLICK_HANDLER) { + view.setOnNewTabClickHandler(model.get(NEW_TAB_CLICK_HANDLER)); } else if (propertyKey == NEW_TAB_BUTTON_IS_VISIBLE) { view.setNewTabButtonVisibility(model.get(NEW_TAB_BUTTON_IS_VISIBLE)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 899c7d9..cf59c43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -625,6 +625,10 @@ */ public void enableExperimentalButton(View.OnClickListener onClickListener, Drawable image, @StringRes int contentDescriptionResId) { + if (FeatureUtilities.isStartSurfaceSinglePaneEnabled()) { + mStartSurfaceToolbarCoordinator.enableExperimentalButton( + onClickListener, image, contentDescriptionResId); + } mToolbarLayout.enableExperimentalButton(onClickListener, image, contentDescriptionResId); } @@ -644,6 +648,9 @@ * @return The experimental toolbar button if it exists. */ public void updateExperimentalButtonImage(Drawable image) { + if (FeatureUtilities.isStartSurfaceSinglePaneEnabled()) { + mStartSurfaceToolbarCoordinator.updateExperimentalButtonImage(image); + } mToolbarLayout.updateExperimentalButtonImage(image); } @@ -651,6 +658,9 @@ * Disable the experimental toolbar button. */ public void disableExperimentalButton() { + if (FeatureUtilities.isStartSurfaceSinglePaneEnabled()) { + mStartSurfaceToolbarCoordinator.disableExperimentalButton(); + } mToolbarLayout.disableExperimentalButton(); } @@ -662,6 +672,12 @@ */ public void showIPHOnExperimentalButton(@StringRes int stringId, @StringRes int accessibilityStringId, Runnable dismissedCallback) { + if (mStartSurfaceToolbarCoordinator != null + && mToolbarLayout.getToolbarDataProvider().isInOverviewAndShowingOmnibox()) { + mStartSurfaceToolbarCoordinator.showIPHOnExperimentalButton( + stringId, accessibilityStringId, dismissedCallback); + return; + } mToolbarLayout.showIPHOnExperimentalButton( stringId, accessibilityStringId, dismissedCallback); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArImmersiveOverlay.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArImmersiveOverlay.java index cf153b8..4a1b9c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArImmersiveOverlay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArImmersiveOverlay.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.ScreenOrientationDelegate; import org.chromium.content_public.browser.ScreenOrientationProvider; +import org.chromium.ui.display.DisplayAndroidManager; import org.chromium.ui.widget.Toast; /** @@ -234,8 +235,9 @@ // transport even if the currently-visible part in the surface view is smaller than this. We // shouldn't get resize events since we're using FLAG_LAYOUT_STABLE and are locking screen // orientation. + Display display = DisplayAndroidManager.getDefaultDisplayForContext(mActivity); if (mSurfaceReportedReady) { - int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + int rotation = display.getRotation(); if (DEBUG_LOGS) { Log.i(TAG, "surfaceChanged ignoring change to width=" + width + " height=" + height @@ -268,7 +270,6 @@ // after the session starts, but the session doesn't start until we report the drawing // surface being ready (including a configured size), so we use this reported size assuming // that's what the fullscreen mode will use. - Display display = mActivity.getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getRealSize(size); @@ -282,7 +283,7 @@ height = size.y; } - int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + int rotation = display.getRotation(); if (DEBUG_LOGS) { Log.i(TAG, "surfaceChanged size=" + width + "x" + height + " rotation=" + rotation); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java index afe0407d..6fc7990 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
@@ -21,14 +21,12 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ApplicationTestUtils; import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.components.security_state.ConnectionSecurityLevel; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -136,13 +134,4 @@ Assert.assertFalse(mTab.needsReload()); Assert.assertFalse(isShowingSadTab()); } - - @Test - @SmallTest - @Feature({"Tab"}) - public void testTabSecurityLevel() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertEquals(ConnectionSecurityLevel.NONE, ((TabImpl) mTab).getSecurityLevel()); - }); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarIntegrationTest.java index b2c25de6..1b2a7b6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarIntegrationTest.java
@@ -157,7 +157,7 @@ @Test @SmallTest @Feature({"Omnibox"}) - // TODO(crbug.com/1048469): Investigate and enable this test for the search engine logo feature. + // TODO(crbug.com/1028469): Investigate and enable this test for the search engine logo feature. @DisableFeatures("OmniboxSearchEngineLogo") @RetryOnFailure public void testLongPress() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/CookieControlsBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/CookieControlsBridgeTest.java new file mode 100644 index 0000000..37cb1cf98 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/CookieControlsBridgeTest.java
@@ -0,0 +1,233 @@ +// Copyright 2019 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.settings.website; + +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.RetryOnFailure; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.components.content_settings.ContentSettingsType; +import org.chromium.components.content_settings.CookieControlsMode; +import org.chromium.content_public.browser.test.util.JavaScriptUtils; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.net.test.EmbeddedTestServer; + +/** + * Integration tests for CookieControlsBridge. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@EnableFeatures(ChromeFeatureList.IMPROVED_COOKIE_CONTROLS) +public class CookieControlsBridgeTest { + private class TestCallbackHandler implements CookieControlsBridge.CookieControlsView { + private CallbackHelper mHelper; + + public TestCallbackHandler(CallbackHelper helper) { + mHelper = helper; + } + + @Override + public void onCookieBlockingStatusChanged(@CookieControlsControllerStatus int status) { + mStatus = status; + mHelper.notifyCalled(); + } + + @Override + public void onBlockedCookiesCountChanged(int blockedCookies) { + mBlockedCookies = blockedCookies; + mHelper.notifyCalled(); + } + } + + @Rule + public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = + new ChromeActivityTestRule<>(ChromeActivity.class); + private EmbeddedTestServer mTestServer; + private CallbackHelper mCallbackHelper; + private TestCallbackHandler mCallbackHandler; + private CookieControlsBridge mCookieControlsBridge; + private int mStatus; + private int mBlockedCookies; + + @Before + public void setUp() throws Exception { + mCallbackHelper = new CallbackHelper(); + mCallbackHandler = new TestCallbackHandler(mCallbackHelper); + mActivityTestRule.startMainActivityOnBlankPage(); + mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); + mStatus = CookieControlsControllerStatus.UNINITIALIZED; + mBlockedCookies = -1; + } + + @After + public void tearDown() { + mTestServer.stopAndDestroyServer(); + } + + /** + * Test two callbacks (one for status disabled, one for blocked cookies count) if cookie + * controls is off. + */ + @Test + @SmallTest + @RetryOnFailure + public void testCookieBridgeWithTPCookiesDisabled() throws Exception { + int expectedCookiesToBlock = 0; + int expectedStatus = CookieControlsControllerStatus.DISABLED; + TestThreadUtils.runOnUiThreadBlocking(() -> { + // Set CookieControlsMode Pref to Off + PrefServiceBridge.getInstance().setInteger( + Pref.COOKIE_CONTROLS_MODE, CookieControlsMode.OFF); + }); + int currentCallCount = mCallbackHelper.getCallCount(); + + // Navigate to a page + final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + Tab tab = mActivityTestRule.loadUrlInNewTab(url, false); + + // Create cookie bridge and wait for desired callbacks. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCookieControlsBridge = + new CookieControlsBridge(mCallbackHandler, tab.getWebContents()); + }); + + mCallbackHelper.waitForCallback(currentCallCount, 2); + Assert.assertEquals(expectedStatus, mStatus); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + } + + /** + * Test two callbacks (one for status enabled, one for blocked cookies count) if cookie controls + * is on. No cookies trying to be set. + */ + @Test + @SmallTest + @RetryOnFailure + public void testCookieBridgeWith3PCookiesEnabled() throws Exception { + int expectedCookiesToBlock = 0; + int expectedStatus = CookieControlsControllerStatus.ENABLED; + TestThreadUtils.runOnUiThreadBlocking(() -> { + // Set CookieControlsMode Pref to On + PrefServiceBridge.getInstance().setInteger( + Pref.COOKIE_CONTROLS_MODE, CookieControlsMode.ON); + }); + int currentCallCount = mCallbackHelper.getCallCount(); + + // Navigate to a page + final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + Tab tab = mActivityTestRule.loadUrlInNewTab(url, false); + + // Create cookie bridge and wait for desired callbacks. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCookieControlsBridge = + new CookieControlsBridge(mCallbackHandler, tab.getWebContents()); + }); + + mCallbackHelper.waitForCallback(currentCallCount, 2); + Assert.assertEquals(expectedStatus, mStatus); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + } + + /** + * Test blocked cookies count changes when new cookie tries to be set. Only one callback because + * status remains enabled. + */ + @Test + @SmallTest + @RetryOnFailure + public void testCookieBridgeWithChangingBlockedCookiesCount() throws Exception { + int expectedCookiesToBlock = 0; + int expectedStatus = CookieControlsControllerStatus.ENABLED; + TestThreadUtils.runOnUiThreadBlocking(() -> { + // Set CookieControlsMode Pref to On + PrefServiceBridge.getInstance().setInteger( + Pref.COOKIE_CONTROLS_MODE, CookieControlsMode.ON); + // Block all cookies + WebsitePreferenceBridge.setCategoryEnabled(ContentSettingsType.COOKIES, false); + }); + int currentCallCount = mCallbackHelper.getCallCount(); + + // Navigate to a page + final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + Tab tab = mActivityTestRule.loadUrlInNewTab(url, false); + + // Create cookie bridge and wait for desired callbacks. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCookieControlsBridge = + new CookieControlsBridge(mCallbackHandler, tab.getWebContents()); + }); + + mCallbackHelper.waitForCallback(currentCallCount, 2); + Assert.assertEquals(expectedStatus, mStatus); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + + // Try to set a cookie on the page when cookies are blocked. + currentCallCount = mCallbackHelper.getCallCount(); + expectedCookiesToBlock = 1; + JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(), "setCookie()"); + mCallbackHelper.waitForCallback(currentCallCount, 1); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + } + + /** + * Test blocked cookies works with CookieControlsMode.INCOGNITO_ONLY. + */ + @Test + @SmallTest + @RetryOnFailure + public void testCookieBridgeWithIncognitoSetting() throws Exception { + int expectedCookiesToBlock = 0; + int expectedStatus = CookieControlsControllerStatus.DISABLED; + TestThreadUtils.runOnUiThreadBlocking(() -> { + // Set CookieControlsMode Pref to IncognitoOnly + PrefServiceBridge.getInstance().setInteger( + Pref.COOKIE_CONTROLS_MODE, CookieControlsMode.INCOGNITO_ONLY); + }); + int currentCallCount = mCallbackHelper.getCallCount(); + + // Navigate to a normal page + final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + Tab tab = mActivityTestRule.loadUrlInNewTab(url, false); + + // Create cookie bridge and wait for desired callbacks. + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCookieControlsBridge = + new CookieControlsBridge(mCallbackHandler, tab.getWebContents()); + }); + + mCallbackHelper.waitForCallback(currentCallCount, 2); + Assert.assertEquals(expectedStatus, mStatus); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + + // Make new incognito page now + expectedStatus = CookieControlsControllerStatus.ENABLED; + Tab incognitoTab = mActivityTestRule.loadUrlInNewTab(url, true); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mCookieControlsBridge = + new CookieControlsBridge(mCallbackHandler, incognitoTab.getWebContents()); + }); + mCallbackHelper.waitForCallback(currentCallCount, 2); + Assert.assertEquals(expectedStatus, mStatus); + Assert.assertEquals(expectedCookiesToBlock, mBlockedCookies); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserTransitionTest.java index b9c3996..4b2f9b2 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserTransitionTest.java
@@ -394,7 +394,7 @@ VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApiWithDoff); TestThreadUtils.runOnUiThreadBlocking(() -> { - SettingsLauncher.getInstance().launchSettingsPage(context, null); + SettingsLauncher.getInstance().launchSettingsPage(context); VrShellDelegateUtils.getDelegateInstance().acceptDoffPromptForTesting(); }); CriteriaHelper.pollUiThread(() -> {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java index f38de87..d2cc41d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java
@@ -7,8 +7,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -50,6 +53,7 @@ @Mock public CloseButtonVisibilityManager mCloseButtonVisibilityManager; + @Mock TrustedWebActivityBrowserControlsVisibilityManager mController; @Before @@ -65,9 +69,8 @@ */ @Test public void testDangerousSecurityLevel() { - setTabSecurityLevel(ConnectionSecurityLevel.DANGEROUS); - mController = buildController(mock(BrowserServicesIntentDataProvider.class)); + setTabSecurityLevel(ConnectionSecurityLevel.DANGEROUS); mController.updateIsInTwaMode(true); assertEquals(BrowserControlsState.SHOWN, getLastBrowserControlsState()); assertFalse(getLastCloseButtonVisibility()); @@ -131,7 +134,7 @@ } private void setTabSecurityLevel(int securityLevel) { - when(mTab.getSecurityLevel()).thenReturn(securityLevel); + doReturn(securityLevel).when(mController).getSecurityLevel(any()); } private BrowserServicesIntentDataProvider buildWebApkIntentDataProvider( @@ -144,9 +147,9 @@ private TrustedWebActivityBrowserControlsVisibilityManager buildController( BrowserServicesIntentDataProvider intentDataProvider) { - return new TrustedWebActivityBrowserControlsVisibilityManager(mTabObserverRegistrar, + return spy(new TrustedWebActivityBrowserControlsVisibilityManager(mTabObserverRegistrar, mTabProvider, mToolbarCoordinator, mCloseButtonVisibilityManager, - intentDataProvider); + intentDataProvider)); } /**
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java index 76eb697..26a097e 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.customtabs; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -16,6 +18,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; @@ -44,12 +47,12 @@ public void setUp() { MockitoAnnotations.initMocks(this); - mColorProvider = new CustomTabStatusBarColorProvider( - mCustomTabIntentDataProvider, mStatusBarColorController); + mColorProvider = Mockito.spy(new CustomTabStatusBarColorProvider( + mCustomTabIntentDataProvider, mStatusBarColorController)); when(mCustomTabIntentDataProvider.getToolbarColor()).thenReturn(USER_PROVIDED_COLOR); when(mCustomTabIntentDataProvider.hasCustomToolbarColor()).thenReturn(true); - when(mTab.isPreview()).thenReturn(false); + doReturn(false).when(mColorProvider).isPreview(any()); } @Test @@ -77,7 +80,7 @@ @Test public void useTabThemeColor_preview() { - when(mTab.isPreview()).thenReturn(true); + doReturn(true).when(mColorProvider).isPreview(any()); mColorProvider.setUseTabThemeColor(true); Assert.assertEquals(DEFAULT_STATUS_BAR_COLOR, getStatusBarColor(mTab));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java index 5d472ca3..9b4c67f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java
@@ -18,8 +18,9 @@ import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; -import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.components.signin.AccountManagerDelegate; import org.chromium.components.signin.AccountManagerDelegateException; import org.chromium.components.signin.AccountManagerFacade; @@ -53,8 +54,8 @@ mReceiver.onReceive(RuntimeEnvironment.application, intent); Assert.assertFalse(ToSAckedReceiver.checkAnyUserHasSeenToS()); - Set<String> toSAckedAccounts = ContextUtils.getAppSharedPreferences().getStringSet( - ToSAckedReceiver.TOS_ACKED_ACCOUNTS, new HashSet<>()); + Set<String> toSAckedAccounts = SharedPreferencesManager.getInstance().readStringSet( + ChromePreferenceKeys.TOS_ACKED_ACCOUNTS, new HashSet<>()); Assert.assertThat(toSAckedAccounts, Matchers.contains(GOOGLE_ACCOUNT)); AccountManagerDelegate accountManagerDelegate = Mockito.mock(AccountManagerDelegate.class);
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java index 5ea18b17e..1da8f237 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java
@@ -4,6 +4,9 @@ package org.chromium.chrome.browser.toolbar; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import org.mockito.Mock; @@ -35,6 +38,7 @@ @Mock SecurityStateModel.Natives mSecurityStateMocks; + @Mock private LocationBarModel mLocationBarModel; @CalledByNative @@ -44,7 +48,7 @@ public void setUp() { MockitoAnnotations.initMocks(this); SecurityStateModelJni.TEST_HOOKS.setInstanceForTesting(mSecurityStateMocks); - mLocationBarModel = new LocationBarModel(ContextUtils.getApplicationContext()); + mLocationBarModel = spy(new LocationBarModel(ContextUtils.getApplicationContext())); mLocationBarModel.initializeWithNative(); } @@ -56,30 +60,34 @@ @CalledByNativeJavaTest public void testGetSecurityLevel() { assertEquals(ConnectionSecurityLevel.NONE, - LocationBarModel.getSecurityLevel(null, !IS_OFFLINE_PAGE, null)); + mLocationBarModel.getSecurityLevel(null, !IS_OFFLINE_PAGE, null)); assertEquals(ConnectionSecurityLevel.NONE, - LocationBarModel.getSecurityLevel(null, IS_OFFLINE_PAGE, null)); + mLocationBarModel.getSecurityLevel(null, IS_OFFLINE_PAGE, null)); assertEquals(ConnectionSecurityLevel.NONE, - LocationBarModel.getSecurityLevel(mTab, IS_OFFLINE_PAGE, null)); + mLocationBarModel.getSecurityLevel(mTab, IS_OFFLINE_PAGE, null)); for (int securityLevel : SECURITY_LEVELS) { - when((mTab).getSecurityLevel()).thenReturn(securityLevel); + doReturn(securityLevel).when(mLocationBarModel).getSecurityLevelFromStateModel(any()); assertEquals("Wrong security level returned for " + securityLevel, securityLevel, - LocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, null)); + mLocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, null)); } - when((mTab).getSecurityLevel()).thenReturn(ConnectionSecurityLevel.SECURE); + doReturn(ConnectionSecurityLevel.SECURE) + .when(mLocationBarModel) + .getSecurityLevelFromStateModel(any()); assertEquals("Wrong security level returned for HTTPS publisher URL", ConnectionSecurityLevel.SECURE, - LocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, "https://example.com")); + mLocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, "https://example.com")); assertEquals("Wrong security level returned for HTTP publisher URL", ConnectionSecurityLevel.WARNING, - LocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, "http://example.com")); + mLocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, "http://example.com")); - when((mTab).getSecurityLevel()).thenReturn(ConnectionSecurityLevel.DANGEROUS); + doReturn(ConnectionSecurityLevel.DANGEROUS) + .when(mLocationBarModel) + .getSecurityLevelFromStateModel(any()); assertEquals("Wrong security level returned for publisher URL on insecure page", ConnectionSecurityLevel.DANGEROUS, - LocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, null)); + mLocationBarModel.getSecurityLevel(mTab, !IS_OFFLINE_PAGE, null)); } @CalledByNativeJavaTest
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index f2670c8..01a2246 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -395,6 +395,12 @@ #define IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS 52411 #define IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE_ONCE 52412 +#if defined(OS_CHROMEOS) +// Quick Answers context menu items. +#define IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER 52413 +#define IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY 52414 +#endif + // NOTE: The last valid command value is 57343 (0xDFFF) // See http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index dcd06a6..e7025a79 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10510,10 +10510,10 @@ Timed out </message> <message name="IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_MESSAGE" desc="Message shown in tab modal dialog when the deep scanning times out."> - Something went wrong. The scanned file has timed out. + Something went wrong. Scanning could not be completed. Please try again. </message> <message name="IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_ACCEPT_BUTTON" desc="The text on the accept button in tab modal dialog when deep scanning times out."> - Scan + Scan again </message> <message name="IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_CANCEL_BUTTON" desc="The text on the cancel button in tab modal dialog when deep scanning times out."> Cancel
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 4935e7a1..4918da1c 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -224,6 +224,10 @@ "google_chrome/google_pay_logo.icon", ] } + + if (is_chrome_branded && is_chromeos) { + icons += [ "google_chrome/assistant.icon" ] + } } source_set("vector_icons") {
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index e58c6b5..134f644 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2592,6 +2592,8 @@ "android/preferences/browser_prefs_android.h", "android/preferences/clipboard_android.cc", "android/preferences/clipboard_android.h", + "android/preferences/cookie_controls_bridge.cc", + "android/preferences/cookie_controls_bridge.h", "android/preferences/pref_change_registrar_android.cc", "android/preferences/pref_change_registrar_android.h", "android/preferences/pref_service_bridge.cc", @@ -3817,6 +3819,8 @@ "notifications/web_page_notifier_controller.h", "policy/default_geolocation_policy_handler.cc", "policy/default_geolocation_policy_handler.h", + "renderer_context_menu/quick_answers_menu_observer.cc", + "renderer_context_menu/quick_answers_menu_observer.h", "signin/signin_error_notifier_ash.cc", "signin/signin_error_notifier_ash.h", "signin/signin_error_notifier_factory_ash.cc", @@ -3851,6 +3855,7 @@ "//chrome/browser/chromeos", "//chrome/services/app_service/public/cpp:instance_update", "//chromeos/components/account_manager", + "//chromeos/components/quick_answers", "//chromeos/components/sync_wifi", "//chromeos/services/assistant/public:feature_flags", "//chromeos/services/assistant/public/cpp:prefs", @@ -4724,6 +4729,7 @@ "//chrome/browser/web_applications", # TODO(loyso): Erase these. crbug.com/877898. + "//chrome/browser/web_applications:common", "//chrome/browser/web_applications:web_applications_on_extensions", "//chrome/browser/web_applications/components", "//chrome/browser/web_applications/extensions", @@ -4732,6 +4738,7 @@ "//apps", "//chrome/browser/sync_file_system/drive_backend:sync_file_system_drive_proto", "//chrome/browser/web_applications", + "//chrome/browser/web_applications:common", "//chrome/browser/web_applications:web_applications_on_extensions", "//chrome/browser/web_applications/components", "//chrome/browser/web_applications/extensions",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index f6fbd20..a84f8e94 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2577,6 +2577,13 @@ kOsCrOS, SINGLE_VALUE_TYPE( ::switches::kEnableExperimentalAccessibilitySwitchAccessText)}, + {"enable-experimental-accessibility-chromevox-annotations", + flag_descriptions::kExperimentalAccessibilityChromeVoxAnnotationsName, + flag_descriptions:: + kExperimentalAccessibilityChromeVoxAnnotationsDescription, + kOsCrOS, + SINGLE_VALUE_TYPE( + ::switches::kEnableExperimentalAccessibilityChromeVoxAnnotations)}, {"enable-experimental-accessibility-chromevox-language-switching", flag_descriptions:: kExperimentalAccessibilityChromeVoxLanguageSwitchingName,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index a8d3e01..fbb9c9d9 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -183,7 +183,6 @@ &kSearchEnginePromoNewDevice, &kServiceManagerForBackgroundPrefetch, &kServiceManagerForDownload, - &kSettingsModernStatusBar, &kSharedClipboardUI, &kSharingQrCodeAndroid, &kShoppingAssist, @@ -545,9 +544,6 @@ const base::Feature kServiceManagerForDownload{ "ServiceManagerForDownload", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kSettingsModernStatusBar{"SettingsModernStatusBar", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kShoppingAssist{"ShoppingAssist", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index a31e391..057545a 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -106,7 +106,6 @@ extern const base::Feature kSearchEnginePromoNewDevice; extern const base::Feature kServiceManagerForBackgroundPrefetch; extern const base::Feature kServiceManagerForDownload; -extern const base::Feature kSettingsModernStatusBar; extern const base::Feature kShoppingAssist; extern const base::Feature kSpannableInlineAutocomplete; extern const base::Feature kSpecialLocaleWrapper;
diff --git a/chrome/browser/android/preferences/cookie_controls_bridge.cc b/chrome/browser/android/preferences/cookie_controls_bridge.cc new file mode 100644 index 0000000..8cbd7823 --- /dev/null +++ b/chrome/browser/android/preferences/cookie_controls_bridge.cc
@@ -0,0 +1,63 @@ +// Copyright 2019 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/android/preferences/cookie_controls_bridge.h" + +#include <memory> +#include "chrome/android/chrome_jni_headers/CookieControlsBridge_jni.h" + +using base::android::JavaParamRef; + +CookieControlsBridge::CookieControlsBridge( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& jweb_contents_android) + : jobject_(obj) { + content::WebContents* web_contents = + content::WebContents::FromJavaWebContents(jweb_contents_android); + controller_ = std::make_unique<CookieControlsController>(web_contents); + observer_.Add(controller_.get()); + controller_->Update(web_contents); +} + +void CookieControlsBridge::OnStatusChanged( + CookieControlsController::Status new_status, + int blocked_cookies) { + if (status_ != new_status) { + status_ = new_status; + JNIEnv* env = base::android::AttachCurrentThread(); + // Only call status callback if status has changed + Java_CookieControlsBridge_onCookieBlockingStatusChanged( + env, jobject_, static_cast<int>(status_)); + } + + OnBlockedCookiesCountChanged(blocked_cookies); +} + +void CookieControlsBridge::OnBlockedCookiesCountChanged(int blocked_cookies) { + // The blocked cookie count changes quite frequently, so avoid unnecessary + // UI updates if possible. + if (blocked_cookies_ == blocked_cookies) + return; + + blocked_cookies_ = blocked_cookies; + JNIEnv* env = base::android::AttachCurrentThread(); + Java_CookieControlsBridge_onBlockedCookiesCountChanged( + env, jobject_, blocked_cookies_.value_or(0)); +} + +CookieControlsBridge::~CookieControlsBridge() = default; + +void CookieControlsBridge::Destroy(JNIEnv* env, + const JavaParamRef<jobject>& obj) { + delete this; +} + +static jlong JNI_CookieControlsBridge_Init( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& jweb_contents_android) { + return reinterpret_cast<intptr_t>( + new CookieControlsBridge(env, obj, jweb_contents_android)); +}
diff --git a/chrome/browser/android/preferences/cookie_controls_bridge.h b/chrome/browser/android/preferences/cookie_controls_bridge.h new file mode 100644 index 0000000..0c4fa16 --- /dev/null +++ b/chrome/browser/android/preferences/cookie_controls_bridge.h
@@ -0,0 +1,45 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_PREFERENCES_COOKIE_CONTROLS_BRIDGE_H_ +#define CHROME_BROWSER_ANDROID_PREFERENCES_COOKIE_CONTROLS_BRIDGE_H_ + +#include "base/android/jni_weak_ref.h" +#include "base/optional.h" +#include "chrome/browser/ui/cookie_controls/cookie_controls_controller.h" +#include "chrome/browser/ui/cookie_controls/cookie_controls_view.h" + +// Communicates between CookieControlsController (C++ backend) and PageInfoView +// (Java UI). +class CookieControlsBridge : public CookieControlsView { + public: + // Creates a CookeControlsBridge for interaction with a + // CookieControlsController. + CookieControlsBridge( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& jweb_contents_android); + + ~CookieControlsBridge() override; + + // Called by the Java counterpart when it is getting garbage collected. + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + + // CookieControlsView: + void OnStatusChanged(CookieControlsController::Status status, + int blocked_cookies) override; + void OnBlockedCookiesCountChanged(int blocked_cookies) override; + + private: + base::android::ScopedJavaGlobalRef<jobject> jobject_; + CookieControlsController::Status status_ = + CookieControlsController::Status::kUninitialized; + base::Optional<int> blocked_cookies_; + std::unique_ptr<CookieControlsController> controller_; + ScopedObserver<CookieControlsController, CookieControlsView> observer_{this}; + + DISALLOW_COPY_AND_ASSIGN(CookieControlsBridge); +}; + +#endif // CHROME_BROWSER_ANDROID_PREFERENCES_COOKIE_CONTROLS_BRIDGE_H_
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.cc b/chrome/browser/apps/platform_apps/shortcut_manager.cc index 00966cd2..93ce9f91 100644 --- a/chrome/browser/apps/platform_apps/shortcut_manager.cc +++ b/chrome/browser/apps/platform_apps/shortcut_manager.cc
@@ -162,6 +162,7 @@ const Extension* extension, extensions::UninstallReason reason) { #if defined(OS_MACOSX) + // TODO(crbug.com/860581): Move this code to BookmarkAppShortcutManager. if (UseAppShimRegistry(browser_context, extension)) { bool delete_multi_profile_shortcuts = AppShimRegistry::Get()->OnAppUninstalledForProfile(extension->id(), @@ -175,7 +176,10 @@ } #endif - web_app::DeleteAllShortcuts(profile_, extension); + // Bookmark apps are handled in + // web_app::AppShortcutManager::OnWebAppWillBeUninstalled() + if (!extension->from_bookmark()) + web_app::DeleteAllShortcuts(profile_, extension); } void AppShortcutManager::OnProfileWillBeRemoved(
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.h b/chrome/browser/apps/platform_apps/shortcut_manager.h index a45d483..1f4aa1a 100644 --- a/chrome/browser/apps/platform_apps/shortcut_manager.h +++ b/chrome/browser/apps/platform_apps/shortcut_manager.h
@@ -20,7 +20,11 @@ class PrefRegistrySyncable; } -// This class manages the installation of shortcuts for platform apps. +// This class manages the installation of shortcuts for any extension-based apps +// (Chrome Apps). Bookmark apps OS shortcut management is handled in +// web_app::AppShortcutManager and its subclasses. +// +// Long term, this class must be deleted together with all extension-based apps. class AppShortcutManager : public KeyedService, public extensions::ExtensionRegistryObserver, public ProfileAttributesStorage::Observer {
diff --git a/chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_navigation_throttle.cc b/chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_navigation_throttle.cc index 1ecd9fe..729d529 100644 --- a/chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_navigation_throttle.cc +++ b/chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_navigation_throttle.cc
@@ -18,7 +18,7 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" @@ -129,15 +129,13 @@ const std::string& app_locale = g_browser_process->GetApplicationLocale(); Browser::Type type = browser->type(); - web_app::WebAppTabHelper* web_app_helper = - web_app::WebAppTabHelper::FromWebContents(web_contents); + web_app::WebAppTabHelperBase* web_app_helper = + web_app::WebAppTabHelperBase::FromWebContents(web_contents); bool is_windowed = (type == Browser::Type::TYPE_APP_POPUP) || (type == Browser::Type::TYPE_APP) || (type == Browser::Type::TYPE_POPUP); - bool is_app = false; - if (web_app_helper && !web_app_helper->app_id().empty()) - is_app = true; + bool is_app = web_app_helper && !web_app_helper->GetAppId().empty(); // Don't throttle windowed applications. We show a notification and close // them. @@ -152,7 +150,7 @@ web_app::WebAppProvider::Get(profile); const web_app::AppRegistrar& registrar = web_app_provider->registrar(); const std::string& app_name = - registrar.GetAppShortName(web_app_helper->app_id()); + registrar.GetAppShortName(web_app_helper->GetAppId()); interstitial_html = GetWebTimeLimitAppErrorPage(time_limit, app_locale, app_name); } else {
diff --git a/chrome/browser/chromeos/first_run/first_run.cc b/chrome/browser/chromeos/first_run/first_run.cc index f69dedc..4d39b1e 100644 --- a/chrome/browser/chromeos/first_run/first_run.cc +++ b/chrome/browser/chromeos/first_run/first_run.cc
@@ -8,8 +8,8 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" -#include "chrome/browser/apps/app_service/app_launch_params.h" -#include "chrome/browser/apps/launch_service/launch_service.h" +#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/first_run/first_run_controller.h" @@ -38,6 +38,8 @@ #include "content/public/common/content_switches.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/constants.h" +#include "ui/display/types/display_constants.h" +#include "ui/events/event_constants.h" #include "ui/gfx/geometry/rect.h" namespace chromeos { @@ -45,33 +47,34 @@ namespace { -void LaunchDialogForProfile(Profile* profile) { +void LaunchHelpForProfile(Profile* profile) { extensions::ExtensionRegistry* registry = extensions::ExtensionRegistry::Get(profile); if (!registry) return; - const extensions::Extension* extension = - registry->GetExtensionById(extension_misc::kFirstRunDialogId, - extensions::ExtensionRegistry::ENABLED); + const extensions::Extension* extension = registry->GetExtensionById( + extension_misc::kGeniusAppId, extensions::ExtensionRegistry::ENABLED); if (!extension) return; - apps::LaunchService::Get(profile)->OpenApplication(apps::AppLaunchParams( - extension->id(), apps::mojom::LaunchContainer::kLaunchContainerWindow, - WindowOpenDisposition::NEW_WINDOW, - apps::mojom::AppLaunchSource::kSourceChromeInternal)); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); + DCHECK(proxy); + proxy->Launch(extension->id(), ui::EventFlags::EF_NONE, + apps::mojom::LaunchSource::kFromChromeInternal, + display::kInvalidDisplayId); profile->GetPrefs()->SetBoolean(prefs::kFirstRunTutorialShown, true); } -void TryLaunchFirstRunDialog(Profile* profile) { +void TryLaunchHelpApp(Profile* profile) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (chromeos::switches::ShouldSkipOobePostLogin()) return; if (command_line->HasSwitch(switches::kForceFirstRunUI)) { - LaunchDialogForProfile(profile); + LaunchHelpForProfile(profile); return; } @@ -98,19 +101,16 @@ if (!is_pref_synced && is_user_ephemeral) return; - LaunchDialogForProfile(profile); + LaunchHelpForProfile(profile); } -// Object of this class waits for session start. Then it launches or not -// launches first-run dialog depending on user prefs and flags. Than object -// deletes itself. -class DialogLauncher : public session_manager::SessionManagerObserver { +// Object of this class waits for session start. Then it maybe launches the help +// app depending on user prefs and flags. The object then deletes itself. +class AppLauncher : public session_manager::SessionManagerObserver { public: - DialogLauncher() { - session_manager::SessionManager::Get()->AddObserver(this); - } + AppLauncher() { session_manager::SessionManager::Get()->AddObserver(this); } - ~DialogLauncher() override { + ~AppLauncher() override { session_manager::SessionManager::Get()->RemoveObserver(this); } @@ -118,12 +118,12 @@ void OnUserSessionStarted(bool is_primary_user) override { auto* profile = ProfileHelper::Get()->GetProfileByUser( user_manager::UserManager::Get()->GetActiveUser()); - TryLaunchFirstRunDialog(profile); + TryLaunchHelpApp(profile); delete this; } private: - DISALLOW_COPY_AND_ASSIGN(DialogLauncher); + DISALLOW_COPY_AND_ASSIGN(AppLauncher); }; } // namespace @@ -135,8 +135,8 @@ registry->RegisterBooleanPref(prefs::kFirstRunTutorialShown, false); } -void MaybeLaunchDialogAfterSessionStart() { - new DialogLauncher(); +void MaybeLaunchHelpAppAfterSessionStart() { + new AppLauncher(); } void LaunchTutorial() {
diff --git a/chrome/browser/chromeos/first_run/first_run.h b/chrome/browser/chromeos/first_run/first_run.h index 45b984d..91cb317 100644 --- a/chrome/browser/chromeos/first_run/first_run.h +++ b/chrome/browser/chromeos/first_run/first_run.h
@@ -15,10 +15,10 @@ // Registers preferences related to ChromeOS first-run tutorial. void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); -// Probably launches first-run dialog after session start depending on synced -// user prefs. This method should be called after user already logged in but -// session didn't started yet. -void MaybeLaunchDialogAfterSessionStart(); +// Maybe launches the help app after session start (depending on synced user +// prefs and flags). This method should be called after the user has already +// logged in and before the session starts. +void MaybeLaunchHelpAppAfterSessionStart(); // Launches overlay tutorial for current user. void LaunchTutorial();
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 645e4ce..25325f6a 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1821,7 +1821,7 @@ // background. base::CommandLine::ForCurrentProcess()->AppendSwitch( ::switches::kSilentLaunch); - first_run::MaybeLaunchDialogAfterSessionStart(); + first_run::MaybeLaunchHelpAppAfterSessionStart(); } else { for (size_t i = 0; i < start_urls.size(); ++i) { base::CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 94a21e7..dcf1ef9 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -1108,6 +1108,10 @@ DVLOG(2) << __func__ << "() download = " << item->DebugString(false) << " verdict = " << static_cast<int>(result); + + // Indicates whether we expect future verdicts on this download. For example, + // if Safe Browsing is performing deep scanning, we will receive a more + // specific verdict later. bool is_pending_scanning = false; // We only mark the content as being dangerous if the download's safety state @@ -1171,6 +1175,10 @@ case safe_browsing::DownloadCheckResult::DEEP_SCANNED_SAFE: danger_type = download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE; break; + case safe_browsing::DownloadCheckResult::PROMPT_FOR_SCANNING: + danger_type = download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING; + is_pending_scanning = true; + break; } DCHECK_NE(danger_type, download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);
diff --git a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index fe189fd..c8359a9 100644 --- a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
@@ -275,7 +275,7 @@ } // Tests that -// Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2 +// Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3 // is only emitted when there are active rulesets. TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { WebRequestInfo example_com_request( @@ -284,7 +284,7 @@ GetRequestParamsForURL("http://google.com")); bool is_incognito_context = false; const char* kHistogramName = - "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"; + "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3"; { base::HistogramTester tester;
diff --git a/chrome/browser/extensions/browsertest_util.cc b/chrome/browser/extensions/browsertest_util.cc index 4f82758..cbc28e49 100644 --- a/chrome/browser/extensions/browsertest_util.cc +++ b/chrome/browser/extensions/browsertest_util.cc
@@ -24,7 +24,7 @@ #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_install_utils.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/common/chrome_features.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/extensions/chrome_app_icon_loader.cc b/chrome/browser/extensions/chrome_app_icon_loader.cc index 5476dba2..e7459fb 100644 --- a/chrome/browser/extensions/chrome_app_icon_loader.cc +++ b/chrome/browser/extensions/chrome_app_icon_loader.cc
@@ -44,7 +44,12 @@ bool ChromeAppIconLoader::CanLoadImageForApp(const std::string& id) { if (map_.find(id) != map_.end()) return true; - return GetExtensionByID(profile(), id) != nullptr; + + const Extension* extension = GetExtensionByID(profile(), id); + if (!extension || (extensions_only_ && !extension->is_extension())) + return false; + + return true; } void ChromeAppIconLoader::FetchImage(const std::string& id) { @@ -77,6 +82,10 @@ it->second->UpdateIcon(); } +void ChromeAppIconLoader::SetExtensionsOnly() { + extensions_only_ = true; +} + void ChromeAppIconLoader::OnIconUpdated(ChromeAppIcon* icon) { delegate()->OnAppImageUpdated(icon->app_id(), icon->image_skia()); }
diff --git a/chrome/browser/extensions/chrome_app_icon_loader.h b/chrome/browser/extensions/chrome_app_icon_loader.h index f35ca2d..a5f64aa 100644 --- a/chrome/browser/extensions/chrome_app_icon_loader.h +++ b/chrome/browser/extensions/chrome_app_icon_loader.h
@@ -48,6 +48,9 @@ void ClearImage(const std::string& id) override; void UpdateImage(const std::string& id) override; + // Sets |extensions_only_| as true to load icons for extensions only. + void SetExtensionsOnly(); + private: using ExtensionIDToChromeAppIconMap = std::map<std::string, std::unique_ptr<ChromeAppIcon>>; @@ -62,6 +65,10 @@ // resize will be performed by ImageLoader. const ResizeFunction resize_function_; + // Loads icons for extensions only if true, otherwise loads icon for both + // Chrome apps and extensions. + bool extensions_only_ = false; + DISALLOW_COPY_AND_ASSIGN(ChromeAppIconLoader); };
diff --git a/chrome/browser/extensions/chrome_app_icon_service.cc b/chrome/browser/extensions/chrome_app_icon_service.cc index e5a184e..a718a39 100644 --- a/chrome/browser/extensions/chrome_app_icon_service.cc +++ b/chrome/browser/extensions/chrome_app_icon_service.cc
@@ -21,7 +21,8 @@ ChromeAppIconService::ChromeAppIconService(content::BrowserContext* context) : context_(context) { #if defined(OS_CHROMEOS) - app_updater_ = std::make_unique<LauncherExtensionAppUpdater>(this, context); + app_updater_ = std::make_unique<LauncherExtensionAppUpdater>( + this, context, false /* extensions_only */); #endif observer_.Add(ExtensionRegistry::Get(context_));
diff --git a/chrome/browser/extensions/cross_origin_read_blocking_browsertest.cc b/chrome/browser/extensions/cross_origin_read_blocking_browsertest.cc index a8aef05f..e1c00c4 100644 --- a/chrome/browser/extensions/cross_origin_read_blocking_browsertest.cc +++ b/chrome/browser/extensions/cross_origin_read_blocking_browsertest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/extensions/extension_action_runner.h" +#include <vector> #include "base/bind.h" #include "base/files/file_path.h" @@ -32,6 +32,7 @@ #include "content/public/test/test_navigation_observer.h" #include "extensions/browser/browsertest_util.h" #include "extensions/browser/url_loader_factory_manager.h" +#include "extensions/common/extension_features.h" #include "extensions/test/test_extension_dir.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -51,8 +52,11 @@ enum TestParam { kAllowlisted = 1 << 0, kOutOfBlinkCors = 1 << 1, + kAllowlistForCors = 1 << 2, }; +const char kCorsErrorWhenFetching[] = "error: TypeError: Failed to fetch"; + } // namespace using CORBAction = network::CrossOriginReadBlocking::Action; @@ -359,13 +363,23 @@ using Base = CrossOriginReadBlockingExtensionTest; CrossOriginReadBlockingExtensionAllowlistingTest() { - if (IsOutOfBlinkCorsEnabled()) { - scoped_feature_list_.InitAndEnableFeature( - network::features::kOutOfBlinkCors); + std::vector<base::Feature> disabled_features; + std::vector<base::Feature> enabled_features; + + if (IsOutOfBlinkCorsEnabled()) + enabled_features.push_back(network::features::kOutOfBlinkCors); + else + disabled_features.push_back(network::features::kOutOfBlinkCors); + + if (ShouldAllowlistAlsoApplyToOorCors()) { + enabled_features.push_back( + extensions_features::kCorbAllowlistAlsoAppliesToOorCors); } else { - scoped_feature_list_.InitAndDisableFeature( - network::features::kOutOfBlinkCors); + disabled_features.push_back( + extensions_features::kCorbAllowlistAlsoAppliesToOorCors); } + + scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); } bool IsExtensionAllowlisted() { @@ -376,6 +390,10 @@ return (GetParam() & TestParam::kOutOfBlinkCors) != 0; } + bool ShouldAllowlistAlsoApplyToOorCors() { + return (GetParam() & TestParam::kAllowlistForCors) != 0; + } + const Extension* InstallExtension( GURL resource_to_fetch_from_declarative_content_script = GURL()) { const Extension* extension = Base::InstallExtension( @@ -436,18 +454,31 @@ // Verifies results of fetching a CORB-eligible resource from a content // script. Expectations differ depending on the following: - // 1. Non-NetworkService: Fetches from content scripts should never be blocked - // 2. NetworkService + allowlisted extension: Fetches from content scripts - // should not be blocked - // 3. NetworkService + other extension: Fetches from content scripts should - // be blocked + // 1. Allowlisted extension: Fetches from content scripts + // should not be blocked + // 2. Other extension: Fetches from content scripts should be blocked by + // either: only CORB or CORS+CORB. void VerifyFetchFromContentScript(const base::HistogramTester& histograms, const std::string& actual_fetch_result, const std::string& expected_fetch_result) { if (AreContentScriptFetchesExpectedToBeBlocked()) { - // Verify the fetch was blocked. - EXPECT_EQ(std::string(), actual_fetch_result); - VerifyFetchFromContentScriptWasBlocked(histograms); + if (ShouldAllowlistAlsoApplyToOorCors()) { + // Verify the fetch was blocked by CORS. + EXPECT_EQ(kCorsErrorWhenFetching, actual_fetch_result); + + // No verification if the request was blocked by CORB, because + // 1) once request_initiator is trustworthy, CORB should only + // apply to no-cors requests + // 2) some CORS-blocked requests may not reach CORB/response-started + // stage at all (e.g. if CORS blocks a redirect). + + // TODO(lukasza): Verify that the request was made in CORS mode (e.g. + // included an Origin header). + } else { + // Verify the fetch was blocked by CORB, but not blocked by CORS. + EXPECT_EQ(std::string(), actual_fetch_result); + VerifyFetchFromContentScriptWasBlocked(histograms); + } } else { // Verify the fetch was allowed. EXPECT_EQ(expected_fetch_result, actual_fetch_result); @@ -667,13 +698,29 @@ embedded_test_server()->GetURL("cross-site.com", "/save_page/text.txt")); std::string fetch_result = FetchViaContentScript(cross_site_resource, active_web_contents()); + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // Verify that no blocking occurred. - EXPECT_THAT(fetch_result, - ::testing::StartsWith( - "text-object.txt: ae52dd09-9746-4b7e-86a6-6ada5e2680c2")); - VerifyFetchFromContentScriptWasAllowed(histograms, - true /* expecting_sniffing */); + if (IsCorbExpectedToBeTurnedOffAltogether()) { + // Verify that CORB didn't run. + EXPECT_EQ( + 0u, + histograms.GetTotalCountsForPrefix("SiteIsolation.XSD.Browser").size()); + } else { + // Verify that CORB sniffing allowed the response. + VerifyFetchFromContentScriptWasAllowed(histograms, + true /* expecting_sniffing */); + } + + if (ShouldAllowlistAlsoApplyToOorCors() && + AreContentScriptFetchesExpectedToBeBlocked()) { + // Verify that the response body was blocked by CORS. + EXPECT_EQ(kCorsErrorWhenFetching, fetch_result); + } else { + // Verify that the response body was not blocked by either CORB nor CORS. + EXPECT_THAT(fetch_result, + ::testing::StartsWith( + "text-object.txt: ae52dd09-9746-4b7e-86a6-6ada5e2680c2")); + } } // Test that responses are blocked by CORB, but have empty response body are not @@ -696,14 +743,13 @@ base::HistogramTester histograms; GURL cross_site_resource( embedded_test_server()->GetURL("cross-site.com", "/nosniff.empty")); - EXPECT_EQ(std::string(), - FetchViaContentScript(cross_site_resource, active_web_contents())); + std::string fetch_result = + FetchViaContentScript(cross_site_resource, active_web_contents()); - // Verify whether blocking occurred or not. - if (AreContentScriptFetchesExpectedToBeBlocked()) - VerifyFetchFromContentScriptWasBlocked(histograms); - else - VerifyFetchFromContentScriptWasAllowed(histograms); + // Verify whether the fetch worked or not (expectations differ depending on + // various factors - see the body of VerifyFetchFromContentScript). + VerifyFetchFromContentScript(histograms, fetch_result, + "" /* expected_response_body */); } // Test that LogInitiatorSchemeBypassingDocumentBlocking exits early for @@ -1130,6 +1176,9 @@ IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest, OriginHeaderInCrossOriginGetRequest) { + const char kResourcePath[] = "/simulated-resource"; + net::test_server::ControllableHttpResponse http_request( + embedded_test_server(), kResourcePath); ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(InstallExtension()); @@ -1144,45 +1193,45 @@ // Inject a content script that performs a cross-origin GET fetch to // cross-site.com. GURL cross_site_resource( - embedded_test_server()->GetURL("cross-site.com", "/echoall")); + embedded_test_server()->GetURL("cross-site.com", kResourcePath)); const char* kScriptTemplate = R"( fetch($1, {method: 'GET', mode:'cors'}) .then(response => response.text()) .then(text => domAutomationController.send(text)) .catch(err => domAutomationController.send('ERROR: ' + err)); )"; - content::DOMMessageQueue message_queue; ExecuteContentScript( active_web_contents(), content::JsReplace(kScriptTemplate, cross_site_resource)); - std::string fetch_result = PopString(&message_queue); - // Verify if the fetch was blocked + what the Origin header was. - if (AreContentScriptFetchesExpectedToBeBlocked()) { - // TODO(lukasza): https://crbug.com/953315: No CORB blocking should occur - // for the CORS-mode request - the test expectations should be the same, - // regardless of AreContentScriptFetchesExpectedToBeBlocked. - EXPECT_EQ("", fetch_result); - } else if (IsExtensionAllowlisted()) { - // Legacy behavior - no Origin: header is present in GET CORS requests from - // content scripts based on the extension permissions. - EXPECT_THAT(fetch_result, ::testing::Not(::testing::HasSubstr("Origin:"))); + // Extract the Origin header. + http_request.WaitForRequest(); + std::string actual_origin_header = "<none>"; + const auto& headers_map = http_request.http_request()->headers; + auto it = headers_map.find("Origin"); + if (it != headers_map.end()) + actual_origin_header = it->second; + + if (AreContentScriptFetchesExpectedToBeBlocked() && + ShouldAllowlistAlsoApplyToOorCors()) { + // Verify the Origin header uses the page's origin (not the extension + // origin). + EXPECT_EQ(url::Origin::Create(page_url).Serialize(), actual_origin_header); } else { - // TODO(lukasza): https://crbug.com/920638: Non-allowlisted extension - // should use the website's origin in the CORS request. - // TODO: EXPECT_THAT(fetch_result, - // ::testing::HasSubstr("Origin: - // http://fetch-initiator.com")); - EXPECT_THAT(fetch_result, ::testing::Not(::testing::HasSubstr("Origin:"))); + // Verify the Origin header is missing. + EXPECT_EQ("<none>", actual_origin_header); } // Regression test against https://crbug.com/944704. - EXPECT_THAT(fetch_result, - ::testing::Not(::testing::HasSubstr("Origin: chrome-extension"))); + EXPECT_THAT(actual_origin_header, + ::testing::Not(::testing::HasSubstr("chrome-extension"))); } IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest, OriginHeaderInCrossOriginPostRequest) { + const char kResourcePath[] = "/simulated-resource"; + net::test_server::ControllableHttpResponse http_request( + embedded_test_server(), kResourcePath); ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(InstallExtension()); @@ -1197,33 +1246,32 @@ // Inject a content script that performs a cross-origin POST fetch to // cross-site.com. GURL cross_site_resource( - embedded_test_server()->GetURL("cross-site.com", "/echoall")); + embedded_test_server()->GetURL("cross-site.com", kResourcePath)); const char* kScriptTemplate = R"( fetch($1, {method: 'POST', mode:'cors'}) .then(response => response.text()) .then(text => domAutomationController.send(text)) .catch(err => domAutomationController.send('ERROR: ' + err)); )"; - content::DOMMessageQueue message_queue; ExecuteContentScript( active_web_contents(), content::JsReplace(kScriptTemplate, cross_site_resource)); - std::string fetch_result = PopString(&message_queue); - // Verify if the fetch was blocked + what the Origin header was. - if (AreContentScriptFetchesExpectedToBeBlocked()) { - // TODO(lukasza): https://crbug.com/953315: No CORB blocking should occur - // for the CORS-mode request - the test expectations should be the same, - // regardless of AreContentScriptFetchesExpectedToBeBlocked. - EXPECT_EQ("", fetch_result); - } else { - EXPECT_THAT(fetch_result, - ::testing::HasSubstr("Origin: http://fetch-initiator.com")); - } + // Extract the Origin header. + http_request.WaitForRequest(); + std::string actual_origin_header = "<none>"; + const auto& headers_map = http_request.http_request()->headers; + auto it = headers_map.find("Origin"); + if (it != headers_map.end()) + actual_origin_header = it->second; + + // Verify the Origin header uses the page's origin (not the extension + // origin). + EXPECT_EQ(url::Origin::Create(page_url).Serialize(), actual_origin_header); // Regression test against https://crbug.com/944704. - EXPECT_THAT(fetch_result, - ::testing::Not(::testing::HasSubstr("Origin: chrome-extension"))); + EXPECT_THAT(actual_origin_header, + ::testing::Not(::testing::HasSubstr("chrome-extension"))); } IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest, @@ -1421,6 +1469,15 @@ EXPECT_EQ("cors-allowed-body", fetch_result); } +INSTANTIATE_TEST_SUITE_P(Allowlisted_AllowlistForCors, + CrossOriginReadBlockingExtensionAllowlistingTest, + ::testing::Values(TestParam::kAllowlisted | + TestParam::kOutOfBlinkCors | + TestParam::kAllowlistForCors)); +INSTANTIATE_TEST_SUITE_P(NotAllowlisted_AllowlistForCors, + CrossOriginReadBlockingExtensionAllowlistingTest, + ::testing::Values(TestParam::kOutOfBlinkCors | + TestParam::kAllowlistForCors)); INSTANTIATE_TEST_SUITE_P(Allowlisted_OorCors, CrossOriginReadBlockingExtensionAllowlistingTest, ::testing::Values(TestParam::kAllowlisted |
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc index 2776f63..bb9a64c 100644 --- a/chrome/browser/file_select_helper.cc +++ b/chrome/browser/file_select_helper.cc
@@ -110,6 +110,7 @@ case Result::SENSITIVE_CONTENT_BLOCK: case Result::SENSITIVE_CONTENT_WARNING: case Result::DEEP_SCANNED_SAFE: + case Result::PROMPT_FOR_SCANNING: NOTREACHED(); return true; }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 335d74d4..e19e2dd 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1305,6 +1305,11 @@ "expiry_milestone": 78 }, { + "name": "enable-experimental-accessibility-chromevox-annotations", + "owners": ["akihiroota"], + "expiry_milestone": 86 + }, + { "name": "enable-experimental-accessibility-chromevox-language-switching", "owners": [ "akihiroota", "dmazzoni", "dtseng" ], "expiry_milestone": 82 @@ -3466,8 +3471,12 @@ }, { "name": "top-chrome-touch-ui", - "owners": [ "chrome-desktop-ui-sea@google.com" ], - "expiry_milestone": 81 + "owners": [ "pbos", "chrome-desktop-ui-sea@google.com" ], + // This flag is used to easily swap into touch-mode for UI development where + // the UI differs significantly between touch/non-touch modes. This is + // exposed in chrome://flags to allow QA and UXers to verify touch-related + // behavior without access to touch devices. + "expiry_milestone": -1 }, { "name": "touch-events",
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 2a02a54..bb5c231 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -81,6 +81,7 @@ "show-taps", "show-touch-hud", "tint-gl-composited-content", + "top-chrome-touch-ui", "translate-android-manual-trigger", "ui-disable-partial-swap", "ui-slow-animations",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 2791f91e..176d948 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3604,6 +3604,11 @@ "Allow Linux applications to request a pointer lock, i.e. exclusive use of " "the mouse pointer."; +const char kExperimentalAccessibilityChromeVoxAnnotationsName[] = + "Enable experimental ChromeVox annotations feature."; +const char kExperimentalAccessibilityChromeVoxAnnotationsDescription[] = + "Allows users to create custom annotations for elements using ChromeVox."; + const char kExperimentalAccessibilityChromeVoxLanguageSwitchingName[] = "Enable experimental ChromeVox language switching."; const char kExperimentalAccessibilityChromeVoxLanguageSwitchingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 2ef68bf3..5f3ef37 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2151,6 +2151,9 @@ extern const char kExoPointerLockName[]; extern const char kExoPointerLockDescription[]; +extern const char kExperimentalAccessibilityChromeVoxAnnotationsName[]; +extern const char kExperimentalAccessibilityChromeVoxAnnotationsDescription[]; + extern const char kExperimentalAccessibilityChromeVoxLanguageSwitchingName[]; extern const char kExperimentalAccessibilityChromeVoxLanguageSwitchingDescription[];
diff --git a/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc b/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc index a124624..1bb70f7 100644 --- a/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc +++ b/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc
@@ -391,6 +391,7 @@ case Result::SENSITIVE_CONTENT_WARNING: case Result::SENSITIVE_CONTENT_BLOCK: case Result::DEEP_SCANNED_SAFE: + case Result::PROMPT_FOR_SCANNING: NOTREACHED(); return ChromeNativeFileSystemPermissionContext::AfterWriteCheckResult:: kAllow;
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 256f03fd..663b997 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -349,9 +349,9 @@ prefs::kAmbientAuthenticationInPrivateModesEnabled, static_cast<int>(net::AmbientAuthAllowedProfileTypes::REGULAR_ONLY)); - // For information about whether to reset the HTTP Cache or not, store the - // groups for all the relevant experiments. Initially unknown status for all. - registry->RegisterStringPref(kHttpCacheFinchExperimentGroups, "NoneNoneNone"); + // For information about whether to reset the HTTP Cache or not, defaults + // to the empty string, which does not prompt a reset. + registry->RegisterStringPref(kHttpCacheFinchExperimentGroups, ""); } void ProfileNetworkContextService::DisableQuicIfNotAllowed() { @@ -606,11 +606,11 @@ base::FieldTrial* field_trial = base::FeatureList::GetFieldTrial( net::features::kSplitCacheByNetworkIsolationKey); std::string current_field_trial_status = - (field_trial ? field_trial->group_name() : "None"); + (field_trial ? field_trial->group_name() : "None") + " "; field_trial = base::FeatureList::GetFieldTrial( net::features::kAppendFrameOriginToNetworkIsolationKey); current_field_trial_status += - (field_trial ? field_trial->group_name() : "None"); + (field_trial ? field_trial->group_name() : "None") + " "; field_trial = base::FeatureList::GetFieldTrial( net::features::kUseRegistrableDomainInNetworkIsolationKey); current_field_trial_status += @@ -621,7 +621,8 @@ local_state->SetString(kHttpCacheFinchExperimentGroups, current_field_trial_status); - return current_field_trial_status != previous_field_trial_status; + return !previous_field_trial_status.empty() && + current_field_trial_status != previous_field_trial_status; } network::mojom::NetworkContextParamsPtr
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index bbacdd7..6d95543 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/task/thread_pool/thread_pool_instance.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/platform_thread.h" // For |Sleep()|. #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -156,6 +157,29 @@ EXPECT_TRUE(base::Contains(encodings, "br")); } +void CheckCacheResetStatus(base::HistogramTester* histograms, bool reset) { + // TODO(crbug/1041810): The failure case, here, is to time out. Since Chrome + // doesn't synchronize cache loading, there's no guarantee that this is + // complete and it's merely available at earliest convenience. If shutdown + // occurs prior to the cache being loaded, then nothing is reported. This + // should probably be fixed to avoid the use of the sleep function, but that + // will require synchronizing in some meaningful way to guarantee the cache + // has been loaded prior to testing the histograms. + while (!histograms->GetBucketCount("HttpCache.HardReset", reset)) { + content::FetchHistogramsFromChildProcesses(); + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(5)); + } + + if (reset) { + // Some tests load the cache multiple times, but should only be reset once. + EXPECT_EQ(histograms->GetBucketCount("HttpCache.HardReset", true), 1); + } else { + // Make sure it's never reset. + EXPECT_EQ(histograms->GetBucketCount("HttpCache.HardReset", true), 0); + } +} + class ProfileNetworkContextServiceCacheSameBrowsertest : public ProfileNetworkContextServiceBrowsertest { public: @@ -170,40 +194,36 @@ ProfileNetworkContextServiceBrowsertest::SetUp(); } - void CheckCacheNotReset() { - content::FetchHistogramsFromChildProcesses(); - SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // Some tests load the cache multiple times, so compare to zero. - EXPECT_GT(histograms_.GetBucketCount("HttpCache.HardReset", false), 0); - // Make sure it's never reset. - EXPECT_EQ(histograms_.GetBucketCount("HttpCache.HardReset", true), 0); - } + base::HistogramTester histograms_; private: base::test::ScopedFeatureList scoped_feature_list_; - base::HistogramTester histograms_; }; -// Flaky on Linux and Mac: https://crbug.com/1041810 -#if defined(OS_LINUX) || defined(OS_MACOSX) -#define MAYBE_TestCacheResetParameter DISABLED_TestCacheResetParameter -#else -#define MAYBE_TestCacheResetParameter TestCacheResetParameter -#endif IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheSameBrowsertest, - MAYBE_TestCacheResetParameter) { - base::RunLoop().RunUntilIdle(); - base::ThreadPoolInstance::Get()->FlushForTesting(); + PRE_TestCacheResetParameter) { + CheckCacheResetStatus(&histograms_, false); - // At this point, we have already called the initialization once on startup. + // At this point, we have already called the initialization. // Verify that we have the correct values in the local_state. PrefService* local_state = g_browser_process->local_state(); DCHECK_EQ( local_state->GetString( "profile_network_context_service.http_cache_finch_experiment_groups"), - "NoneNoneNone"); + "None None None"); +} - CheckCacheNotReset(); +IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheSameBrowsertest, + TestCacheResetParameter) { + CheckCacheResetStatus(&histograms_, false); + + // At this point, we have already called the initialization. + // Verify that we have the correct values in the local_state. + PrefService* local_state = g_browser_process->local_state(); + DCHECK_EQ( + local_state->GetString( + "profile_network_context_service.http_cache_finch_experiment_groups"), + "None None None"); } class ProfileNetworkContextServiceCacheChangeBrowsertest @@ -217,33 +237,45 @@ } ~ProfileNetworkContextServiceCacheChangeBrowsertest() override = default; - void CheckCacheReset() { - content::FetchHistogramsFromChildProcesses(); - SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // Some tests load the cache multiple times, but should only be reset once. - EXPECT_EQ(histograms_.GetBucketCount("HttpCache.HardReset", true), 1); - } + base::HistogramTester histograms_; private: base::test::ScopedFeatureList scoped_feature_list_; - base::HistogramTester histograms_; }; // Flaky on Linux and Mac: https://crbug.com/1041810 +// The first time we load, even if we're in an experiment there's no reset +// from the unknown state. IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheChangeBrowsertest, - MAYBE_TestCacheResetParameter) { - base::RunLoop().RunUntilIdle(); - base::ThreadPoolInstance::Get()->FlushForTesting(); + PRE_TestCacheResetParameter) { + CheckCacheResetStatus(&histograms_, false); - // At this point, we have already called the initialization once on startup. + // At this point, we have already called the initialization. // Verify that we have the correct values in the local_state. PrefService* local_state = g_browser_process->local_state(); DCHECK_EQ( local_state->GetString( "profile_network_context_service.http_cache_finch_experiment_groups"), - "Nonescoped_feature_list_trial_groupNone"); + "None scoped_feature_list_trial_group None"); + // Set the local state for the next test. + local_state->SetString( + "profile_network_context_service.http_cache_finch_experiment_groups", + "None None None"); +} - CheckCacheReset(); +// The second time we load we know the state, which was "None None None" for the +// previous test, so we should see a reset being in an experiment. +IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheChangeBrowsertest, + TestCacheResetParameter) { + CheckCacheResetStatus(&histograms_, true); + + // At this point, we have already called the initialization once. + // Verify that we have the correct values in the local_state. + PrefService* local_state = g_browser_process->local_state(); + DCHECK_EQ( + local_state->GetString( + "profile_network_context_service.http_cache_finch_experiment_groups"), + "None scoped_feature_list_trial_group None"); } class AmbientAuthenticationTestWithPolicy
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc index 735fff5..9ad0ca5e 100644 --- a/chrome/browser/notifications/notification_platform_bridge_linux.cc +++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -63,6 +63,7 @@ // DBus methods. const char kMethodCloseNotification[] = "CloseNotification"; const char kMethodGetCapabilities[] = "GetCapabilities"; +const char kMethodListActivatableNames[] = "ListActivatableNames"; const char kMethodNameHasOwner[] = "NameHasOwner"; const char kMethodNotify[] = "Notify"; @@ -251,7 +252,7 @@ return resource_file; } -bool CheckNotificationsNameHasOwner(dbus::Bus* bus) { +bool CheckNotificationsNameHasOwnerOrIsActivatable(dbus::Bus* bus) { dbus::ObjectProxy* dbus_proxy = bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS)); dbus::MethodCall name_has_owner_call(DBUS_INTERFACE_DBUS, @@ -263,7 +264,22 @@ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); dbus::MessageReader reader(name_has_owner_response.get()); bool owned = false; - return name_has_owner_response && reader.PopBool(&owned) && owned; + if (name_has_owner_response && reader.PopBool(&owned) && owned) + return true; + + // If the service currently isn't running, maybe it is activatable. + dbus::MethodCall list_activatable_names_call(DBUS_INTERFACE_DBUS, + kMethodListActivatableNames); + std::unique_ptr<dbus::Response> list_activatable_names_response = + dbus_proxy->CallMethodAndBlock(&list_activatable_names_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); + if (list_activatable_names_response) { + dbus::MessageReader reader(list_activatable_names_response.get()); + std::vector<std::string> activatable_names; + reader.PopArrayOfStrings(&activatable_names); + return base::Contains(activatable_names, kFreedesktopNotificationsName); + } + return false; } } // namespace @@ -441,7 +457,7 @@ bus_ = base::MakeRefCounted<dbus::Bus>(bus_options); } - if (!CheckNotificationsNameHasOwner(bus_.get())) { + if (!CheckNotificationsNameHasOwnerOrIsActivatable(bus_.get())) { OnConnectionInitializationFinishedOnTaskRunner( ConnectionInitializationStatusCode:: NATIVE_NOTIFICATIONS_NOT_SUPPORTED);
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc index 9f089a98..66cdd8f 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" -#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros_local.h" #include "base/rand_util.h" #include "base/sequenced_task_runner.h" @@ -556,34 +555,10 @@ hints_fetcher_->FetchOptimizationGuideServiceHints( top_hosts, std::vector<GURL>{}, registered_optimization_types_, optimization_guide::proto::CONTEXT_BATCH_UPDATE, - base::BindOnce(&OptimizationGuideHintsManager::OnHintsFetched, + base::BindOnce(&OptimizationGuideHintsManager::OnTopHostsHintsFetched, ui_weak_ptr_factory_.GetWeakPtr())); } -void OptimizationGuideHintsManager::OnHintsFetched( - optimization_guide::proto::RequestContext request_context, - optimization_guide::HintsFetcherRequestStatus fetch_status, - base::Optional<std::unique_ptr<optimization_guide::proto::GetHintsResponse>> - get_hints_response) { - switch (request_context) { - case optimization_guide::proto::CONTEXT_BATCH_UPDATE: - OnTopHostsHintsFetched(std::move(get_hints_response)); - UMA_HISTOGRAM_ENUMERATION( - "OptimizationGuide.HintsFetcher.RequestStatus.BatchUpdate", - fetch_status); - return; - case optimization_guide::proto::CONTEXT_PAGE_NAVIGATION: - OnPageNavigationHintsFetched(std::move(get_hints_response)); - UMA_HISTOGRAM_ENUMERATION( - "OptimizationGuide.HintsFetcher.RequestStatus.PageNavigation", - fetch_status); - return; - case optimization_guide::proto::CONTEXT_UNSPECIFIED: - NOTREACHED(); - } - NOTREACHED(); -} - void OptimizationGuideHintsManager::OnTopHostsHintsFetched( base::Optional<std::unique_ptr<optimization_guide::proto::GetHintsResponse>> get_hints_response) { @@ -751,8 +726,9 @@ target_hosts_serialized, std::vector<GURL>{}, registered_optimization_types_, optimization_guide::proto::CONTEXT_PAGE_NAVIGATION, - base::BindOnce(&OptimizationGuideHintsManager::OnHintsFetched, - ui_weak_ptr_factory_.GetWeakPtr())); + base::BindOnce( + &OptimizationGuideHintsManager::OnPageNavigationHintsFetched, + ui_weak_ptr_factory_.GetWeakPtr())); for (const auto& host : target_hosts) LoadHintForHost(host, base::DoNothing()); @@ -1050,8 +1026,9 @@ hints_fetcher_->FetchOptimizationGuideServiceHints( hosts, urls, registered_optimization_types_, optimization_guide::proto::CONTEXT_PAGE_NAVIGATION, - base::BindOnce(&OptimizationGuideHintsManager::OnHintsFetched, - ui_weak_ptr_factory_.GetWeakPtr())); + base::BindOnce( + &OptimizationGuideHintsManager::OnPageNavigationHintsFetched, + ui_weak_ptr_factory_.GetWeakPtr())); if (!hosts.empty() && !urls.empty()) { race_navigation_recorder.set_race_attempt_status(
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager.h b/chrome/browser/optimization_guide/optimization_guide_hints_manager.h index 04b45c1..26d6639 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager.h +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager.h
@@ -207,16 +207,6 @@ // Service. Used to fetch hints for origins frequently visited by the user. void FetchTopHostsHints(); - // Called when the hints have been fetched from the remote Optimization Guide - // Service and are ready for parsing or when the fetch was not able to be - // completed. - void OnHintsFetched( - optimization_guide::proto::RequestContext request_context, - optimization_guide::HintsFetcherRequestStatus fetch_status, - base::Optional< - std::unique_ptr<optimization_guide::proto::GetHintsResponse>> - get_hints_response); - // Called when the hints for the top hosts have been fetched from the remote // Optimization Guide Service and are ready for parsing. This is used when // fetching hints in batch mode.
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc index f89ff5f..54a48dd 100644 --- a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
@@ -189,32 +189,22 @@ override { switch (fetch_state_) { case HintsFetcherEndState::kFetchFailed: - std::move(hints_fetched_callback) - .Run(request_context, - optimization_guide::HintsFetcherRequestStatus::kResponseError, - base::nullopt); + std::move(hints_fetched_callback).Run(base::nullopt); return false; case HintsFetcherEndState::kFetchSuccessWithHostHints: hints_fetched_ = true; std::move(hints_fetched_callback) - .Run(request_context, - optimization_guide::HintsFetcherRequestStatus::kSuccess, - BuildHintsResponse({"host.com"}, {})); + .Run(BuildHintsResponse({"host.com"}, {})); return true; case HintsFetcherEndState::kFetchSuccessWithURLHints: hints_fetched_ = true; std::move(hints_fetched_callback) - .Run(request_context, - optimization_guide::HintsFetcherRequestStatus::kSuccess, - BuildHintsResponse({}, + .Run(BuildHintsResponse({}, {"https://somedomain.org/news/whatever"})); return true; case HintsFetcherEndState::kFetchSuccessWithNoHints: hints_fetched_ = true; - std::move(hints_fetched_callback) - .Run(request_context, - optimization_guide::HintsFetcherRequestStatus::kSuccess, - BuildHintsResponse({}, {})); + std::move(hints_fetched_callback).Run(BuildHintsResponse({}, {})); return true; } return true;
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 7d3a9ad..110fa74 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -574,6 +574,8 @@ public static final String TAB_ID_MANAGER_NEXT_ID = "org.chromium.chrome.browser.tab.TabIdManager.NEXT_ID"; + public static final String TOS_ACKED_ACCOUNTS = "ToS acknowledged accounts"; + /** * Keys for deferred recording of the outcomes of showing the clear data dialog after * Trusted Web Activity client apps are uninstalled or have their data cleared. @@ -854,6 +856,7 @@ SYNC_SESSIONS_UUID, TABBED_ACTIVITY_LAST_BACKGROUNDED_TIME_MS_PREF, TAB_ID_MANAGER_NEXT_ID, + TOS_ACKED_ACCOUNTS, TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA, TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL, TWA_DISCLOSURE_ACCEPTED_PACKAGES,
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java index a895f1a..0329f940 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java
@@ -127,6 +127,7 @@ */ public void addToStringSet(String key, String value) { mKeyChecker.checkIsKeyInUse(key); + // Construct a new set so it can be modified safely. See crbug.com/568369. Set<String> values = new HashSet<>( ContextUtils.getAppSharedPreferences().getStringSet(key, Collections.emptySet())); values.add(value); @@ -138,6 +139,7 @@ */ public void removeFromStringSet(String key, String value) { mKeyChecker.checkIsKeyInUse(key); + // Construct a new set so it can be modified safely. See crbug.com/568369. Set<String> values = new HashSet<>( ContextUtils.getAppSharedPreferences().getStringSet(key, Collections.emptySet())); if (values.remove(value)) {
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc new file mode 100644 index 0000000..2720c70 --- /dev/null +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc
@@ -0,0 +1,134 @@ +// Copyright 2020 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/renderer_context_menu/quick_answers_menu_observer.h" + +#include <utility> + +#include "base/strings/utf_string_conversions.h" +#include "build/branding_buildflags.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/profiles/profile.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" +#include "components/renderer_context_menu/render_view_context_menu_proxy.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/common/context_menu_params.h" + +namespace { + +using chromeos::quick_answers::QuickAnswer; +using chromeos::quick_answers::QuickAnswersClient; +using chromeos::quick_answers::QuickAnswersRequest; + +// TODO(llin): Update the placeholder after finalizing on the design. +constexpr char kLoadingPlaceholder[] = "Loading..."; +constexpr char kNoResult[] = "See result in Assistant"; + +} // namespace + +QuickAnswersMenuObserver::QuickAnswersMenuObserver( + RenderViewContextMenuProxy* proxy) + : proxy_(proxy) { + auto* assistant_state = ash::AssistantState::Get(); + if (assistant_state && proxy_ && proxy_->GetBrowserContext()) { + auto* browser_context = proxy_->GetBrowserContext(); + if (browser_context->IsOffTheRecord()) + return; + + quick_answers_client_ = std::make_unique<QuickAnswersClient>( + content::BrowserContext::GetDefaultStoragePartition(browser_context) + ->GetURLLoaderFactoryForBrowserProcess() + .get(), + assistant_state, this); + } +} + +QuickAnswersMenuObserver::~QuickAnswersMenuObserver() = default; + +void QuickAnswersMenuObserver::InitMenu( + const content::ContextMenuParams& params) { + if (!is_eligible_ || !proxy_ || !quick_answers_client_) + return; + + if (params.input_field_type == + blink::ContextMenuDataInputFieldType::kPassword) + return; + + auto selected_text = base::UTF16ToUTF8(params.selection_text); + if (selected_text.empty()) + return; + + // Add Quick Answer Menu item. + // TODO(llin): Update the menu item after finalizing on the design. +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + proxy_->AddMenuItemWithIcon(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + params.selection_text, kAssistantIcon); +#else + proxy_->AddMenuItem(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + params.selection_text); +#endif + proxy_->AddMenuItem(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + base::UTF8ToUTF16(kLoadingPlaceholder)); + proxy_->AddSeparator(); + + // Fetch Quick Answer. + QuickAnswersRequest request; + request.selected_text = selected_text; + quick_answers_client_->SendRequest(request); +} + +bool QuickAnswersMenuObserver::IsCommandIdSupported(int command_id) { + return (command_id == IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY || + command_id == IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER); +} + +bool QuickAnswersMenuObserver::IsCommandIdChecked(int command_id) { + return false; +} + +bool QuickAnswersMenuObserver::IsCommandIdEnabled(int command_id) { + return command_id == IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY; +} + +void QuickAnswersMenuObserver::ExecuteCommand(int command_id) { + // TODO(llin): Implements Quick Answers click action. +} + +void QuickAnswersMenuObserver::OnQuickAnswerReceived( + std::unique_ptr<QuickAnswer> quick_answer) { + if (quick_answer) { + proxy_->UpdateMenuItem( + IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*enabled=*/false, + /*hidden=*/false, + /*title=*/ + base::UTF8ToUTF16(quick_answer->primary_answer.empty() + ? kNoResult + : quick_answer->primary_answer)); + + if (!quick_answer->secondary_answer.empty()) { + proxy_->UpdateMenuItem( + IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*enabled=*/true, + /*hidden=*/false, + /*title=*/base::UTF8ToUTF16(quick_answer->secondary_answer)); + } + } else { + proxy_->UpdateMenuItem(IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*enabled=*/false, + /*hidden=*/false, + /*title=*/base::UTF8ToUTF16(kNoResult)); + } +} + +void QuickAnswersMenuObserver::OnEligibilityChanged(bool eligible) { + is_eligible_ = eligible; +} + +void QuickAnswersMenuObserver::SetQuickAnswerClientForTesting( + std::unique_ptr<chromeos::quick_answers::QuickAnswersClient> + quick_answers_client) { + quick_answers_client_ = std::move(quick_answers_client); +}
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.h b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.h new file mode 100644 index 0000000..78c03af9 --- /dev/null +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.h
@@ -0,0 +1,55 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_ +#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_ + +#include <memory> +#include <string> + +#include "chromeos/components/quick_answers/quick_answers_client.h" +#include "components/renderer_context_menu/render_view_context_menu_observer.h" + +class RenderViewContextMenuProxy; + +// A class that implements the quick answers menu. +class QuickAnswersMenuObserver + : public RenderViewContextMenuObserver, + public chromeos::quick_answers::QuickAnswersClient::QuickAnswersDelegate { + public: + QuickAnswersMenuObserver(const QuickAnswersMenuObserver&) = delete; + QuickAnswersMenuObserver& operator=(const QuickAnswersMenuObserver&) = delete; + + explicit QuickAnswersMenuObserver(RenderViewContextMenuProxy* proxy); + ~QuickAnswersMenuObserver() override; + + // RenderViewContextMenuObserver implementation. + void InitMenu(const content::ContextMenuParams& params) override; + bool IsCommandIdSupported(int command_id) override; + bool IsCommandIdChecked(int command_id) override; + bool IsCommandIdEnabled(int command_id) override; + void ExecuteCommand(int command_id) override; + + // QuickAnswersDelegate implementation. + void OnQuickAnswerReceived( + std::unique_ptr<chromeos::quick_answers::QuickAnswer> answer) override; + void OnEligibilityChanged(bool eligible) override; + + void SetQuickAnswerClientForTesting( + std::unique_ptr<chromeos::quick_answers::QuickAnswersClient> + quick_answers_client); + + private: + // The interface to add a context-menu item and update it. + RenderViewContextMenuProxy* proxy_; + + std::unique_ptr<chromeos::quick_answers::QuickAnswersClient> + quick_answers_client_; + + // Whether the feature is enabled and all eligibility criteria are met ( + // locale, consents, etc). + bool is_eligible_ = false; +}; + +#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_QUICK_ANSWERS_MENU_OBSERVER_H_
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc new file mode 100644 index 0000000..b196827 --- /dev/null +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc
@@ -0,0 +1,255 @@ +// Copyright 2020 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/renderer_context_menu/quick_answers_menu_observer.h" + +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/components/quick_answers/quick_answers_client.h" +#include "chromeos/components/quick_answers/quick_answers_model.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using chromeos::quick_answers::QuickAnswer; +using chromeos::quick_answers::QuickAnswersClient; +using chromeos::quick_answers::QuickAnswersRequest; + +using testing::_; + +class MockQuickAnswersClient : public QuickAnswersClient { + public: + MockQuickAnswersClient(network::mojom::URLLoaderFactory* url_loader_factory, + ash::AssistantState* assistant_state, + QuickAnswersMenuObserver* delegate) + : QuickAnswersClient(url_loader_factory, assistant_state, delegate) {} + + MockQuickAnswersClient(const MockQuickAnswersClient&) = delete; + MockQuickAnswersClient& operator=(const MockQuickAnswersClient&) = delete; + + // QuickAnswersClient::QuickAnswersClient: + MOCK_METHOD1(SendRequest, void(const QuickAnswersRequest&)); +}; + +MATCHER_P(QuickAnswersRequestEqual, quick_answers_request, "") { + return (arg.selected_text == quick_answers_request.selected_text); +} + +// A test class for Quick Answers. This test should be a browser test because it +//// accesses resources. +class QuickAnswersMenuObserverTest : public InProcessBrowserTest { + public: + QuickAnswersMenuObserverTest() = default; + + QuickAnswersMenuObserverTest(const QuickAnswersMenuObserverTest&) = delete; + QuickAnswersMenuObserverTest& operator=(const QuickAnswersMenuObserverTest&) = + delete; + + // InProcessBrowserTest overrides: + void SetUpOnMainThread() override { + Reset(false); + mock_quick_answers_cient_ = std::make_unique<MockQuickAnswersClient>( + /*url_loader_factory=*/nullptr, + /*assistant_state=*/ash::AssistantState::Get(), + /*delegate=*/observer_.get()); + observer_->OnEligibilityChanged(true); + } + void TearDownOnMainThread() override { + observer_.reset(); + menu_.reset(); + } + + void Reset(bool incognito) { + observer_.reset(); + menu_ = std::make_unique<MockRenderViewContextMenu>(incognito); + observer_ = std::make_unique<QuickAnswersMenuObserver>(menu_.get()); + menu_->SetObserver(observer_.get()); + } + + void InitMenu() { + content::ContextMenuParams params; + static const base::string16 selected_text = base::ASCIIToUTF16("sel"); + params.selection_text = selected_text; + observer_->InitMenu(params); + } + + MockRenderViewContextMenu* menu() { return menu_.get(); } + QuickAnswersMenuObserver* observer() { return observer_.get(); } + + protected: + void VerifyMenuItems(int index, + int expected_command_id, + const std::string& expected_title, + bool enabled) { + MockRenderViewContextMenu::MockMenuItem item; + menu()->GetMenuItem(index, &item); + EXPECT_EQ(expected_command_id, item.command_id); + EXPECT_EQ(base::UTF8ToUTF16(expected_title), item.title); + EXPECT_EQ(enabled, item.enabled); + EXPECT_FALSE(item.hidden); + } + + void MockQuickAnswerClient() { + std::unique_ptr<QuickAnswersRequest> expected_quick_answers_request = + std::make_unique<QuickAnswersRequest>(); + expected_quick_answers_request->selected_text = "sel"; + EXPECT_CALL( + *mock_quick_answers_cient_, + SendRequest(QuickAnswersRequestEqual(*expected_quick_answers_request))) + .Times(1); + observer_->SetQuickAnswerClientForTesting( + std::move(mock_quick_answers_cient_)); + } + + std::unique_ptr<QuickAnswersMenuObserver> observer_; + std::unique_ptr<MockQuickAnswersClient> mock_quick_answers_cient_; + + std::unique_ptr<MockRenderViewContextMenu> menu_; +}; + +} // namespace + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, PlaceHolderMenuItems) { + MockQuickAnswerClient(); + InitMenu(); + + // Shows quick answers loading state. + ASSERT_EQ(3u, menu()->GetMenuSize()); + + // Verify the query menu item. + VerifyMenuItems( + /*index=*/0, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*expected_title=*/"sel", + /*enabled=*/true); + // Verify the answer menu item. + VerifyMenuItems( + /*index=*/1, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*expected_title=*/"Loading...", + /*enabled=*/false); +} + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, PrimaryAnswerOnly) { + MockQuickAnswerClient(); + InitMenu(); + + std::unique_ptr<QuickAnswer> quick_answer = std::make_unique<QuickAnswer>(); + quick_answer->primary_answer = "primary answer"; + observer_->OnQuickAnswerReceived(std::move(quick_answer)); + + // Verify that quick answer menu items is showing. + ASSERT_EQ(3u, menu()->GetMenuSize()); + + // Verify the query menu item. + VerifyMenuItems( + /*index=*/0, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*expected_title=*/"sel", + /*enabled=*/true); + + // Verify the answer menu item. + VerifyMenuItems( + /*index=*/1, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*expected_title=*/"primary answer", + /*enabled=*/false); +} + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, SecondaryAnswerOnly) { + MockQuickAnswerClient(); + InitMenu(); + + std::unique_ptr<QuickAnswer> quick_answer = std::make_unique<QuickAnswer>(); + quick_answer->secondary_answer = "secondary answer"; + observer_->OnQuickAnswerReceived(std::move(quick_answer)); + + // Verify that quick answer menu items is showing. + ASSERT_EQ(3u, menu()->GetMenuSize()); + + // Verify the query menu item. + VerifyMenuItems( + /*index=*/0, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*expected_title=*/"secondary answer", + /*enabled=*/true); + + // Verify the answer menu item. + VerifyMenuItems( + /*index=*/1, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*expected_title=*/"See result in Assistant", + /*enabled=*/false); +} + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, + PrimaryAndSecondaryAnswer) { + MockQuickAnswerClient(); + InitMenu(); + + std::unique_ptr<QuickAnswer> quick_answer = std::make_unique<QuickAnswer>(); + quick_answer->primary_answer = "primary answer"; + quick_answer->secondary_answer = "secondary answer"; + observer_->OnQuickAnswerReceived(std::move(quick_answer)); + + // Verify that quick answer menu items is showing. + ASSERT_EQ(3u, menu()->GetMenuSize()); + + // Verify the query menu item. + VerifyMenuItems( + /*index=*/0, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*expected_title=*/"secondary answer", + /*enabled=*/true); + + // Verify the answer menu item. + VerifyMenuItems( + /*index=*/1, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*expected_title=*/"primary answer", + /*enabled=*/false); +} + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, NoAnswer) { + MockQuickAnswerClient(); + InitMenu(); + + observer_->OnQuickAnswerReceived(nullptr); + + // Verify that quick answer menu items is showing. + ASSERT_EQ(3u, menu()->GetMenuSize()); + + // Verify the query menu item. + VerifyMenuItems( + /*index=*/0, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY, + /*expected_title=*/"sel", + /*enabled=*/true); + + // Verify the answer menu item. + VerifyMenuItems( + /*index=*/1, + /*command_id=*/IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER, + /*expected_title=*/"See result in Assistant", + /*enabled=*/false); +} + +IN_PROC_BROWSER_TEST_F(QuickAnswersMenuObserverTest, FeatureIneligible) { + observer_->OnEligibilityChanged(false); + + // Verify that quick answer client is not called to fetch result. + EXPECT_CALL(*mock_quick_answers_cient_, SendRequest(testing::_)).Times(0); + observer_->SetQuickAnswerClientForTesting( + std::move(mock_quick_answers_cient_)); + + InitMenu(); + + // Verify that no Quick Answer menu items shown. + ASSERT_EQ(0u, menu()->GetMenuSize()); +}
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 292a302..e70bae63 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -198,6 +198,7 @@ #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/intent_helper/open_with_menu.h" #include "chrome/browser/chromeos/arc/intent_helper/start_smart_selection_action_menu.h" +#include "chrome/browser/renderer_context_menu/quick_answers_menu_observer.h" #endif using base::UserMetricsAction; @@ -804,6 +805,8 @@ void RenderViewContextMenu::InitMenu() { RenderViewContextMenuBase::InitMenu(); + AppendQuickAnswersItems(); + if (content_type_->SupportsGroup( ContextMenuContentType::ITEM_GROUP_PASSWORD)) { AppendPasswordItems(); @@ -1331,6 +1334,18 @@ #endif } +void RenderViewContextMenu::AppendQuickAnswersItems() { +#if defined(OS_CHROMEOS) + if (!quick_answers_menu_observer_) { + quick_answers_menu_observer_ = + std::make_unique<QuickAnswersMenuObserver>(this); + } + + observers_.AddObserver(quick_answers_menu_observer_.get()); + quick_answers_menu_observer_->InitMenu(params_); +#endif +} + void RenderViewContextMenu::AppendSmartSelectionActionItems() { #if defined(OS_CHROMEOS) start_smart_selection_action_menu_observer_ =
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index d5195d4..da5e511f 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -37,6 +37,7 @@ class ClickToCallContextMenuObserver; class PrintPreviewContextMenuObserver; class Profile; +class QuickAnswersMenuObserver; class SharedClipboardContextMenuObserver; class SpellingMenuObserver; class SpellingOptionsSubMenuObserver; @@ -159,6 +160,7 @@ void AppendOpenWithLinkItems(); void AppendSmartSelectionActionItems(); void AppendOpenInBookmarkAppLinkItems(); + void AppendQuickAnswersItems(); void AppendImageItems(); void AppendAudioItems(); void AppendCanvasItems(); @@ -275,6 +277,7 @@ // An observer that handles smart text selection action items. std::unique_ptr<RenderViewContextMenuObserver> start_smart_selection_action_menu_observer_; + std::unique_ptr<QuickAnswersMenuObserver> quick_answers_menu_observer_; #endif #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/chrome/browser/resources/chromeos/login/sync_consent.css b/chrome/browser/resources/chromeos/login/sync_consent.css index 034b2431..c73b1b2 100644 --- a/chrome/browser/resources/chromeos/login/sync_consent.css +++ b/chrome/browser/resources/chromeos/login/sync_consent.css
@@ -32,3 +32,19 @@ --cr-checkbox-label-padding-start: 12px; } +/* Styles used with SplitSettingsSync. */ + +#osSyncConsentFooter { + border-bottom: solid 1px var(--google-grey-300); + border-top: solid 1px var(--google-grey-300); + padding: 16px 0; +} + +#osSyncConsentToggleName { + font-weight: 500; + margin-bottom: 4px; +} + +#osSyncConsentToggleDescription { + color: var(--google-grey-700); +}
diff --git a/chrome/browser/resources/chromeos/login/sync_consent.html b/chrome/browser/resources/chromeos/login/sync_consent.html index 095d8d62..3760c05 100644 --- a/chrome/browser/resources/chromeos/login/sync_consent.html +++ b/chrome/browser/resources/chromeos/login/sync_consent.html
@@ -29,8 +29,7 @@ src1x="chrome://oobe/logo_24px-1x.svg" src2x="chrome://oobe/logo_24px-2x.svg"> </hd-iron-icon> - <div class="overview-list-item-text flex layout vertical - center-justified"> + <div class="flex layout vertical center-justified"> <div role="heading" aria-level="2" class="overview-list-item-title" consent-description> [[i18nDynamic(locale, 'syncConsentScreenChromeSyncName')]] @@ -44,8 +43,7 @@ <hd-iron-icon class="overview-list-item-icon" icon1x="sync-consent-32:googleg" icon2x="sync-consent-64:googleg"> </hd-iron-icon> - <div class="overview-list-item-text flex layout vertical - center-justified"> + <div class="flex layout vertical center-justified"> <div role ="heading" aria-level="2" class="overview-list-item-title" consent-description> [[i18nDynamic(locale, @@ -82,19 +80,18 @@ [[i18nDynamic(locale, 'osSyncConsentTitle')]] </h1> <div slot="footer" class="layout vertical"> - <div class="overview-list-item flex layout horizontal center"> - <div class="overview-list-item-text flex layout vertical - center-justified"> - <div role="heading" aria-level="2" class="overview-list-item-title" - id="enableOsSyncLabel" consent-description> + <div id="osSyncConsentFooter" class="flex layout horizontal center"> + <div class="flex layout vertical center-justified"> + <div role="heading" aria-level="2" id="osSyncConsentToggleName" + consent-description> [[i18nDynamic(locale, 'osSyncConsentToggleName')]] </div> - <div class="overview-list-item-description" consent-description> + <div id="osSyncConsentToggleDescription" consent-description> [[i18nDynamic(locale, 'osSyncConsentToggleDescription')]] </div> </div> <cr-toggle id="enableOsSyncToggle" checked - aria-labelledby="enableOsSyncLabel"> + aria-labelledby="osSyncConsentToggleName"> </cr-toggle> </div> </div>
diff --git a/chrome/browser/resources/chromeos/smb_shares/OWNERS b/chrome/browser/resources/chromeos/smb_shares/OWNERS index 704b95c8..0da0ab6 100644 --- a/chrome/browser/resources/chromeos/smb_shares/OWNERS +++ b/chrome/browser/resources/chromeos/smb_shares/OWNERS
@@ -1 +1,3 @@ -khorimoto@chromium.org \ No newline at end of file +amistry@chromium.org + +# COMPONENT: Enterprise>ActiveDirectory \ No newline at end of file
diff --git a/chrome/browser/resources/downloads/OWNERS b/chrome/browser/resources/downloads/OWNERS index 455bfb5..cb00587 100644 --- a/chrome/browser/resources/downloads/OWNERS +++ b/chrome/browser/resources/downloads/OWNERS
@@ -1,3 +1 @@ -dbeam@chromium.org - # COMPONENT: UI>Browser>Downloads
diff --git a/chrome/browser/resources/history/OWNERS b/chrome/browser/resources/history/OWNERS index 5152930..5e21905 100644 --- a/chrome/browser/resources/history/OWNERS +++ b/chrome/browser/resources/history/OWNERS
@@ -1,4 +1,3 @@ calamity@chromium.org -dbeam@chromium.org # COMPONENT: UI>Browser>History
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index 74aab7e1..e3d9220 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -227,6 +227,20 @@ #realbox-icon { background-position: center center; background-repeat: no-repeat; + bottom: 0; + left: 16px; + margin: auto; + position: absolute; + top: 0; + width: 24px; +} + +[dir=rtl] #realbox-icon { + left: auto; + right: 16px; +} + +#realbox-icon.load-favicon { background-size: 24px; } @@ -500,8 +514,7 @@ right: auto; } -#realbox-input-wrapper > :-webkit-any(.google-g-icon, .microphone-icon, - .search-icon) { +#realbox-input-wrapper > :-webkit-any(#realbox-icon, .microphone-icon) { z-index: 3; }
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html index 3c24062..e09bb54f 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.html +++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -78,7 +78,8 @@ <div id="realbox-container" $i18n{hiddenIfRealboxDisabled}> <div id="realbox-input-wrapper"> - <div id="realbox-icon" class="$i18n{realboxIconClass}"></div> + <div id="realbox-icon" class="$i18n{realboxIconClass}" + data-realbox-icon-class="$i18n{realboxIconClass}"></div> <input id="realbox" type="search" autocomplete="off" spellcheck="false" aria-live="polite" autofocus> <button id="realbox-microphone" class="microphone-icon" hidden></button>
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js index bde8e39..0e9acb0 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.js +++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -91,6 +91,7 @@ IMAGE_CONTAINER: 'image-container', INITED: 'inited', // Reveals the <body> once init() is done. LEFT_ALIGN_ATTRIBUTION: 'left-align-attribution', + LOAD_FAVICON: 'load-favicon', // The image next to a realbox match. MATCH_IMAGE: 'match-image', // Vertically centers the most visited section for a non-Google provided page. @@ -724,7 +725,7 @@ // TODO(crbug.com/997229): use chrome://favicon/<url> when perms allow. const iconUrl = new URL('chrome-search://ntpicon/'); iconUrl.searchParams.set('show_fallback_monogram', 'false'); - iconUrl.searchParams.set('size', '24@' + window.devicePixelRatio + 'x'); + iconUrl.searchParams.set('size', '32@' + window.devicePixelRatio + 'x'); // The fallback color must match that of .clock-icon and .search-icon iconUrl.searchParams.set( 'color', @@ -2118,13 +2119,19 @@ /** @param {!AutocompleteMatch|undefined} match */ function setRealboxIcon(match) { - const showIcon = match && !match.isSearchType; + const loadFavicon = match && !match.isSearchType; const realboxIcon = $(IDS.REALBOX_ICON); - realboxIcon.style.webkitMask = showIcon ? 'none' : ''; - realboxIcon.style.backgroundColor = showIcon ? 'transparent' : ''; + realboxIcon.style.webkitMask = loadFavicon ? 'none' : ''; + realboxIcon.style.backgroundColor = loadFavicon ? 'transparent' : ''; realboxIcon.style.backgroundImage = - showIcon ? `url(${getIconUrl(match.destinationUrl)})` : ''; + loadFavicon ? `url(${getIconUrl(match.destinationUrl)})` : ''; + + const historical = match && SEARCH_HISTORY_MATCH_TYPES.includes(match.type); + realboxIcon.className = loadFavicon ? + CLASSES.LOAD_FAVICON : + (historical ? CLASSES.CLOCK_ICON : + realboxIcon.dataset['realboxIconClass']); } /** @param {boolean} visible */
diff --git a/chrome/browser/resources/settings/OWNERS b/chrome/browser/resources/settings/OWNERS index b887eda..81a6dc6 100644 --- a/chrome/browser/resources/settings/OWNERS +++ b/chrome/browser/resources/settings/OWNERS
@@ -1,4 +1,3 @@ -dbeam@chromium.org dpapad@chromium.org dschuyler@chromium.org hcarmona@chromium.org
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index bc248ce..d143e53 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -32,7 +33,6 @@ <link rel="import" href="chrome://resources/cr_elements/chromeos/cr_picture/cr_png_behavior.html"> </if> <if expr="not chromeos"> -<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> <link rel="import" href="import_data_dialog.html"> <link rel="import" href="manage_profile.html"> </if> @@ -76,7 +76,6 @@ width: 40px; } -<if expr="not chromeos"> #toast { left: 0; z-index: 1; @@ -98,12 +97,10 @@ font-size: 1.1rem; line-height: 1.625rem; } -</if> </style> <settings-animated-pages id="pages" section="people" focus-config="[[focusConfig_]]"> <div route-path="default"> -<if expr="not chromeos"> <template is="dom-if" if="[[shouldShowSyncAccountControl_( syncStatus.syncSystemEnabled, syncStatus.signinAllowed)]]"> <settings-sync-account-control @@ -117,8 +114,8 @@ "$i18n{peopleSignInPromptSecondaryWithNoAccount}"> </settings-sync-account-control> </template> - <template is="dom-if" if="[[!diceEnabled_]]"> -</if> + <template is="dom-if" if="[[shouldShowProfile_( + syncStatus.syncSystemEnabled, syncStatus.signinAllowed)]]" restamp> <div id="picture-subpage-trigger" class="settings-box first two-line"> <template is="dom-if" if="[[syncStatus]]"> <div id="profile-icon" on-click="onProfileTap_" @@ -151,6 +148,7 @@ aria-describedby="profile-name"></cr-icon-button> </if> </div> +<!-- Chrome OS is always signed-in and does not show a sign-out button. --> <if expr="not chromeos"> <template is="dom-if" if="[[showSignin_(syncStatus)]]"> <div class="separator"></div> @@ -169,14 +167,12 @@ </if> </template> </div> -<if expr="not chromeos"> - </template> <!-- if="[[!diceEnabled_]]" --> -</if> + </template> <!-- if="[[shouldShowProfile_()]]" --> - <template is="dom-if" if="[[!syncStatus.signedIn]]"> +<!-- Chrome OS uses settings-sync-account-control for sync promos. --> <if expr="not chromeos"> + <template is="dom-if" if="[[!syncStatus.signedIn]]"> <template is="dom-if" if="[[!diceEnabled_]]"> -</if> <div class="settings-box two-line" id="sync-overview" hidden="[[!syncStatus.signinAllowed]]"> <div class="start settings-box-text"> @@ -186,10 +182,9 @@ </a> </div> </div> -<if expr="not chromeos"> </template> <!-- if="[[!diceEnabled_]]" --> -</if> </template> +</if> <cr-link-row id="sync-setup" label="$i18n{syncAndNonPersonalizedServices}" @@ -230,9 +225,6 @@ page-title="$i18n{syncPageTitle}" learn-more-url="$i18n{syncAndGoogleServicesLearnMoreURL}"> <settings-sync-page -<if expr="not chromeos"> - dice-enabled="[[diceEnabled_]]" -</if> sync-status="[[syncStatus]]" prefs="{{prefs}}" page-visibility="[[pageVisibility.privacy]]"> </settings-sync-page> @@ -272,11 +264,9 @@ on-close="onImportDataDialogClosed_"> </settings-import-data-dialog> </template> -<if expr="not chromeos"> <cr-toast duration="3000" id="toast"> <span>$i18n{syncSettingsSavedToast}</span> </cr-toast> -</if> </template> <script src="people_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index 4d5bd65..979bb9e8 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -25,6 +25,7 @@ notify: true, }, + // Chrome OS does not support DICE. // <if expr="not chromeos"> /** * This flag is used to conditionally show a set of new sign-in UIs to the @@ -278,13 +279,7 @@ this.syncStatus = syncStatus; - if ( - shouldRecordSigninImpression - // <if expr="not chromeos"> - // Sync account control is not shown on Chrome OS. - && !this.shouldShowSyncAccountControl_() - // </if> - ) { + if (shouldRecordSigninImpression && !this.shouldShowSyncAccountControl_()) { // SyncAccountControl records the impressions user actions. chrome.metricsPrivate.recordUserAction('Signin_Impression_FromSettings'); } @@ -334,10 +329,6 @@ } // </if> - // <if expr="chromeos"> - cr.ui.focusWithoutInk(assert(this.$$('#disconnectButton'))); - // </if> - if (settings.Router.getInstance().getCurrentRoute() == settings.routes.SIGN_OUT) { settings.Router.getInstance().navigateToPreviousRoute(); @@ -366,6 +357,7 @@ settings.Router.getInstance().navigateToPreviousRoute(); cr.ui.focusWithoutInk(assert(this.$.importDataDialogTrigger)); }, + // </if> /** * Open URL for managing your Google Account. @@ -385,11 +377,30 @@ if (this.syncStatus == undefined) { return false; } - + // <if expr="chromeos"> + if (!loadTimeData.getBoolean('splitSettingsSyncEnabled')) { + return false; + } + // </if> return !!this.syncStatus.syncSystemEnabled && !!this.syncStatus.signinAllowed; }, - // </if> + + /** + * @return {boolean} Whether to show the profile row and associated controls. + * @private + */ + shouldShowProfile_() { + // Closure compiler doesn't understand <if> so use a variable. + let show = false; + // <if expr="chromeos"> + show = !this.shouldShowSyncAccountControl_(); + // </if> + // <if expr="not chromeos"> + show = !this.diceEnabled_; + // </if> + return show; + }, /** * @param {string} iconUrl
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index 39412e4..35954f1a 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -147,10 +147,6 @@ 'syncPrefs.trustedVaultKeysRequired)', }, - // <if expr="not chromeos"> - diceEnabled: Boolean, - // </if> - /** @private */ showSetupCancelDialog_: { type: Boolean,
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index 5ff5fb7..5093a5e 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -561,11 +561,11 @@ } TEST_F(ChromePasswordProtectionServiceTest, VerifyCanSendSamplePing) { - // If experiment is not enabled, do not send ping. + // Experiment is on by default. service_->ConfigService(/*is_incognito=*/false, /*is_extended_reporting=*/true); service_->set_bypass_probability_for_tests(true); - EXPECT_FALSE(service_->CanSendSamplePing()); + EXPECT_TRUE(service_->CanSendSamplePing()); { base::test::ScopedFeatureList feature_list;
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc index f7e3fbd..5b7fa064 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -143,7 +143,7 @@ return IsSupportedDownload(*item_, item_->GetTargetFilePath(), reason, type); } -content::BrowserContext* CheckClientDownloadRequest::GetBrowserContext() { +content::BrowserContext* CheckClientDownloadRequest::GetBrowserContext() const { return content::DownloadItemUtils::GetBrowserContext(item_); } @@ -244,6 +244,17 @@ item_->RemoveObserver(this); } +bool CheckClientDownloadRequest::ShouldPromptForDeepScanning( + DownloadCheckResultReason reason) const { + if (reason != REASON_DOWNLOAD_UNCOMMON) + return false; + + Profile* profile = Profile::FromBrowserContext(GetBrowserContext()); + return base::FeatureList::IsEnabled(kPromptAppForDeepScanning) && + AdvancedProtectionStatusManagerFactory::GetForProfile(profile) + ->IsUnderAdvancedProtection(); +} + bool CheckClientDownloadRequest::ShouldUploadForDlpScan() { if (!base::FeatureList::IsEnabled(kContentComplianceEnabled)) return false;
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h index 33062a9..ca0528f 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h
@@ -50,7 +50,7 @@ // CheckClientDownloadRequestBase overrides: bool IsSupportedDownload(DownloadCheckResultReason* reason, ClientDownloadRequest::DownloadType* type) override; - content::BrowserContext* GetBrowserContext() override; + content::BrowserContext* GetBrowserContext() const override; bool IsCancelled() override; void PopulateRequest(ClientDownloadRequest* request) override; base::WeakPtr<CheckClientDownloadRequestBase> GetWeakPtr() override; @@ -71,6 +71,11 @@ void NotifyRequestFinished(DownloadCheckResult result, DownloadCheckResultReason reason) override; + // Called when finishing the download, to decide whether to prompt the user + // for deep scanning or not. + bool ShouldPromptForDeepScanning( + DownloadCheckResultReason reason) const override; + // Returns true when the file should be uploaded for a DLP compliance scan. // This consults the CheckContentCompliance enterprise policy. bool ShouldUploadForDlpScan();
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc index 77c015d8..25855e4 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc
@@ -229,10 +229,11 @@ UploadBinary(); did_upload_binary = true; } + } else if (ShouldPromptForDeepScanning(reason)) { + result = DownloadCheckResult::PROMPT_FOR_SCANNING; + reason = DownloadCheckResultReason::REASON_ADVANCED_PROTECTION_PROMPT; } - DVLOG(2) << "SafeBrowsing download verdict for: " << source_url_ - << " verdict:" << reason << " result:" << static_cast<int>(result); UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", reason, REASON_MAX);
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h index 7d67d0b..67eeb19fe7 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h
@@ -102,7 +102,7 @@ virtual bool IsSupportedDownload( DownloadCheckResultReason* reason, ClientDownloadRequest::DownloadType* type) = 0; - virtual content::BrowserContext* GetBrowserContext() = 0; + virtual content::BrowserContext* GetBrowserContext() const = 0; virtual bool IsCancelled() = 0; virtual base::WeakPtr<CheckClientDownloadRequestBase> GetWeakPtr() = 0; @@ -143,6 +143,11 @@ virtual void NotifyRequestFinished(DownloadCheckResult result, DownloadCheckResultReason reason) = 0; + // Called when finishing the download, to decide whether to prompt the user + // for deep scanning or not. + virtual bool ShouldPromptForDeepScanning( + DownloadCheckResultReason reason) const = 0; + // Source URL being downloaded from. This shuold always be set, but could be // for example an artificial blob: URL if there is no source URL. const GURL source_url_;
diff --git a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc index 5967ded..37004a5a 100644 --- a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.cc
@@ -92,8 +92,8 @@ return true; } -content::BrowserContext* -CheckNativeFileSystemWriteRequest::GetBrowserContext() { +content::BrowserContext* CheckNativeFileSystemWriteRequest::GetBrowserContext() + const { return item_->browser_context; } @@ -159,6 +159,11 @@ void CheckNativeFileSystemWriteRequest::UploadBinary() {} +bool CheckNativeFileSystemWriteRequest::ShouldPromptForDeepScanning( + DownloadCheckResultReason reason) const { + return false; +} + void CheckNativeFileSystemWriteRequest::NotifyRequestFinished( DownloadCheckResult result, DownloadCheckResultReason reason) {
diff --git a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h index cad4e90c..9c14e2f 100644 --- a/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_native_file_system_write_request.h
@@ -38,7 +38,7 @@ // CheckClientDownloadRequestBase overrides: bool IsSupportedDownload(DownloadCheckResultReason* reason, ClientDownloadRequest::DownloadType* type) override; - content::BrowserContext* GetBrowserContext() override; + content::BrowserContext* GetBrowserContext() const override; bool IsCancelled() override; void PopulateRequest(ClientDownloadRequest* request) override; base::WeakPtr<CheckClientDownloadRequestBase> GetWeakPtr() override; @@ -51,6 +51,8 @@ const std::string& response_body) override; bool ShouldUploadBinary(DownloadCheckResultReason reason) override; void UploadBinary() override; + bool ShouldPromptForDeepScanning( + DownloadCheckResultReason reason) const override; void NotifyRequestFinished(DownloadCheckResult result, DownloadCheckResultReason reason) override;
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_request.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_request.cc index 56b37b5..fbfc770 100644 --- a/chrome/browser/safe_browsing/download_protection/deep_scanning_request.cc +++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_request.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/safe_browsing/download_protection/deep_scanning_request.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback_forward.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h" @@ -13,6 +16,9 @@ #include "chrome/browser/safe_browsing/download_protection/download_item_request.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.h" #include "components/download/public/common/download_item.h" #include "components/policy/core/browser/url_util.h" #include "components/policy/core/common/cloud/dm_token.h" @@ -195,7 +201,7 @@ /*response=*/response); Profile* profile = Profile::FromBrowserContext( content::DownloadItemUtils::GetBrowserContext(item_)); - if (profile) { + if (profile && trigger_ == DeepScanTrigger::TRIGGER_POLICY) { std::string raw_digest_sha256 = item_->GetHash(); MaybeReportDeepScanningVerdict( profile, item_->GetURL(), item_->GetTargetFilePath().AsUTF8Unsafe(), @@ -208,6 +214,16 @@ DownloadCheckResult download_result = DownloadCheckResult::UNKNOWN; if (result == BinaryUploadService::Result::SUCCESS) { DeepScanningClientResponseToDownloadCheckResult(response, &download_result); + } else if (trigger_ == DeepScanTrigger::TRIGGER_APP_PROMPT && + MaybeShowDeepScanFailureModalDialog( + base::BindOnce(&DeepScanningRequest::Start, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&DeepScanningRequest::FinishRequest, + weak_ptr_factory_.GetWeakPtr(), + DownloadCheckResult::UNKNOWN), + base::BindOnce(&DeepScanningRequest::OpenDownload, + weak_ptr_factory_.GetWeakPtr()))) { + return; } FinishRequest(download_result); @@ -225,4 +241,30 @@ download_service_->RequestFinished(this); } +bool DeepScanningRequest::MaybeShowDeepScanFailureModalDialog( + base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback) { + Profile* profile = Profile::FromBrowserContext( + content::DownloadItemUtils::GetBrowserContext(item_)); + if (!profile) + return false; + + Browser* browser = + chrome::FindTabbedBrowser(profile, /*match_original_profiles=*/false); + if (!browser) + return false; + + DeepScanningFailureModalDialog::ShowForWebContents( + browser->tab_strip_model()->GetActiveWebContents(), + std::move(accept_callback), std::move(cancel_callback), + std::move(open_now_callback)); + return true; +} + +void DeepScanningRequest::OpenDownload() { + item_->OpenDownload(); + FinishRequest(DownloadCheckResult::UNKNOWN); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_request.h b/chrome/browser/safe_browsing/download_protection/deep_scanning_request.h index ced372c2..9fb5ac00 100644 --- a/chrome/browser/safe_browsing/download_protection/deep_scanning_request.h +++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_request.h
@@ -60,6 +60,15 @@ // Callback when |item_| is destroyed. void OnDownloadDestroyed(download::DownloadItem* download) override; + // Called to attempt to show the modal dialog for scan failure. Returns + // whether the dialog was successfully shown. + bool MaybeShowDeepScanFailureModalDialog(base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback); + + // Called to open the download. This is triggered by the timeout modal dialog. + void OpenDownload(); + // The download item to scan. This is unowned, and could become nullptr if the // download is destroyed. download::DownloadItem* item_;
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_util.h b/chrome/browser/safe_browsing/download_protection/download_protection_util.h index de4be79d..1bc4eb8 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_util.h +++ b/chrome/browser/safe_browsing/download_protection/download_protection_util.h
@@ -27,7 +27,8 @@ BLOCKED_TOO_LARGE, SENSITIVE_CONTENT_WARNING, SENSITIVE_CONTENT_BLOCK, - DEEP_SCANNED_SAFE + DEEP_SCANNED_SAFE, + PROMPT_FOR_SCANNING, }; // Enum to keep track why a particular download verdict was chosen. @@ -67,6 +68,7 @@ REASON_SENSITIVE_CONTENT_WARNING = 31, REASON_SENSITIVE_CONTENT_BLOCK = 32, REASON_DEEP_SCANNED_SAFE = 33, + REASON_ADVANCED_PROTECTION_PROMPT = 34, REASON_MAX // Always add new values before this one. };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 68eaa55..1cb5563 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -93,6 +93,8 @@ "chrome_select_file_policy.h", "color_chooser.h", "confirm_bubble.h", + "cookie_controls/cookie_controls_controller.cc", + "cookie_controls/cookie_controls_controller.h", "crypto_module_password_dialog.h", "cryptuiapi_shim.h", "enterprise_startup_dialog.h", @@ -1451,6 +1453,7 @@ "//chrome/browser/web_applications", # TODO(loyso): Erase these. crbug.com/877898. + "//chrome/browser/web_applications:common", "//chrome/browser/web_applications:web_applications_on_extensions", "//chrome/browser/web_applications/components", "//chrome/browser/web_applications/extensions", @@ -2650,8 +2653,6 @@ "autofill/payments/save_upi_bubble_controller_impl.cc", "autofill/payments/save_upi_bubble_controller_impl.h", "bubble_anchor_util.h", - "cookie_controls/cookie_controls_controller.cc", - "cookie_controls/cookie_controls_controller.h", "cookie_controls/cookie_controls_view.h", "manifest_web_app_browser_controller.cc", "manifest_web_app_browser_controller.h", @@ -3178,10 +3179,14 @@ "views/relaunch_notification/wall_clock_timer.h", "views/sad_tab_view.cc", "views/sad_tab_view.h", + "views/safe_browsing/deep_scanning_failure_modal_dialog.cc", + "views/safe_browsing/deep_scanning_failure_modal_dialog.h", "views/safe_browsing/deep_scanning_modal_dialog.cc", "views/safe_browsing/deep_scanning_modal_dialog.h", "views/safe_browsing/password_reuse_modal_warning_dialog.cc", "views/safe_browsing/password_reuse_modal_warning_dialog.h", + "views/safe_browsing/prompt_for_scanning_modal_dialog.cc", + "views/safe_browsing/prompt_for_scanning_modal_dialog.h", "views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc", "views/send_tab_to_self/send_tab_to_self_bubble_device_button.h", "views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc", @@ -4308,6 +4313,10 @@ } if (is_android) { + java_cpp_enum("cookie_controls_controller_status_javagen") { + sources = [ "cookie_controls/cookie_controls_controller.h" ] + } + java_cpp_enum("tab_model_enums_java") { sources = [ "android/tab_model/tab_model.h" ] }
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.cc b/chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.cc index bb22aeb..89488b5 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.cc
@@ -35,6 +35,14 @@ // Chrome, which should be hidden. if (app_id == kArcIntentHelperAppId) return false; + + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); + if (!proxy || proxy->AppRegistryCache().GetAppType(app_id) == + apps::mojom::AppType::kUnknown) { + return false; + } + return true; }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index 3490eb3ec..cfcf921 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -1303,6 +1303,17 @@ std::make_unique<AppServiceAppIconLoader>( profile_, extension_misc::EXTENSION_ICON_MEDIUM, this); app_icon_loaders_.push_back(std::move(app_service_app_icon_loader)); + + // Some special extensions open new windows, and on Chrome OS, those windows + // should show the extension icon in the shelf. Extensions are not present + // in the App Service, so try loading extensions icon using + // ChromeAppIconLoader. + std::unique_ptr<extensions::ChromeAppIconLoader> chrome_app_icon_loader = + std::make_unique<extensions::ChromeAppIconLoader>( + profile_, extension_misc::EXTENSION_ICON_MEDIUM, + base::BindRepeating(&app_list::MaybeResizeAndPadIconForMd), this); + chrome_app_icon_loader->SetExtensionsOnly(); + app_icon_loaders_.push_back(std::move(chrome_app_icon_loader)); } else { // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded // image is associated with a profile (its loader requires the profile). @@ -1352,9 +1363,19 @@ std::unique_ptr<LauncherAppUpdater> app_service_app_updater( new LauncherAppServiceAppUpdater(this, profile())); app_updaters_.push_back(std::move(app_service_app_updater)); + + // Some special extensions open new windows, and on Chrome OS, those windows + // should show the extension icon in the shelf. Extensions are not present + // in the App Service, so use LauncherExtensionAppUpdater to handle + // extensions life-cycle events. + std::unique_ptr<LauncherExtensionAppUpdater> extension_app_updater( + new LauncherExtensionAppUpdater(this, profile(), + true /* extensions_only */)); + app_updaters_.push_back(std::move(extension_app_updater)); } else { std::unique_ptr<LauncherAppUpdater> extension_app_updater( - new LauncherExtensionAppUpdater(this, profile())); + new LauncherExtensionAppUpdater(this, profile(), + false /* extensions_only */)); app_updaters_.push_back(std::move(extension_app_updater)); if (arc::IsArcAllowedForProfile(profile())) {
diff --git a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc index 4817b53..8968599 100644 --- a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc +++ b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc
@@ -13,10 +13,15 @@ LauncherExtensionAppUpdater::LauncherExtensionAppUpdater( Delegate* delegate, - content::BrowserContext* browser_context) - : LauncherAppUpdater(delegate, browser_context) { + content::BrowserContext* browser_context, + bool extensions_only) + : LauncherAppUpdater(delegate, browser_context), + extensions_only_(extensions_only) { StartObservingExtensionRegistry(); + if (extensions_only) + return; + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(browser_context); if (prefs) prefs->AddObserver(this); @@ -25,6 +30,9 @@ LauncherExtensionAppUpdater::~LauncherExtensionAppUpdater() { StopObservingExtensionRegistry(); + if (extensions_only_) + return; + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(browser_context()); if (prefs) prefs->RemoveObserver(this); @@ -33,13 +41,17 @@ void LauncherExtensionAppUpdater::OnExtensionLoaded( content::BrowserContext* browser_context, const extensions::Extension* extension) { - delegate()->OnAppInstalled(browser_context, extension->id()); + if (ShouldHandleExtension(extension)) + delegate()->OnAppInstalled(browser_context, extension->id()); } void LauncherExtensionAppUpdater::OnExtensionUnloaded( content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UnloadedExtensionReason reason) { + if (!ShouldHandleExtension(extension)) + return; + if (reason == extensions::UnloadedExtensionReason::UNINSTALL) delegate()->OnAppUninstalledPrepared(browser_context, extension->id()); else @@ -50,7 +62,8 @@ content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UninstallReason reason) { - delegate()->OnAppUninstalled(browser_context, extension->id()); + if (ShouldHandleExtension(extension)) + delegate()->OnAppUninstalled(browser_context, extension->id()); } void LauncherExtensionAppUpdater::OnShutdown( @@ -102,3 +115,8 @@ for (const auto& iter : extension_ids) UpdateApp(iter); } + +bool LauncherExtensionAppUpdater::ShouldHandleExtension( + const extensions::Extension* extension) const { + return !extensions_only_ || extension->is_extension(); +}
diff --git a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h index dd3116d1..e0b272c 100644 --- a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h +++ b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h
@@ -18,7 +18,8 @@ public ArcAppListPrefs::Observer { public: LauncherExtensionAppUpdater(Delegate* delegate, - content::BrowserContext* browser_context); + content::BrowserContext* browser_context, + bool extensions_only); ~LauncherExtensionAppUpdater() override; // ExtensionRegistryObserver: @@ -46,8 +47,14 @@ void UpdateApp(const std::string& app_id); void UpdateEquivalentApp(const std::string& arc_package_name); + bool ShouldHandleExtension(const extensions::Extension* extension) const; + extensions::ExtensionRegistry* extension_registry_ = nullptr; + // Handles life-cycle events for extensions only if true, otherwise handles + // life-cycle events for both Chrome apps and extensions. + const bool extensions_only_; + DISALLOW_COPY_AND_ASSIGN(LauncherExtensionAppUpdater); };
diff --git a/chrome/browser/ui/cookie_controls/cookie_controls_controller.h b/chrome/browser/ui/cookie_controls/cookie_controls_controller.h index 2481c483..74358b2 100644 --- a/chrome/browser/ui/cookie_controls/cookie_controls_controller.h +++ b/chrome/browser/ui/cookie_controls/cookie_controls_controller.h
@@ -22,15 +22,18 @@ class CookieControlsView; // A controller for CookieControlsIconView and CookieControlsBubbleView. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.settings.website +// GENERATED_JAVA_CLASS_NAME_OVERRIDE: CookieControlsControllerStatus class CookieControlsController { public: enum class Status { kUninitialized, - // Cookie blocking is enabled. + // Third-Party cookie blocking is enabled. kEnabled, - // Cookie blocking is disabled. + // Third-Party cookie blocking is disabled. kDisabled, - // Cookie blocking is enabled in general but was disabled for this site. + // Third-Party cookie blocking is enabled in general but was disabled + // for this site. kDisabledForSite, };
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index cc04468..29e29a8 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -35,7 +35,7 @@ #include "chrome/browser/web_applications/components/file_handler_manager.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_launch/web_launch_files_helper.h" #include "chrome/common/chrome_features.h" @@ -268,8 +268,8 @@ } if (extension->from_bookmark()) { - web_app::WebAppTabHelper* tab_helper = - web_app::WebAppTabHelper::FromWebContents(contents); + web_app::WebAppTabHelperBase* tab_helper = + web_app::WebAppTabHelperBase::FromWebContents(contents); DCHECK(tab_helper); tab_helper->SetAppId(extension->id()); } @@ -445,8 +445,8 @@ // TODO(https://crbug.com/1032443): // Eventually move this to browser_navigator.cc: CreateTargetContents(). if (extension && extension->from_bookmark()) { - web_app::WebAppTabHelper* tab_helper = - web_app::WebAppTabHelper::FromWebContents(web_contents); + web_app::WebAppTabHelperBase* tab_helper = + web_app::WebAppTabHelperBase::FromWebContents(web_contents); DCHECK(tab_helper); tab_helper->SetAppId(extension->id()); }
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index b5eeee713f..654b5f9c 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -139,8 +139,8 @@ #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" #include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" #include "chrome/browser/web_applications/components/web_app_utils.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "extensions/browser/view_type_utils.h" #endif
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index e104656..83d2d6a 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -45,6 +45,7 @@ #include "chrome/browser/ui/views/download/download_shelf_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/safe_browsing/deep_scanning_modal_dialog.h" +#include "chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/download/public/common/download_danger_type.h" @@ -664,18 +665,6 @@ return; } - if (IsShowingDeepScanning() && sender == open_button_) { - content::WebContents* current_web_contents = - shelf_->browser()->tab_strip_model()->GetActiveWebContents(); - open_now_modal_dialog_ = TabModalConfirmDialog::Create( - std::make_unique<safe_browsing::DeepScanningModalDialog>( - current_web_contents, - base::BindOnce(&DownloadItemView::OpenDownloadDuringAsyncScanning, - weak_ptr_factory_.GetWeakPtr())), - current_web_contents); - return; - } - if (sender == dropdown_button_) { // TODO(estade): this is copied from ToolbarActionView but should be shared // one way or another. @@ -706,6 +695,29 @@ } if (sender == open_button_) { + if (IsShowingDeepScanning()) { + content::WebContents* current_web_contents = + shelf_->browser()->tab_strip_model()->GetActiveWebContents(); + open_now_modal_dialog_ = TabModalConfirmDialog::Create( + std::make_unique<safe_browsing::DeepScanningModalDialog>( + current_web_contents, + base::BindOnce(&DownloadItemView::OpenDownloadDuringAsyncScanning, + weak_ptr_factory_.GetWeakPtr())), + current_web_contents); + return; + } + if (model_->GetDangerType() == + download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING) { + content::WebContents* current_web_contents = + shelf_->browser()->tab_strip_model()->GetActiveWebContents(); + safe_browsing::PromptForScanningModalDialog::ShowForWebContents( + current_web_contents, + base::BindOnce(&DownloadItemView::ConfirmDeepScanning, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&DownloadItemView::BypassDeepScanning, + weak_ptr_factory_.GetWeakPtr())); + return; + } if (IsShowingWarningDialog()) return; if (complete_animation_.get() && complete_animation_->is_animating()) @@ -715,7 +727,7 @@ } if (sender == scan_button_) { - DownloadCommands(model_.get()).ExecuteCommand(DownloadCommands::DEEP_SCAN); + ConfirmDeepScanning(); return; } @@ -1062,10 +1074,14 @@ dangerous_label, /*listener=*/nullptr); dangerous_download_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); dangerous_download_label->SetAutoColorReadabilityEnabled(false); + dangerous_download_label->set_can_process_events_within_subtree(false); dangerous_download_label_ = AddChildView(std::move(dangerous_download_label)); SizeLabelToMinWidth(); - open_button_->SetEnabled(false); + bool open_button_enabled = + (model_->GetDangerType() == + download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING); + open_button_->SetEnabled(open_button_enabled); file_name_label_->SetVisible(false); status_label_->SetVisible(false); dropdown_button_->SetVisible(mode_ == MALICIOUS_MODE); @@ -1506,3 +1522,12 @@ ? 20 : 27; } + +void DownloadItemView::ConfirmDeepScanning() { + DownloadCommands(model_.get()).ExecuteCommand(DownloadCommands::DEEP_SCAN); +} + +void DownloadItemView::BypassDeepScanning() { + DownloadCommands(model_.get()) + .ExecuteCommand(DownloadCommands::BYPASS_DEEP_SCANNING); +}
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h index 7e3cd4e..051cbc583 100644 --- a/chrome/browser/ui/views/download/download_item_view.h +++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -306,6 +306,12 @@ // Returns the height/width of the error icon, in dp. static int GetErrorIconSize(); + // Starts deep scanning for this download item. + void ConfirmDeepScanning(); + + // Bypasses the prompt for deep scanning for this download item. + void BypassDeepScanning(); + // The download shelf that owns us. DownloadShelfView* shelf_;
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc index 161260e..4b7b125 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -206,11 +206,8 @@ views::style::STYLE_SECONDARY); description->SetMultiLine(true); description->SetHorizontalAlignment(gfx::ALIGN_LEFT); - description->SetBorder(views::CreateEmptyBorder( - 0, horizontal_spacing, - ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_RELATED_CONTROL_VERTICAL_SMALL), - horizontal_spacing)); + description->SetBorder(views::CreateEmptyBorder(0, horizontal_spacing, + 0, horizontal_spacing)); container->AddChildView(std::move(description)); // Add a (currently empty) section for the menu items of the section.
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index bdb8d442..0eb59ac 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/ui/views/extensions/pwa_confirmation_bubble_view.h" #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/web_applications/components/web_app_constants.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" #include "chrome/grit/generated_resources.h" #include "components/omnibox/browser/vector_icons.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.cc b/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.cc new file mode 100644 index 0000000..792a6a71 --- /dev/null +++ b/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.cc
@@ -0,0 +1,114 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.h" + +#include <memory> + +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/grit/generated_resources.h" +#include "components/constrained_window/constrained_window_views.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/ui_base_types.h" +#include "ui/views/controls/button/md_text_button.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/window/dialog_delegate.h" + +namespace safe_browsing { + +/*static*/ +void DeepScanningFailureModalDialog::ShowForWebContents( + content::WebContents* web_contents, + base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback) { + constrained_window::ShowWebModalDialogViews( + new DeepScanningFailureModalDialog(std::move(accept_callback), + std::move(cancel_callback), + std::move(open_now_callback)), + web_contents); +} + +DeepScanningFailureModalDialog::DeepScanningFailureModalDialog( + base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback) + : accept_callback_(std::move(accept_callback)), + cancel_callback_(std::move(cancel_callback)), + open_now_callback_(std::move(open_now_callback)) { + DialogDelegate::set_button_label( + ui::DIALOG_BUTTON_OK, + l10n_util::GetStringUTF16( + IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_ACCEPT_BUTTON)); + DialogDelegate::set_button_label( + ui::DIALOG_BUTTON_CANCEL, + l10n_util::GetStringUTF16( + IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_CANCEL_BUTTON)); + auto open_now_button = views::MdTextButton::CreateSecondaryUiButton( + this, + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_OPEN_NOW_BUTTON)); + open_now_button_ = DialogDelegate::SetExtraView(std::move(open_now_button)); + + set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType( + views::TEXT, views::TEXT)); + views::GridLayout* layout = + SetLayoutManager(std::make_unique<views::GridLayout>()); + + // Use a fixed maximum message width, so longer messages will wrap. + const int kMaxMessageWidth = 400; + views::ColumnSet* cs = layout->AddColumnSet(0); + cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::FIXED, + kMaxMessageWidth, false); + + // Add the message label. + auto label = std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_MESSAGE), + views::style::CONTEXT_MESSAGE_BOX_BODY_TEXT, + views::style::STYLE_SECONDARY); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + label->SetMultiLine(true); + label->SizeToFit(kMaxMessageWidth); + layout->StartRow(views::GridLayout::kFixedSize, 0); + layout->AddView(std::move(label)); +} + +DeepScanningFailureModalDialog::~DeepScanningFailureModalDialog() = default; + +bool DeepScanningFailureModalDialog::IsDialogButtonEnabled( + ui::DialogButton button) const { + return (button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL); +} + +bool DeepScanningFailureModalDialog::Accept() { + std::move(accept_callback_).Run(); + return true; +} + +bool DeepScanningFailureModalDialog::Cancel() { + std::move(cancel_callback_).Run(); + return true; +} + +bool DeepScanningFailureModalDialog::ShouldShowCloseButton() const { + return false; +} + +base::string16 DeepScanningFailureModalDialog::GetWindowTitle() const { + return l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_TIMED_OUT_DIALOG_TITLE); +} + +ui::ModalType DeepScanningFailureModalDialog::GetModalType() const { + return ui::MODAL_TYPE_CHILD; +} + +void DeepScanningFailureModalDialog::ButtonPressed(views::Button* sender, + const ui::Event& event) { + if (sender == open_now_button_) { + std::move(open_now_callback_).Run(); + CancelDialog(); + } +} + +} // namespace safe_browsing
diff --git a/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.h b/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.h new file mode 100644 index 0000000..264daeb --- /dev/null +++ b/chrome/browser/ui/views/safe_browsing/deep_scanning_failure_modal_dialog.h
@@ -0,0 +1,69 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_DEEP_SCANNING_FAILURE_MODAL_DIALOG_H_ +#define CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_DEEP_SCANNING_FAILURE_MODAL_DIALOG_H_ + +#include "base/callback.h" +#include "base/callback_forward.h" +#include "base/timer/timer.h" +#include "ui/base/ui_base_types.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/window/dialog_delegate.h" + +namespace content { +class WebContents; +} + +namespace safe_browsing { + +// A tab modal dialog that provides more information to the user about the +// prompt for deep scanning. +class DeepScanningFailureModalDialog : public views::DialogDelegateView, + public views::ButtonListener { + public: + // Show this dialog for the given |web_contents|. + static void ShowForWebContents(content::WebContents* web_contents, + base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback); + + // Create a DeepScanningFailureModalDialog attached to |web_contents|. The + // dialog will call |accept_callback| if the user accepts the prompt. + DeepScanningFailureModalDialog(base::OnceClosure accept_callback, + base::OnceClosure cancel_callback, + base::OnceClosure open_now_callback); + DeepScanningFailureModalDialog(const DeepScanningFailureModalDialog&) = + delete; + DeepScanningFailureModalDialog& operator=( + const DeepScanningFailureModalDialog&) = delete; + ~DeepScanningFailureModalDialog() override; + + // views::DialogDelegate implementation: + bool IsDialogButtonEnabled(ui::DialogButton button) const override; + bool Cancel() override; + bool Accept() override; + bool ShouldShowCloseButton() const override; + + // views::WidgetDelegate implementation: + base::string16 GetWindowTitle() const override; + ui::ModalType GetModalType() const override; + + // views::ButtonListener implementation: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + private: + // The open now button for this dialog. The pointer is unowned, but this is a + // child View of this dialog's View, so it has the same lifetime. + views::Button* open_now_button_; + + // The callbacks to trigger on each way the dialog is resolved. + base::OnceClosure accept_callback_; + base::OnceClosure cancel_callback_; + base::OnceClosure open_now_callback_; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_DEEP_SCANNING_FAILURE_MODAL_DIALOG_H_
diff --git a/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc new file mode 100644 index 0000000..35ff2329 --- /dev/null +++ b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.cc
@@ -0,0 +1,107 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.h" + +#include <memory> + +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/grit/generated_resources.h" +#include "components/constrained_window/constrained_window_views.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/ui_base_types.h" +#include "ui/views/controls/button/md_text_button.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/window/dialog_delegate.h" + +namespace safe_browsing { + +/*static*/ +void PromptForScanningModalDialog::ShowForWebContents( + content::WebContents* web_contents, + base::OnceClosure accept_callback, + base::OnceClosure open_now_callback) { + constrained_window::ShowWebModalDialogViews( + new PromptForScanningModalDialog(std::move(accept_callback), + std::move(open_now_callback)), + web_contents); +} + +PromptForScanningModalDialog::PromptForScanningModalDialog( + base::OnceClosure accept_callback, + base::OnceClosure open_now_callback) + : accept_callback_(std::move(accept_callback)), + open_now_callback_(std::move(open_now_callback)) { + DialogDelegate::set_button_label( + ui::DIALOG_BUTTON_OK, + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_ACCEPT_BUTTON)); + DialogDelegate::set_button_label( + ui::DIALOG_BUTTON_CANCEL, + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_CANCEL_BUTTON)); + auto open_now_button = views::MdTextButton::CreateSecondaryUiButton( + this, + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_OPEN_NOW_BUTTON)); + open_now_button_ = DialogDelegate::SetExtraView(std::move(open_now_button)); + + set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType( + views::TEXT, views::TEXT)); + views::GridLayout* layout = + SetLayoutManager(std::make_unique<views::GridLayout>()); + + // Use a fixed maximum message width, so longer messages will wrap. + const int kMaxMessageWidth = 400; + views::ColumnSet* cs = layout->AddColumnSet(0); + cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + views::GridLayout::kFixedSize, views::GridLayout::FIXED, + kMaxMessageWidth, false); + + // Add the message label. + auto label = std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_MESSAGE), + views::style::CONTEXT_MESSAGE_BOX_BODY_TEXT, + views::style::STYLE_SECONDARY); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + label->SetMultiLine(true); + label->SizeToFit(kMaxMessageWidth); + layout->StartRow(views::GridLayout::kFixedSize, 0); + layout->AddView(std::move(label)); +} + +PromptForScanningModalDialog::~PromptForScanningModalDialog() = default; + +bool PromptForScanningModalDialog::IsDialogButtonEnabled( + ui::DialogButton button) const { + return (button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL); +} + +bool PromptForScanningModalDialog::Accept() { + std::move(accept_callback_).Run(); + return true; +} + +bool PromptForScanningModalDialog::Cancel() { + return true; +} + +bool PromptForScanningModalDialog::ShouldShowCloseButton() const { + return false; +} + +base::string16 PromptForScanningModalDialog::GetWindowTitle() const { + return l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_INFO_DIALOG_TITLE); +} + +ui::ModalType PromptForScanningModalDialog::GetModalType() const { + return ui::MODAL_TYPE_CHILD; +} + +void PromptForScanningModalDialog::ButtonPressed(views::Button* sender, + const ui::Event& event) { + if (sender == open_now_button_) { + std::move(open_now_callback_).Run(); + CancelDialog(); + } +} + +} // namespace safe_browsing
diff --git a/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.h b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.h new file mode 100644 index 0000000..5f0c1126 --- /dev/null +++ b/chrome/browser/ui/views/safe_browsing/prompt_for_scanning_modal_dialog.h
@@ -0,0 +1,65 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_PROMPT_FOR_SCANNING_MODAL_DIALOG_H_ +#define CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_PROMPT_FOR_SCANNING_MODAL_DIALOG_H_ + +#include "base/callback.h" +#include "base/callback_forward.h" +#include "base/timer/timer.h" +#include "ui/base/ui_base_types.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/window/dialog_delegate.h" + +namespace content { +class WebContents; +} + +namespace safe_browsing { + +// A tab modal dialog that provides more information to the user about the +// prompt for deep scanning. +class PromptForScanningModalDialog : public views::DialogDelegateView, + public views::ButtonListener { + public: + // Show this dialog for the given |web_contents|. + static void ShowForWebContents(content::WebContents* web_contents, + base::OnceClosure accept_callback, + base::OnceClosure open_now_callback); + + // Create a PromptForScanningModalDialog attached to |web_contents|. The + // dialog will call |accept_callback| if the user accepts the prompt. + PromptForScanningModalDialog(base::OnceClosure accept_callback, + base::OnceClosure open_now_callback); + PromptForScanningModalDialog(const PromptForScanningModalDialog&) = delete; + PromptForScanningModalDialog& operator=(const PromptForScanningModalDialog&) = + delete; + ~PromptForScanningModalDialog() override; + + // views::DialogDelegate implementation: + bool IsDialogButtonEnabled(ui::DialogButton button) const override; + bool Cancel() override; + bool Accept() override; + bool ShouldShowCloseButton() const override; + + // views::WidgetDelegate implementation: + base::string16 GetWindowTitle() const override; + ui::ModalType GetModalType() const override; + + // views::ButtonListener implementation: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + private: + // The open now button for this dialog. The pointer is unowned, but this is a + // child View of this dialog's View, so it has the same lifetime. + views::Button* open_now_button_; + + // The callbacks to trigger on each way the dialog is resolved. + base::OnceClosure accept_callback_; + base::OnceClosure open_now_callback_; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_UI_VIEWS_SAFE_BROWSING_PROMPT_FOR_SCANNING_MODAL_DIALOG_H_
diff --git a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc index 4909436f..bc5dac97 100644 --- a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc +++ b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/common/web_application_info.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,9 +65,10 @@ apps::mojom::AppLaunchSource::kSourceTest)); DCHECK(web_contents); - WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents); + WebAppTabHelperBase* tab_helper = + WebAppTabHelperBase::FromWebContents(web_contents); DCHECK(tab_helper); - EXPECT_EQ(app_id, tab_helper->app_id()); + EXPECT_EQ(app_id, tab_helper->GetAppId()); Browser* browser = chrome::FindBrowserWithWebContents(web_contents); EXPECT_EQ(browser, chrome::FindLastActive());
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc index 5800bb5..6d66d8d2 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -16,11 +16,11 @@ #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_install_utils.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "chrome/browser/web_launch/web_launch_files_helper.h" #include "content/public/browser/render_view_host.h" #include "extensions/common/constants.h" @@ -65,7 +65,8 @@ // TODO(https://crbug.com/1032443): // Eventually move this to browser_navigator.cc: CreateTargetContents(). - WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents); + WebAppTabHelperBase* tab_helper = + WebAppTabHelperBase::FromWebContents(web_contents); DCHECK(tab_helper); tab_helper->SetAppId(app_id);
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.cc b/chrome/browser/ui/web_applications/web_app_metrics.cc index 4708127..d730037c 100644 --- a/chrome/browser/ui/web_applications/web_app_metrics.cc +++ b/chrome/browser/ui/web_applications/web_app_metrics.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/web_applications/web_app_metrics_factory.h" #include "chrome/browser/web_applications/components/app_registrar.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "content/public/browser/web_contents.h" @@ -97,9 +97,10 @@ engagement_type); } - // A presence of WebAppTabHelper with valid app_id indicates a web app. - WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents); - if (!tab_helper || tab_helper->app_id().empty()) + // A presence of WebAppTabHelperBase with valid app_id indicates a web app. + WebAppTabHelperBase* tab_helper = + WebAppTabHelperBase::FromWebContents(web_contents); + if (!tab_helper || tab_helper->GetAppId().empty()) return; // No HostedAppBrowserController if app is running as a tab in common browser.
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/OWNERS b/chrome/browser/ui/webui/chromeos/crostini_installer/OWNERS index 08850f4..3a2b81f 100644 --- a/chrome/browser/ui/webui/chromeos/crostini_installer/OWNERS +++ b/chrome/browser/ui/webui/chromeos/crostini_installer/OWNERS
@@ -1,2 +1,6 @@ +file://chrome/browser/chromeos/guest_os/OWNERS + per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS + +# COMPONENT: UI>Shell>Containers
diff --git a/chrome/browser/ui/webui/chromeos/crostini_upgrader/OWNERS b/chrome/browser/ui/webui/chromeos/crostini_upgrader/OWNERS index 08850f4..3a2b81f 100644 --- a/chrome/browser/ui/webui/chromeos/crostini_upgrader/OWNERS +++ b/chrome/browser/ui/webui/chromeos/crostini_upgrader/OWNERS
@@ -1,2 +1,6 @@ +file://chrome/browser/chromeos/guest_os/OWNERS + per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS + +# COMPONENT: UI>Shell>Containers
diff --git a/chrome/browser/ui/webui/downloads/OWNERS b/chrome/browser/ui/webui/downloads/OWNERS index 23fd391..81029b1 100644 --- a/chrome/browser/ui/webui/downloads/OWNERS +++ b/chrome/browser/ui/webui/downloads/OWNERS
@@ -1,7 +1,5 @@ file://components/download/OWNERS -dbeam@chromium.org - per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 6f07a92..d6c3c149 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -9,6 +9,26 @@ group("web_app_test_group") { } +# Implementations that are common to both BMO/Extensions backends. +# TODO(alancutter): Migrate sources from :web_applications into here where +# possible. +# TODO(https://crbug.com/877898): Merge this into :web_applications once all +# Extension codepaths have been removed. +source_set("common") { + sources = [ + "web_app_tab_helper.cc", + "web_app_tab_helper.h", + ] + + deps = [ + ":web_app_group", + "//chrome/browser/web_applications/components", + "//chrome/common", + "//content/public/browser", + "//skia", + ] +} + source_set("web_applications") { sources = [ "external_web_app_manager.cc", @@ -51,6 +71,7 @@ ] deps = [ + ":common", ":web_app_group", "//chrome/browser/web_applications/components", "//chrome/common",
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index bf276534..a571dba 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -57,8 +57,8 @@ "web_app_provider_base_factory.h", "web_app_shortcut.cc", "web_app_shortcut.h", - "web_app_tab_helper.cc", - "web_app_tab_helper.h", + "web_app_tab_helper_base.cc", + "web_app_tab_helper_base.h", "web_app_ui_manager.h", "web_app_url_loader.cc", "web_app_url_loader.h",
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.cc b/chrome/browser/web_applications/components/app_shortcut_manager.cc index 71c8f53..442ada3 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.cc +++ b/chrome/browser/web_applications/components/app_shortcut_manager.cc
@@ -39,6 +39,16 @@ observers_.RemoveObserver(observer); } +void AppShortcutManager::OnWebAppWillBeUninstalled(const AppId& app_id) { + std::unique_ptr<ShortcutInfo> shortcut_info = BuildShortcutInfo(app_id); + base::FilePath shortcut_data_dir = + internals::GetShortcutDataDir(*shortcut_info); + + internals::PostShortcutIOTask( + base::BindOnce(&internals::DeletePlatformShortcuts, shortcut_data_dir), + std::move(shortcut_info)); +} + bool AppShortcutManager::CanCreateShortcuts() const { #if defined(OS_CHROMEOS) return false;
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.h b/chrome/browser/web_applications/components/app_shortcut_manager.h index e4f041e..a8f42edc 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.h +++ b/chrome/browser/web_applications/components/app_shortcut_manager.h
@@ -44,6 +44,9 @@ void AddObserver(AppShortcutObserver* observer); void RemoveObserver(AppShortcutObserver* observer); + // AppRegistrarObserver: + void OnWebAppWillBeUninstalled(const AppId& app_id) override; + // Tells the AppShortcutManager that no shortcuts should actually be written // to the disk. void SuppressShortcutsForTesting(); @@ -55,6 +58,10 @@ bool add_to_desktop, CreateShortcutsCallback callback); + // Builds initial ShortcutInfo without |ShortcutInfo::favicon| being read. + virtual std::unique_ptr<ShortcutInfo> BuildShortcutInfo( + const AppId& app_id) = 0; + // The result of a call to GetShortcutInfo. using GetShortcutInfoCallback = base::OnceCallback<void(std::unique_ptr<ShortcutInfo>)>;
diff --git a/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc index 68d291e..1ec4d7d 100644 --- a/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc +++ b/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/web_applications/components/pending_app_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/web_applications/components/web_app_file_handler_registration_linux.cc b/chrome/browser/web_applications/components/web_app_file_handler_registration_linux.cc index 7aef4c2..828b5de00 100644 --- a/chrome/browser/web_applications/components/web_app_file_handler_registration_linux.cc +++ b/chrome/browser/web_applications/components/web_app_file_handler_registration_linux.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/app_shortcut_manager.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/components/web_app_shortcut.h" @@ -26,6 +27,16 @@ base::DoNothing()); } +void UpdateFileHandlerRegistrationInOs(const AppId& app_id, Profile* profile) { + // On Linux, file associations are managed through shortcuts in the app menu, + // so after enabling or disabling file handling for an app its shortcuts + // need to be recreated. + AppShortcutManager& shortcut_manager = + WebAppProviderBase::GetProviderBase(profile)->shortcut_manager(); + shortcut_manager.GetShortcutInfoForApp( + app_id, base::BindOnce(&OnShortcutInfoReceived)); +} + } // namespace bool ShouldRegisterFileHandlersWithOs() { @@ -37,14 +48,18 @@ Profile* profile, const std::set<std::string>& file_extensions, const std::set<std::string>& mime_types) { - AppShortcutManager& shortcut_manager = - WebAppProviderBase::GetProviderBase(profile)->shortcut_manager(); - shortcut_manager.GetShortcutInfoForApp( - app_id, base::BindOnce(OnShortcutInfoReceived)); + UpdateFileHandlerRegistrationInOs(app_id, profile); } void UnregisterFileHandlersWithOs(const AppId& app_id, Profile* profile) { - // TODO(harrisjay): Add support for unregistering file handlers. + // If this was triggered as part of the uninstallation process, nothing more + // is needed. Uninstalling already cleans up shortcuts (and thus, file + // handlers). + auto* provider = WebAppProviderBase::GetProviderBase(profile); + if (!provider->registrar().IsInstalled(app_id)) + return; + + UpdateFileHandlerRegistrationInOs(app_id, profile); } } // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc new file mode 100644 index 0000000..c2ce7ca --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
@@ -0,0 +1,11 @@ +// Copyright 2019 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/web_applications/components/web_app_tab_helper_base.h" + +namespace web_app { + +WEB_CONTENTS_USER_DATA_KEY_IMPL(WebAppTabHelperBase) + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.h b/chrome/browser/web_applications/components/web_app_tab_helper_base.h new file mode 100644 index 0000000..a222ffc --- /dev/null +++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_ + +#include "chrome/browser/web_applications/components/web_app_helpers.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace base { +class UnguessableToken; +} + +namespace web_app { + +// Public interface for WebAppTabHelper. +class WebAppTabHelperBase + : public content::WebContentsUserData<WebAppTabHelperBase> { + public: + using content::WebContentsUserData<WebAppTabHelperBase>::FromWebContents; + + virtual const AppId& GetAppId() const = 0; + virtual void SetAppId(const AppId& app_id) = 0; + + // These methods require an app associated with the tab (valid GetAppId()). + + // Returns true if the app was installed by user, false if default installed. + virtual bool IsUserInstalled() const = 0; + // For user-installed apps: + // Returns true if the app was installed through the install button. + // Returns false if the app was installed through the create shortcut button. + virtual bool IsFromInstallButton() const = 0; + + virtual const base::UnguessableToken& GetAudioFocusGroupIdForTesting() + const = 0; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.cc b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.cc index 8f56264..40fc0a8 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.cc
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/web_app_shortcut.h" +#include "chrome/browser/web_applications/extensions/bookmark_app_registrar.h" #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut.h" #include "extensions/browser/extension_registry.h" @@ -17,6 +18,17 @@ BookmarkAppShortcutManager::~BookmarkAppShortcutManager() = default; +std::unique_ptr<web_app::ShortcutInfo> +BookmarkAppShortcutManager::BuildShortcutInfo(const web_app::AppId& app_id) { + BookmarkAppRegistrar* registry = registrar()->AsBookmarkAppRegistrar(); + DCHECK(registry); + + const Extension* app = registry->FindExtension(app_id); + DCHECK(app); + + return web_app::ShortcutInfoForExtensionAndProfile(app, profile()); +} + void BookmarkAppShortcutManager::GetShortcutInfoForApp( const web_app::AppId& app_id, GetShortcutInfoCallback callback) {
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.h b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.h index a9d8f729..61f0e80 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_manager.h
@@ -17,6 +17,9 @@ explicit BookmarkAppShortcutManager(Profile* profile); ~BookmarkAppShortcutManager() override; + // AppShortcutManager: + std::unique_ptr<web_app::ShortcutInfo> BuildShortcutInfo( + const web_app::AppId& app_id) override; void GetShortcutInfoForApp(const web_app::AppId& app_id, GetShortcutInfoCallback callback) override;
diff --git a/chrome/browser/web_applications/extensions/web_app_audio_focus_browsertest.cc b/chrome/browser/web_applications/extensions/web_app_audio_focus_browsertest.cc index e385695b..85a3f83 100644 --- a/chrome/browser/web_applications/extensions/web_app_audio_focus_browsertest.cc +++ b/chrome/browser/web_applications/extensions/web_app_audio_focus_browsertest.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_service.h" @@ -75,8 +75,9 @@ const base::UnguessableToken& GetAudioFocusGroupId( content::WebContents* web_contents) { - WebAppTabHelper* helper = WebAppTabHelper::FromWebContents(web_contents); - return helper->audio_focus_group_id_; + WebAppTabHelperBase* helper = + WebAppTabHelperBase::FromWebContents(web_contents); + return helper->GetAudioFocusGroupIdForTesting(); } private:
diff --git a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc index 7a09aaa..0a30ec7 100644 --- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc +++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/web_applications/components/file_handler_manager.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" +#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" @@ -178,11 +179,18 @@ shortcut_info->profile_name = profile->GetPrefs()->GetString(prefs::kProfileName); shortcut_info->version_for_display = app->GetVersionForDisplay(); - if (const auto* info = extensions::FileHandlers::GetFileHandlers(app)) { - shortcut_info->file_handler_extensions = - web_app::GetFileExtensionsFromFileHandlers(*info); - shortcut_info->file_handler_mime_types = - web_app::GetMimeTypesFromFileHandlers(*info); + + // File Handlers should only be included in bookmark apps. + if (app->from_bookmark()) { + FileHandlerManager& file_handler_manager = + WebAppProviderBase::GetProviderBase(profile)->file_handler_manager(); + if (const auto* file_handlers = + file_handler_manager.GetEnabledFileHandlers(app->id())) { + shortcut_info->file_handler_extensions = + web_app::GetFileExtensionsFromFileHandlers(*file_handlers); + shortcut_info->file_handler_mime_types = + web_app::GetMimeTypesFromFileHandlers(*file_handlers); + } } return shortcut_info;
diff --git a/chrome/browser/web_applications/test/test_app_shortcut_manager.cc b/chrome/browser/web_applications/test/test_app_shortcut_manager.cc index 02c2430..7b64e91 100644 --- a/chrome/browser/web_applications/test/test_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/test/test_app_shortcut_manager.cc
@@ -44,6 +44,12 @@ std::move(callback), success)); } +std::unique_ptr<ShortcutInfo> TestAppShortcutManager::BuildShortcutInfo( + const AppId& app_id) { + NOTIMPLEMENTED(); + return nullptr; +} + void TestAppShortcutManager::GetShortcutInfoForApp( const AppId& app_id, GetShortcutInfoCallback callback) {
diff --git a/chrome/browser/web_applications/test/test_app_shortcut_manager.h b/chrome/browser/web_applications/test/test_app_shortcut_manager.h index b74c726..5168b65 100644 --- a/chrome/browser/web_applications/test/test_app_shortcut_manager.h +++ b/chrome/browser/web_applications/test/test_app_shortcut_manager.h
@@ -40,6 +40,7 @@ void CreateShortcuts(const AppId& app_id, bool on_desktop, CreateShortcutsCallback callback) override; + std::unique_ptr<ShortcutInfo> BuildShortcutInfo(const AppId& app_id) override; void GetShortcutInfoForApp(const AppId& app_id, GetShortcutInfoCallback callback) override;
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.cc b/chrome/browser/web_applications/web_app_shortcut_manager.cc index c56e83a..0eab5ab 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/web_app_shortcut_manager.cc
@@ -36,17 +36,11 @@ WebAppShortcutManager::~WebAppShortcutManager() = default; -void WebAppShortcutManager::OnWebAppWillBeUninstalled(const AppId& app_id) { +std::unique_ptr<ShortcutInfo> WebAppShortcutManager::BuildShortcutInfo( + const AppId& app_id) { const WebApp* app = GetWebAppRegistrar().GetAppById(app_id); DCHECK(app); - - std::unique_ptr<ShortcutInfo> shortcut_info = BuildShortcutInfoForWebApp(app); - base::FilePath shortcut_data_dir = - internals::GetShortcutDataDir(*shortcut_info); - - internals::PostShortcutIOTask( - base::BindOnce(&internals::DeletePlatformShortcuts, shortcut_data_dir), - std::move(shortcut_info)); + return BuildShortcutInfoForWebApp(app); } void WebAppShortcutManager::GetShortcutInfoForApp(
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.h b/chrome/browser/web_applications/web_app_shortcut_manager.h index bc9cd85b..dc0686e0 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.h +++ b/chrome/browser/web_applications/web_app_shortcut_manager.h
@@ -32,10 +32,8 @@ FileHandlerManager* file_handler_manager); ~WebAppShortcutManager() override; - // AppRegistrarObserver: - void OnWebAppWillBeUninstalled(const AppId& app_id) override; - // AppShortcutManager: + std::unique_ptr<ShortcutInfo> BuildShortcutInfo(const AppId& app_id) override; void GetShortcutInfoForApp(const AppId& app_id, GetShortcutInfoCallback callback) override;
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc similarity index 87% rename from chrome/browser/web_applications/components/web_app_tab_helper.cc rename to chrome/browser/web_applications/web_app_tab_helper.cc index f0497639..31da9345 100644 --- a/chrome/browser/web_applications/components/web_app_tab_helper.cc +++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/web_applications/components/web_app_tab_helper.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "base/unguessable_token.h" #include "chrome/browser/profiles/profile.h" @@ -17,7 +17,13 @@ namespace web_app { -WEB_CONTENTS_USER_DATA_KEY_IMPL(WebAppTabHelper) +void WebAppTabHelper::CreateForWebContents(content::WebContents* contents) { + DCHECK(contents); + if (!FromWebContents(contents)) { + contents->SetUserData(UserDataKey(), + std::make_unique<WebAppTabHelper>(contents)); + } +} WebAppTabHelper::WebAppTabHelper(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), @@ -31,6 +37,26 @@ WebAppTabHelper::~WebAppTabHelper() = default; +const AppId& WebAppTabHelper::GetAppId() const { + return app_id_; +} + +bool WebAppTabHelper::IsUserInstalled() const { + return !app_id_.empty() && provider_->registrar().WasInstalledByUser(app_id_); +} + +bool WebAppTabHelper::IsFromInstallButton() const { + // TODO(loyso): Use something better to record apps installed from promoted + // UIs. crbug.com/774918. + return !app_id_.empty() && + provider_->registrar().GetAppScope(app_id_).has_value(); +} + +const base::UnguessableToken& WebAppTabHelper::GetAudioFocusGroupIdForTesting() + const { + return audio_focus_group_id_; +} + void WebAppTabHelper::SetAppId(const AppId& app_id) { DCHECK(app_id.empty() || provider_->registrar().IsInstalled(app_id)); if (app_id_ == app_id) @@ -64,18 +90,7 @@ auto* new_tab_helper = FromWebContents(new_web_contents); // Clone common state: - new_tab_helper->SetAppId(app_id()); -} - -bool WebAppTabHelper::IsUserInstalled() const { - return !app_id_.empty() && provider_->registrar().WasInstalledByUser(app_id_); -} - -bool WebAppTabHelper::IsFromInstallButton() const { - // TODO(loyso): Use something better to record apps installed from promoted - // UIs. crbug.com/774918. - return !app_id_.empty() && - provider_->registrar().GetAppScope(app_id_).has_value(); + new_tab_helper->SetAppId(GetAppId()); } bool WebAppTabHelper::IsInAppWindow() const { @@ -90,7 +105,7 @@ } void WebAppTabHelper::OnWebAppUninstalled(const AppId& uninstalled_app_id) { - if (app_id() == uninstalled_app_id) + if (GetAppId() == uninstalled_app_id) ResetAppId(); }
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper.h b/chrome/browser/web_applications/web_app_tab_helper.h similarity index 69% rename from chrome/browser/web_applications/components/web_app_tab_helper.h rename to chrome/browser/web_applications/web_app_tab_helper.h index ed53d7c..02be6cae 100644 --- a/chrome/browser/web_applications/components/web_app_tab_helper.h +++ b/chrome/browser/web_applications/web_app_tab_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_H_ -#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_H_ +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_ #include "base/macros.h" #include "base/scoped_observer.h" @@ -11,8 +11,8 @@ #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/app_registrar_observer.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" +#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" namespace content { class WebContents; @@ -24,20 +24,21 @@ // Per-tab web app helper. Allows to associate a tab (web page) with a web app // (or legacy bookmark app). -class WebAppTabHelper : public content::WebContentsObserver, - public content::WebContentsUserData<WebAppTabHelper>, +class WebAppTabHelper : public WebAppTabHelperBase, + public content::WebContentsObserver, public AppRegistrarObserver { public: - using content::WebContentsUserData<WebAppTabHelper>::CreateForWebContents; - using content::WebContentsUserData<WebAppTabHelper>::FromWebContents; + static void CreateForWebContents(content::WebContents* contents); explicit WebAppTabHelper(content::WebContents* web_contents); ~WebAppTabHelper() override; - const AppId& app_id() const { return app_id_; } - - // Set associated app_id. - void SetAppId(const AppId& app_id); + // WebAppTabHelperBase: + const AppId& GetAppId() const override; + void SetAppId(const AppId& app_id) override; + bool IsUserInstalled() const override; + bool IsFromInstallButton() const override; + const base::UnguessableToken& GetAudioFocusGroupIdForTesting() const override; // content::WebContentsObserver: void DidFinishNavigation( @@ -46,18 +47,7 @@ content::WebContents* old_web_contents, content::WebContents* new_web_contents) override; - // These methods require an app associated with the tab (valid app_id()). - // - // Returns true if the app was installed by user, false if default installed. - bool IsUserInstalled() const; - // For user-installed apps: - // Returns true if the app was installed through the install button. - // Returns false if the app was installed through the create shortcut button. - bool IsFromInstallButton() const; - private: - WEB_CONTENTS_USER_DATA_KEY_DECL(); - friend class WebAppAudioFocusBrowserTest; friend class content::WebContentsUserData<WebAppTabHelper>; @@ -98,4 +88,4 @@ } // namespace web_app -#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_H_ +#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 72633ec..6f0d2be 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc
@@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/common/extensions/extension_constants.h" + #include "base/macros.h" #include "build/build_config.h" -#include "chrome/common/extensions/extension_constants.h" +#include "extensions/common/constants.h" namespace extension_urls { @@ -77,6 +79,7 @@ kAutoclickExtensionId, kSelectToSpeakExtensionId, kSwitchAccessExtensionId, + kFilesManagerAppId, kFirstRunDialogId, kEspeakSpeechSynthesisExtensionId, kGoogleSpeechSynthesisExtensionId,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 37fe96b8..beb85488 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1500,6 +1500,7 @@ "../browser/policy/accessibility_policy_browsertest.cc", "../browser/policy/arc_policy_browsertest.cc", "../browser/policy/assistant_policy_browsertest.cc", + "../browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc", ] }
diff --git a/chrome/test/base/in_process_browser_test_browsertest.cc b/chrome/test/base/in_process_browser_test_browsertest.cc index c8f712a..cb2ed68 100644 --- a/chrome/test/base/in_process_browser_test_browsertest.cc +++ b/chrome/test/base/in_process_browser_test_browsertest.cc
@@ -21,6 +21,7 @@ #include "content/public/common/content_switches.h" #include "net/base/filename_util.h" #include "net/base/net_errors.h" +#include "net/dns/public/resolve_error_info.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -44,7 +45,8 @@ explicit LoadFailObserver(content::WebContents* contents) : content::WebContentsObserver(contents), failed_load_(false), - error_code_(net::OK) { } + error_code_(net::OK), + resolve_error_info_(net::ResolveErrorInfo(net::OK)) {} void DidFinishNavigation( content::NavigationHandle* navigation_handle) override { @@ -53,16 +55,21 @@ failed_load_ = true; error_code_ = navigation_handle->GetNetErrorCode(); + resolve_error_info_ = navigation_handle->GetResolveErrorInfo(); validated_url_ = navigation_handle->GetURL(); } bool failed_load() const { return failed_load_; } net::Error error_code() const { return error_code_; } + net::ResolveErrorInfo resolve_error_info() const { + return resolve_error_info_; + } const GURL& validated_url() const { return validated_url_; } private: bool failed_load_; net::Error error_code_; + net::ResolveErrorInfo resolve_error_info_; GURL validated_url_; DISALLOW_COPY_AND_ASSIGN(LoadFailObserver); @@ -85,6 +92,7 @@ ui_test_utils::NavigateToURL(browser(), url); EXPECT_TRUE(observer.failed_load()); EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, observer.error_code()); + EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, observer.resolve_error_info().error); EXPECT_EQ(url, observer.validated_url()); } }
diff --git a/chrome/test/data/local_ntp/local_ntp_browsertest.html b/chrome/test/data/local_ntp/local_ntp_browsertest.html index 610bff72..d8a1fb6 100644 --- a/chrome/test/data/local_ntp/local_ntp_browsertest.html +++ b/chrome/test/data/local_ntp/local_ntp_browsertest.html
@@ -70,7 +70,8 @@ <div id="realbox-container"> <div id="realbox-input-wrapper"> - <div id="realbox-icon" class="search-icon"></div> + <div id="realbox-icon" class="search-icon" + data-realbox-icon-class="search-icon"></div> <input id="realbox" type="search" autocomplete="off" spellcheck="false" autofocus> <button id="realbox-microphone" class="microphone-icon" hidden>
diff --git a/chrome/test/data/local_ntp/realbox_browsertest.js b/chrome/test/data/local_ntp/realbox_browsertest.js index 2e25b831..f2bd877 100644 --- a/chrome/test/data/local_ntp/realbox_browsertest.js +++ b/chrome/test/data/local_ntp/realbox_browsertest.js
@@ -27,6 +27,7 @@ * @const */ test.realbox.CLASSES = { + CLOCK_ICON: 'clock-icon', HAS_IMAGE: 'has-image', IMAGE_CONTAINER: 'image-container', MATCH_IMAGE: 'match-image', @@ -1261,13 +1262,14 @@ matches: [ test.realbox.getUrlMatch({allowedToBeDefaultMatch: true}), test.realbox.getSearchMatch(), + test.realbox.getSearchMatch({type: 'search-history'}), ], }); assertTrue(test.realbox.areMatchesShowing()); // First URL match should be showing and the favicon should be in the realbox. const matchEls = $(test.realbox.IDS.REALBOX_MATCHES).children; - assertEquals(2, matchEls.length); + assertEquals(3, matchEls.length); assertTrue(matchEls[0].classList.contains(test.realbox.CLASSES.SELECTED)); assertTrue(!!realboxIcon.style.backgroundImage); @@ -1283,6 +1285,12 @@ assertTrue(matchEls[1].classList.contains(test.realbox.CLASSES.SELECTED)); assertFalse(!!realboxIcon.style.backgroundImage); + test.realbox.realboxEl.dispatchEvent(arrowDown); + + // Third search match should change to clock icon. + assertTrue(matchEls[2].classList.contains(test.realbox.CLASSES.SELECTED)); + assertEquals(realboxIcon.className, test.realbox.CLASSES.CLOCK_ICON); + const escapeToDefaultMatch = new KeyboardEvent('keydown', { bubbles: true, cancelable: true,
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index bff07dc7..93bad1ff 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -35,7 +35,6 @@ "//chrome/browser/ui", ] data = [ - "$root_gen_dir/chrome/test/data/webui/cr_focus_row_behavior_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_action_menu_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_checkbox_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.m.js", @@ -44,8 +43,9 @@ "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_tabs_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toggle_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/iron_list_focus_test.m.js", - "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_focus_row_behavior_test.m.js", "$root_gen_dir/chrome/test/data/webui/mock_controller.m.js", + "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/test_store.m.js", "$root_gen_dir/chrome/test/data/webui/test_util.m.js", ] @@ -185,12 +185,14 @@ "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_icon_button_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_lazy_render_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_link_row_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_button_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_group_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_search_field_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_slider_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_manager_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_view_manager_test.m.js", "$root_gen_dir/chrome/test/data/webui/fake_chrome_event.m.js",
diff --git a/chrome/test/data/webui/settings/certificate_manager_test.js b/chrome/test/data/webui/cr_components/certificate_manager_test.js similarity index 99% rename from chrome/test/data/webui/settings/certificate_manager_test.js rename to chrome/test/data/webui/cr_components/certificate_manager_test.js index 6b982671..935cf64 100644 --- a/chrome/test/data/webui/settings/certificate_manager_test.js +++ b/chrome/test/data/webui/cr_components/certificate_manager_test.js
@@ -888,7 +888,6 @@ }); }); } - }); suite('CertificateListTests', function() {
diff --git a/chrome/test/data/webui/cr_components/cr_components_browsertest.js b/chrome/test/data/webui/cr_components/cr_components_browsertest.js index b9d47ec..f0c046c 100644 --- a/chrome/test/data/webui/cr_components/cr_components_browsertest.js +++ b/chrome/test/data/webui/cr_components/cr_components_browsertest.js
@@ -96,3 +96,39 @@ }); GEN('#endif'); + +GEN('#if defined(USE_NSS_CERTS)'); + +/** + * Test fixture for chrome://settings/certificates. This tests the + * certificate-manager component in the context of the Settings privacy page. + * @constructor + * @extends {CrComponentsBrowserTest} + */ +function CrComponentsCertificateManagerTest() {} + +CrComponentsCertificateManagerTest.prototype = { + __proto__: CrComponentsBrowserTest.prototype, + + /** + * Using the certificate-manager instance within + * chrome://settings/privacy_page for these tests, so that all strings are + * properly defined. + * @override + */ + browsePreload: 'chrome://settings/privacy_page/privacy_page.html', + + /** @override */ + extraLibraries: CrComponentsBrowserTest.prototype.extraLibraries.concat([ + '../test_util.js', + '../test_browser_proxy.js', + '../settings/ensure_lazy_loaded.js', + 'certificate_manager_test.js', + ]), +}; + +TEST_F('CrComponentsCertificateManagerTest', 'All', function() { + mocha.run(); +}); + +GEN('#endif // defined(USE_NSS_CERTS)');
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn index 9e1dfa52..ab0180d 100644 --- a/chrome/test/data/webui/cr_elements/BUILD.gn +++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -19,6 +19,8 @@ "cr_input_test.js", "cr_lazy_render_tests.js", "cr_link_row_tests.js", + "cr_policy_indicator_tests.js", + "cr_policy_indicator_behavior_tests.js", "cr_radio_button_test.js", "cr_radio_group_test.js", "cr_search_field_tests.js",
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js index 9771c9d..260e1c6 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_v3_browsertest.js
@@ -255,3 +255,28 @@ TEST_F('CrElementsViewManagerV3Test', 'All', function() { mocha.run(); }); + +// eslint-disable-next-line no-var +var CrElementsPolicyIndicatorV3Test = class extends CrElementsV3BrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://test?module=cr_elements/cr_policy_indicator_tests.m.js'; + } +}; + +TEST_F('CrElementsPolicyIndicatorV3Test', 'All', function() { + mocha.run(); +}); + +// eslint-disable-next-line no-var +var CrElementsPolicyIndicatorBehaviorV3Test = + class extends CrElementsV3BrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://test?module=cr_elements/cr_policy_indicator_behavior_tests.m.js'; + } +}; + +TEST_F('CrElementsPolicyIndicatorBehaviorV3Test', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js b/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js index 1689b4e..25ffe8f 100644 --- a/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js +++ b/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js
@@ -3,6 +3,14 @@ // found in the LICENSE file. /** @fileoverview Suite of tests for CrPolicyIndicatorBehavior. */ + +// clang-format off +// #import {CrPolicyIndicatorBehavior, CrPolicyIndicatorType} from 'chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.m.js'; +// #import {Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {isChromeOS} from 'chrome://resources/js/cr.m.js'; +// #import 'chrome://test/cr_elements/cr_policy_strings.js'; +// clang-format on + suite('CrPolicyIndicatorBehavior', function() { suiteSetup(function() { Polymer({
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.js b/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.js index a3f2323..46e3655 100644 --- a/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.js +++ b/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.js
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {CrPolicyIndicatorType} from 'chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.m.js'; +// #import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js'; +// #import {isChromeOS} from 'chrome://resources/js/cr.m.js'; +// #import 'chrome://test/cr_elements/cr_policy_strings.js'; +// clang-format on + /** @fileoverview Suite of tests for cr-policy-indicator. */ suite('CrPolicyIndicator', function() { /** @type {!CrPolicyIndicatorElement|undefined} */
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_strings.js b/chrome/test/data/webui/cr_elements/cr_policy_strings.js index 7e588ea..50151d82 100644 --- a/chrome/test/data/webui/cr_elements/cr_policy_strings.js +++ b/chrome/test/data/webui/cr_elements/cr_policy_strings.js
@@ -16,3 +16,6 @@ controlledSettingParent: 'parent', controlledSettingChildRestriction: 'Restricted for child', }; + +// Necessary for tests residing within a JS module. +window.CrPolicyStrings = CrPolicyStrings;
diff --git a/chrome/test/data/webui/cr_elements/cr_slider_test.js b/chrome/test/data/webui/cr_elements/cr_slider_test.js index 80da6cc..a4ca150 100644 --- a/chrome/test/data/webui/cr_elements/cr_slider_test.js +++ b/chrome/test/data/webui/cr_elements/cr_slider_test.js
@@ -4,7 +4,7 @@ // clang-format off // #import 'chrome://resources/cr_elements/cr_slider/cr_slider.m.js'; -// #import {Polymer, flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; // #import {flushTasks, eventToPromise} from '../test_util.m.js'; // #import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; // clang-format on @@ -14,7 +14,16 @@ setup(function() { PolymerTest.clearBody(); - document.body.innerHTML = '<cr-slider min="0" max="100"></cr-slider>'; + document.body.innerHTML = ` + <style> + #wrapper { + width: 200px; + } + </style> + <div id="wrapper"> + <cr-slider min="0" max="100"></cr-slider> + </div> + `; crSlider = document.body.querySelector('cr-slider'); crSlider.value = 0;
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 41c59c8..c9c75d1 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -840,40 +840,6 @@ mocha.run(); }); -GEN('#if defined(USE_NSS_CERTS)'); - -/** - * Test fixture for chrome://settings/certificates. This tests the - * certificate-manager component in the context of the Settings privacy page. - * @constructor - * @extends {CrSettingsBrowserTest} - */ -function CrSettingsCertificateManagerTest() {} - -CrSettingsCertificateManagerTest.prototype = { - __proto__: CrSettingsBrowserTest.prototype, - - /** - * The certificate-manager subpage is embedded in privacy_page.html. - * @override - */ - browsePreload: 'chrome://settings/privacy_page/privacy_page.html', - - /** @override */ - extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - '../test_util.js', - '../test_browser_proxy.js', - 'ensure_lazy_loaded.js', - 'certificate_manager_test.js', - ]), -}; - -TEST_F('CrSettingsCertificateManagerTest', 'All', function() { - mocha.run(); -}); - -GEN('#endif // defined(USE_NSS_CERTS)'); - /** * Test fixture for * chrome/browser/resources/settings/privacy_page/personalization_options.html.
diff --git a/chrome/test/data/webui/settings/people_page_test.js b/chrome/test/data/webui/settings/people_page_test.js index fba48d0..b9d7c0dc 100644 --- a/chrome/test/data/webui/settings/people_page_test.js +++ b/chrome/test/data/webui/settings/people_page_test.js
@@ -17,14 +17,14 @@ } } - suite('ProfileInfoTests', function() { - /** @type {SettingsPeoplePageElement} */ - let peoplePage = null; - /** @type {settings.ProfileInfoBrowserProxy} */ - let browserProxy = null; - /** @type {settings.SyncBrowserProxy} */ - let syncBrowserProxy = null; + /** @type {?SettingsPeoplePageElement} */ + let peoplePage = null; + /** @type {?settings.ProfileInfoBrowserProxy} */ + let profileInfoBrowserProxy = null; + /** @type {?settings.SyncBrowserProxy} */ + let syncBrowserProxy = null; + suite('ProfileInfoTests', function() { suiteSetup(function() { loadTimeData.overrideValues({ // Force Dice off. Dice is tested in the DiceUITest suite. @@ -39,8 +39,8 @@ }); setup(async function() { - browserProxy = new TestProfileInfoBrowserProxy(); - settings.ProfileInfoBrowserProxyImpl.instance_ = browserProxy; + profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); + settings.ProfileInfoBrowserProxyImpl.instance_ = profileInfoBrowserProxy; syncBrowserProxy = new TestSyncBrowserProxy(); settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; @@ -51,7 +51,7 @@ document.body.appendChild(peoplePage); await syncBrowserProxy.whenCalled('getSyncStatus'); - await browserProxy.whenCalled('getProfileInfo'); + await profileInfoBrowserProxy.whenCalled('getProfileInfo'); Polymer.dom.flush(); }); @@ -61,10 +61,10 @@ test('GetProfileInfo', function() { assertEquals( - browserProxy.fakeProfileInfo.name, + profileInfoBrowserProxy.fakeProfileInfo.name, peoplePage.$$('#profile-name').textContent.trim()); const bg = peoplePage.$$('#profile-icon').style.backgroundImage; - assertTrue(bg.includes(browserProxy.fakeProfileInfo.iconUrl)); + assertTrue(bg.includes(profileInfoBrowserProxy.fakeProfileInfo.iconUrl)); const iconDataUrl = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEA' + 'LAAAAAABAAEAAAICTAEAOw=='; @@ -81,16 +81,9 @@ if (!cr.isChromeOS) { suite('SyncStatusTests', function() { - /** @type {SettingsPeoplePageElement} */ - let peoplePage = null; - /** @type {settings.SyncBrowserProxy} */ - let browserProxy = null; - /** @type {settings.ProfileInfoBrowserProxy} */ - let profileInfoBrowserProxy = null; - setup(function() { - browserProxy = new TestSyncBrowserProxy(); - settings.SyncBrowserProxyImpl.instance_ = browserProxy; + syncBrowserProxy = new TestSyncBrowserProxy(); + settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); settings.ProfileInfoBrowserProxyImpl.instance_ = @@ -122,7 +115,7 @@ test('GetProfileInfo', function() { let disconnectButton = null; - return browserProxy.whenCalled('getSyncStatus') + return syncBrowserProxy.whenCalled('getSyncStatus') .then(function() { Polymer.dom.flush(); disconnectButton = peoplePage.$$('#disconnectButton'); @@ -154,7 +147,7 @@ return popstatePromise; }) .then(function() { - return browserProxy.whenCalled('signOut'); + return syncBrowserProxy.whenCalled('signOut'); }) .then(function(deleteProfile) { assertFalse(deleteProfile); @@ -182,7 +175,7 @@ assertTrue(!!disconnectManagedProfileConfirm); assertFalse(disconnectManagedProfileConfirm.hidden); - browserProxy.resetResolver('signOut'); + syncBrowserProxy.resetResolver('signOut'); const popstatePromise = new Promise(function(resolve) { listenOnce(window, 'popstate', resolve); @@ -193,7 +186,7 @@ return popstatePromise; }) .then(function() { - return browserProxy.whenCalled('signOut'); + return syncBrowserProxy.whenCalled('signOut'); }) .then(function(deleteProfile) { assertTrue(deleteProfile); @@ -201,7 +194,7 @@ }); test('getProfileStatsCount', function() { - return browserProxy.whenCalled('getSyncStatus') + return syncBrowserProxy.whenCalled('getSyncStatus') .then(function() { Polymer.dom.flush(); @@ -279,7 +272,7 @@ }); test('Signout dialog suppressed when not signed in', function() { - return browserProxy.whenCalled('getSyncStatus') + return syncBrowserProxy.whenCalled('getSyncStatus') .then(function() { settings.Router.getInstance().navigateTo( settings.routes.SIGN_OUT); @@ -315,13 +308,6 @@ }); suite('DiceUITest', function() { - /** @type {SettingsPeoplePageElement} */ - let peoplePage = null; - /** @type {settings.SyncBrowserProxy} */ - let browserProxy = null; - /** @type {settings.ProfileInfoBrowserProxy} */ - let profileInfoBrowserProxy = null; - suiteSetup(function() { // Force UIs to think DICE is enabled for this profile. loadTimeData.overrideValues({ @@ -330,8 +316,8 @@ }); setup(function() { - browserProxy = new TestSyncBrowserProxy(); - settings.SyncBrowserProxyImpl.instance_ = browserProxy; + syncBrowserProxy = new TestSyncBrowserProxy(); + settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); settings.ProfileInfoBrowserProxyImpl.instance_ = @@ -350,7 +336,7 @@ }); test('ShowCorrectRows', function() { - return browserProxy.whenCalled('getSyncStatus').then(function() { + return syncBrowserProxy.whenCalled('getSyncStatus').then(function() { // The correct /manageProfile link row is shown. assertTrue(!!peoplePage.$$('#edit-profile')); assertFalse(!!peoplePage.$$('#picture-subpage-trigger')); @@ -455,16 +441,9 @@ } suite('SyncSettings', function() { - /** @type {SettingsPeoplePageElement} */ - let peoplePage = null; - /** @type {settings.SyncBrowserProxy} */ - let browserProxy = null; - /** @type {settings.ProfileInfoBrowserProxy} */ - let profileInfoBrowserProxy = null; - setup(async function() { - browserProxy = new TestSyncBrowserProxy(); - settings.SyncBrowserProxyImpl.instance_ = browserProxy; + syncBrowserProxy = new TestSyncBrowserProxy(); + settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); settings.ProfileInfoBrowserProxyImpl.instance_ = profileInfoBrowserProxy; @@ -474,7 +453,7 @@ peoplePage.pageVisibility = settings.pageVisibility; document.body.appendChild(peoplePage); - await browserProxy.whenCalled('getSyncStatus'); + await syncBrowserProxy.whenCalled('getSyncStatus'); Polymer.dom.flush(); }); @@ -550,16 +529,22 @@ } } - suite('Chrome OS', function() { - /** @type {SettingsPeoplePageElement} */ - let peoplePage = null; - /** @type {settings.SyncBrowserProxy} */ - let browserProxy = null; - /** @type {settings.ProfileInfoBrowserProxy} */ - let profileInfoBrowserProxy = null; - /** @type {settings.AccountManagerBrowserProxy} */ - let accountManagerBrowserProxy = null; + /** @type {?settings.AccountManagerBrowserProxy} */ + let accountManagerBrowserProxy = null; + // Preferences should exist for embedded 'personalization_options.html'. + // We don't perform tests on them. + const DEFAULT_PREFS = { + profile: {password_manager_leak_detection: {value: true}}, + signin: { + allowed_on_next_startup: + {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true} + }, + safebrowsing: + {enabled: {value: true}, scout_reporting_enabled: {value: true}}, + }; + + suite('Chrome OS', function() { suiteSetup(function() { loadTimeData.overrideValues({ // Simulate SplitSettings (OS settings in their own surface). @@ -570,8 +555,8 @@ }); setup(async function() { - browserProxy = new TestSyncBrowserProxy(); - settings.SyncBrowserProxyImpl.instance_ = browserProxy; + syncBrowserProxy = new TestSyncBrowserProxy(); + settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); settings.ProfileInfoBrowserProxyImpl.instance_ = @@ -583,18 +568,12 @@ PolymerTest.clearBody(); peoplePage = document.createElement('settings-people-page'); - // Preferences should exist for embedded 'personalization_options.html'. - // We don't perform tests on them. - peoplePage.prefs = { - profile: {password_manager_leak_detection: {value: true}}, - safebrowsing: - {enabled: {value: true}, scout_reporting_enabled: {value: true}}, - }; + peoplePage.prefs = DEFAULT_PREFS; peoplePage.pageVisibility = settings.pageVisibility; document.body.appendChild(peoplePage); await accountManagerBrowserProxy.whenCalled('getAccounts'); - await browserProxy.whenCalled('getSyncStatus'); + await syncBrowserProxy.whenCalled('getSyncStatus'); Polymer.dom.flush(); }); @@ -628,10 +607,6 @@ }); suite('Chrome OS with account manager disabled', function() { - let peoplePage = null; - let syncBrowserProxy = null; - let profileInfoBrowserProxy = null; - suiteSetup(function() { loadTimeData.overrideValues({ // Simulate SplitSettings (OS settings in their own surface). @@ -651,13 +626,7 @@ PolymerTest.clearBody(); peoplePage = document.createElement('settings-people-page'); - // Preferences should exist for embedded 'personalization_options.html'. - // We don't perform tests on them. - peoplePage.prefs = { - profile: {password_manager_leak_detection: {value: true}}, - safebrowsing: - {enabled: {value: true}, scout_reporting_enabled: {value: true}}, - }; + peoplePage.prefs = DEFAULT_PREFS; peoplePage.pageVisibility = settings.pageVisibility; document.body.appendChild(peoplePage); @@ -689,5 +658,51 @@ assertEquals(oldRoute, settings.Router.getInstance().getCurrentRoute()); }); }); + + suite('Chrome OS with SplitSettingsSync', function() { + suiteSetup(function() { + loadTimeData.overrideValues({ + splitSettingsSyncEnabled: true, + }); + }); + + setup(async function() { + syncBrowserProxy = new TestSyncBrowserProxy(); + settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy; + + profileInfoBrowserProxy = new TestProfileInfoBrowserProxy(); + settings.ProfileInfoBrowserProxyImpl.instance_ = + profileInfoBrowserProxy; + + PolymerTest.clearBody(); + peoplePage = document.createElement('settings-people-page'); + peoplePage.prefs = DEFAULT_PREFS; + peoplePage.pageVisibility = settings.pageVisibility; + document.body.appendChild(peoplePage); + + await syncBrowserProxy.whenCalled('getSyncStatus'); + Polymer.dom.flush(); + }); + + teardown(function() { + peoplePage.remove(); + }); + + test('Sync account control is shown', () => { + sync_test_util.simulateSyncStatus({ + signinAllowed: true, + syncSystemEnabled: true, + }); + + // Account control is visible. + const accountControl = peoplePage.$$('settings-sync-account-control'); + assertNotEquals( + 'none', window.getComputedStyle(accountControl).display); + + // Profile row items are not available. + assertFalse(!!peoplePage.$$('#profile-icon')); + assertFalse(!!peoplePage.$$('#profile-row')); + }); + }); } });
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 7bc18b97..66ac32f 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -1313,7 +1313,7 @@ network::DnsLookupResult result2 = network::BlockingDnsLookup(network_context, kHostPortPair, std::move(params), net::NetworkIsolationKey()); - EXPECT_EQ(net::ERR_DNS_CACHE_MISS, result2.error); + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, result2.error); } // HostResolver and HostResolverPrivate tests. The PPAPI code used by these
diff --git a/chromeos/components/quick_answers/quick_answers_client.cc b/chromeos/components/quick_answers/quick_answers_client.cc index 9e36d11..d0c1b54 100644 --- a/chromeos/components/quick_answers/quick_answers_client.cc +++ b/chromeos/components/quick_answers/quick_answers_client.cc
@@ -46,13 +46,16 @@ : url_loader_factory_(url_loader_factory), assistant_state_(assistant_state), delegate_(delegate) { - // We observe Assistant state to detect enabling/disabling of Assistant in - // settings as well as enabling/disabling of screen context. - assistant_state_->AddObserver(this); + if (assistant_state_) { + // We observe Assistant state to detect enabling/disabling of Assistant in + // settings as well as enabling/disabling of screen context. + assistant_state_->AddObserver(this); + } } QuickAnswersClient::~QuickAnswersClient() { - assistant_state_->RemoveObserver(this); + if (assistant_state_) + assistant_state_->RemoveObserver(this); } void QuickAnswersClient::OnAssistantFeatureAllowedChanged( @@ -79,6 +82,10 @@ NotifyEligibilityChanged(); } +void QuickAnswersClient::OnAssistantStateDestroyed() { + assistant_state_ = nullptr; +} + void QuickAnswersClient::SendRequest( const QuickAnswersRequest& quick_answers_request) { // Preprocess the request. @@ -96,8 +103,8 @@ void QuickAnswersClient::NotifyEligibilityChanged() { DCHECK(delegate_); bool is_eligible = - (chromeos::features::IsQuickAnswersEnabled() && assistant_enabled_ && - locale_supported_ && assistant_context_enabled_ && + (chromeos::features::IsQuickAnswersEnabled() && assistant_state_ && + assistant_enabled_ && locale_supported_ && assistant_context_enabled_ && assistant_allowed_state_ == ash::mojom::AssistantAllowedState::ALLOWED); if (is_eligible_ != is_eligible) {
diff --git a/chromeos/components/quick_answers/quick_answers_client.h b/chromeos/components/quick_answers/quick_answers_client.h index 77b373b..dbcc3e1 100644 --- a/chromeos/components/quick_answers/quick_answers_client.h +++ b/chromeos/components/quick_answers/quick_answers_client.h
@@ -64,9 +64,10 @@ void OnAssistantSettingsEnabled(bool enabled) override; void OnAssistantContextEnabled(bool enabled) override; void OnLocaleChanged(const std::string& locale) override; + void OnAssistantStateDestroyed() override; - // Send a quick answer request. - void SendRequest(const QuickAnswersRequest& quick_answers_request); + // Send a quick answer request. Virtual for testing. + virtual void SendRequest(const QuickAnswersRequest& quick_answers_request); private: void OnQuickAnswerReceived(std::unique_ptr<QuickAnswer> quick_answer);
diff --git a/chromeos/network/OWNERS b/chromeos/network/OWNERS index 7ac9225..8c9e09c 100644 --- a/chromeos/network/OWNERS +++ b/chromeos/network/OWNERS
@@ -1,4 +1,5 @@ +azeemarshad@chromium.org khorimoto@chromium.org stevenjb@chromium.org tbarzic@chromium.org -# COMPONENT: OS>Systems>Network +# COMPONENT: UI>Shell>Networking
diff --git a/chromeos/services/machine_learning/public/mojom/graph_executor.mojom b/chromeos/services/machine_learning/public/mojom/graph_executor.mojom index 42d5c04..be84ea0 100644 --- a/chromeos/services/machine_learning/public/mojom/graph_executor.mojom +++ b/chromeos/services/machine_learning/public/mojom/graph_executor.mojom
@@ -28,8 +28,6 @@ UNKNOWN_OUTPUT_ERROR = 7, DUPLICATE_OUTPUT_ERROR = 8, EXECUTION_ERROR = 9, - // Remove kMax and use builtin kMaxValue after Mojo uprev (crbug.com/909719). - kMax = EXECUTION_ERROR, }; // API for performing inference on a TensorFlow graph. A given graph can be
diff --git a/chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom b/chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom index 745ad0f4..2e24676 100644 --- a/chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom +++ b/chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom
@@ -23,8 +23,6 @@ OK = 0, MODEL_SPEC_ERROR = 1, LOAD_MODEL_ERROR = 2, - // Remove kMax and use builtin kMaxValue after Mojo uprev (crbug.com/909719). - kMax = LOAD_MODEL_ERROR, }; // Top-level interface between Chromium and the ML Service daemon.
diff --git a/chromeos/services/machine_learning/public/mojom/model.mojom b/chromeos/services/machine_learning/public/mojom/model.mojom index 2b48d7a..ea9b891 100644 --- a/chromeos/services/machine_learning/public/mojom/model.mojom +++ b/chromeos/services/machine_learning/public/mojom/model.mojom
@@ -44,8 +44,6 @@ OK = 0, MODEL_INTERPRETATION_ERROR = 1, MEMORY_ALLOCATION_ERROR = 2, - // Remove kMax and use builtin kMaxValue after Mojo uprev (crbug.com/909719). - kMax = MEMORY_ALLOCATION_ERROR, }; // Model specification for builtin models.
diff --git a/components/cronet/stale_host_resolver.cc b/components/cronet/stale_host_resolver.cc index 5097042..58fb0c8 100644 --- a/components/cronet/stale_host_resolver.cc +++ b/components/cronet/stale_host_resolver.cc
@@ -216,8 +216,10 @@ cache_parameters.source = net::HostResolverSource::LOCAL_ONLY; cache_request_ = resolver_->inner_resolver_->CreateRequest( host_, network_isolation_key_, net_log_, cache_parameters); - cache_error_ = + int error = cache_request_->Start(base::BindOnce([](int error) { NOTREACHED(); })); + DCHECK_NE(net::ERR_IO_PENDING, error); + cache_error_ = cache_request_->GetResolveErrorInfo().error; DCHECK_NE(net::ERR_IO_PENDING, cache_error_); // If it's a fresh cache hit (or literal), return it synchronously. if (cache_error_ != net::ERR_DNS_CACHE_MISS &&
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index 6cb904b..ef1a76a 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -9,6 +9,8 @@ #include "base/macros.h" #include "cc/trees/layer_tree_frame_sink.h" #include "components/exo/layer_tree_frame_sink_holder.h" +#include "components/exo/shell_surface_base.h" +#include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" #include "components/exo/wm_helper.h" #include "components/viz/common/quads/compositor_frame.h" @@ -17,6 +19,7 @@ #include "components/viz/common/quads/solid_color_draw_quad.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/skia/include/core/SkPath.h" +#include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" @@ -212,6 +215,21 @@ void SurfaceTreeHost::SubmitCompositorFrame() { viz::CompositorFrame frame = PrepareToSubmitCompositorFrame(); + // TODO(1041932,1034876): Remove or early return once these issues + // are fixed or identified. + if (frame.size_in_pixels().IsEmpty()) { + aura::Window* toplevel = root_surface_->window()->GetToplevelWindow(); + auto app_type = toplevel->GetProperty(aura::client::kAppType); + const std::string* app_id = GetShellApplicationId(toplevel); + const std::string* startup_id = GetShellStartupId(toplevel); + auto* shell_surface = GetShellSurfaceBaseForWindow(toplevel); + DCHECK(!frame.size_in_pixels().IsEmpty()) + << " Title=" << shell_surface->GetWindowTitle() + << ", AppType=" << static_cast<int>(app_type) + << ", AppId=" << (app_id ? *app_id : "''") + << ", StartupId=" << (startup_id ? *startup_id : "''"); + } + root_surface_->AppendSurfaceHierarchyCallbacks(&frame_callbacks_, &presentation_callbacks_); if (!presentation_callbacks_.empty()) {
diff --git a/components/metrics/structured/BUILD.gn b/components/metrics/structured/BUILD.gn index 3cddbd9..6abb879 100644 --- a/components/metrics/structured/BUILD.gn +++ b/components/metrics/structured/BUILD.gn
@@ -10,6 +10,8 @@ sources = [ "event_base.cc", "event_base.h", + "key_data.cc", + "key_data.h", "recorder.cc", "recorder.h", "structured_metrics_provider.cc", @@ -22,13 +24,17 @@ "//base", "//components/metrics", "//components/prefs", + "//crypto", "//tools/metrics/structured:structured_events", ] } source_set("unit_tests") { testonly = true - sources = [ "structured_metrics_provider_unittest.cc" ] + sources = [ + "key_data_unittest.cc", + "structured_metrics_provider_unittest.cc", + ] deps = [ ":structured",
diff --git a/components/metrics/structured/DEPS b/components/metrics/structured/DEPS index 6f3255b4..1f172b2 100644 --- a/components/metrics/structured/DEPS +++ b/components/metrics/structured/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/metrics", "+components/prefs", + "+tools/metrics/structured", ]
diff --git a/components/metrics/structured/key_data.cc b/components/metrics/structured/key_data.cc new file mode 100644 index 0000000..539c0a52 --- /dev/null +++ b/components/metrics/structured/key_data.cc
@@ -0,0 +1,193 @@ +// Copyright 2019 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/metrics/structured/key_data.h" + +#include <memory> + +#include "base/rand_util.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/time/time.h" +#include "base/unguessable_token.h" +#include "base/values.h" +#include "components/prefs/json_pref_store.h" +#include "crypto/hmac.h" +#include "crypto/sha2.h" +#include "tools/metrics/structured/structured_events.h" + +namespace metrics { +namespace structured { +namespace internal { +namespace { + +// The expected size of a key, in bytes. +constexpr size_t kKeySize = 32; + +// The default maximum number of days before rotating keys. +constexpr size_t kDefaultRotationPeriod = 90; + +// Generates a key, which is the string representation of +// base::UnguessableToken, and is of size |kKeySize| bytes. +std::string GenerateKey() { + const std::string key = base::UnguessableToken::Create().ToString(); + DCHECK_EQ(key.size(), kKeySize); + return key; +} + +std::string HashToHex(const uint64_t hash) { + return base::HexEncode(&hash, sizeof(uint64_t)); +} + +std::string KeyPath(const uint64_t event) { + return base::StrCat({"keys.", base::NumberToString(event), ".key"}); +} + +std::string LastRotationPath(const uint64_t event) { + return base::StrCat({"keys.", base::NumberToString(event), ".last_rotation"}); +} + +std::string RotationPeriodPath(const uint64_t event) { + return base::StrCat( + {"keys.", base::NumberToString(event), ".rotation_period"}); +} + +} // namespace + +KeyData::KeyData(JsonPrefStore* key_store) : key_store_(key_store) { + DCHECK(key_store_); + ValidateKeys(); +} + +KeyData::~KeyData() = default; + +base::Optional<std::string> KeyData::ValidateAndGetKey(const uint64_t event) { + DCHECK(key_store_); + const int now = (base::Time::Now() - base::Time::UnixEpoch()).InDays(); + + // If the key for |key_path| doesn't exist, initialize new key data. Set the + // last rotation to a uniformly selected day between today and + // |kDefaultRotationPeriod| days ago, to uniformly distribute users amongst + // rotation cohorts. + if (!key_store_->GetValue(KeyPath(event), nullptr)) { + const int rotation_seed = base::RandInt(0, kDefaultRotationPeriod - 1); + SetRotationPeriod(event, kDefaultRotationPeriod); + SetLastRotation(event, now - rotation_seed); + SetKey(event, GenerateKey()); + } + + // If the key for |event| is outdated, generate a new key and write it to + // the |keys| pref store along with updated rotation data. Update the last + // rotation such that the user stays in the same cohort. + const int rotation_period = GetRotationPeriod(event); + const int last_rotation = GetLastRotation(event); + if (now - last_rotation > rotation_period) { + const int new_last_rotation = now - (now - last_rotation) % rotation_period; + SetLastRotation(event, new_last_rotation); + SetKey(event, GenerateKey()); + } + + const base::Value* key_json; + if (!(key_store_->GetValue(KeyPath(event), &key_json) && + key_json->is_string())) { + // TODO(crbug.com/1016655): log an error to UMA. + return base::nullopt; + } + + const std::string key = key_json->GetString(); + if (key.size() != kKeySize) { + // TODO(crbug.com/1016655): log an error to UMA. + return base::nullopt; + } + + return key; +} + +void KeyData::ValidateKeys() { + for (const uint64_t event : metrics::structured::events::kEventNameHashes) { + ValidateAndGetKey(event); + } +} + +void KeyData::SetLastRotation(const uint64_t event, const int last_rotation) { + return key_store_->SetValue(LastRotationPath(event), + std::make_unique<base::Value>(last_rotation), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); +} + +void KeyData::SetRotationPeriod(const uint64_t event, + const int rotation_period) { + return key_store_->SetValue(RotationPeriodPath(event), + std::make_unique<base::Value>(rotation_period), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); +} + +void KeyData::SetKey(const uint64_t event, const std::string& key) { + return key_store_->SetValue(KeyPath(event), + std::make_unique<base::Value>(key), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); +} + +int KeyData::GetLastRotation(const uint64_t event) { + const base::Value* value; + if (!(key_store_->GetValue(LastRotationPath(event), &value) && + value->is_int())) { + // TODO(crbug.com/1016655): log an error to UMA. + DCHECK(false); + return 0u; + } + return value->GetInt(); +} + +int KeyData::GetRotationPeriod(const uint64_t event) { + const base::Value* value; + if (!(key_store_->GetValue(RotationPeriodPath(event), &value) && + value->is_int())) { + // TODO(crbug.com/1016655): log an error to UMA. + DCHECK(false); + return 0u; + } + return value->GetInt(); +} + +uint64_t KeyData::UserEventId(const uint64_t event) { + // Retrieve the key for |event|. + const base::Optional<std::string> key = ValidateAndGetKey(event); + if (!key) { + // TODO(crbug.com/1016655): log an error to UMA. + return 0u; + } + + // Compute and return the hash. + uint64_t hash; + crypto::SHA256HashString(key.value(), &hash, sizeof(uint64_t)); + return hash; +} + +uint64_t KeyData::HashForEventMetric(const uint64_t event, + const uint64_t metric, + const std::string& value) { + // Retrieve the key for |event|. + const base::Optional<std::string> key = ValidateAndGetKey(event); + if (!key) { + // TODO(crbug.com/1016655): log an error to UMA. + DCHECK(false); + return 0u; + } + + // Initialize the HMAC. + crypto::HMAC hmac(crypto::HMAC::HashAlgorithm::SHA256); + CHECK(hmac.Init(key.value())); + + // Compute and return the digest. + const std::string salted_value = base::StrCat({HashToHex(metric), value}); + uint64_t digest; + CHECK(hmac.Sign(salted_value, reinterpret_cast<uint8_t*>(&digest), + sizeof(digest))); + return digest; +} + +} // namespace internal +} // namespace structured +} // namespace metrics
diff --git a/components/metrics/structured/key_data.h b/components/metrics/structured/key_data.h new file mode 100644 index 0000000..90497ced --- /dev/null +++ b/components/metrics/structured/key_data.h
@@ -0,0 +1,115 @@ +// Copyright 2019 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_METRICS_STRUCTURED_KEY_DATA_H_ +#define COMPONENTS_METRICS_STRUCTURED_KEY_DATA_H_ + +#include <string> + +#include "base/optional.h" + +class JsonPrefStore; + +namespace metrics { +namespace structured { +namespace internal { + +// KeyData is the central class for managing keys and generating hashes for +// structured metrics. +// +// The class maintains one key and its rotation data for every event defined +// in /tools/metrics/structured.xml. This can be used to generate: +// - a user ID for the event with KeyData::UserEventId. +// - a hash of a given value for the event with KeyData::Hash. +// +// KeyData performs key rotation. Every event is associated with a rotation +// period, which is 90 days unless specified in structured.xml. Keys are rotated +// with a resolution of one day. They are guaranteed not to be used for Hash or +// UserEventId for longer than their rotation period, except in cases of local +// clock changes. +// +// When first created, every event's key rotation date is selected uniformly so +// that there is an even distribution of rotations across users. This means +// that, for most users, the first rotation period will be shorter than the +// standard full rotation period for that event. +// +// Key storage is backed by a JsonPrefStore which is passed to the ctor and must +// outlive the KeyData instance. Within the pref store, each event has three +// pieces of associated data: +// - the rotation period for this event in days. +// - the day of the last key rotation, as a day since the unix epoch. +// - the key itself. +// +// This is stored in the structure: +// keys.{event_name_hash}.rotation_period +// .last_rotation +// .key +// +// TODO(crbug.com/1016655): log UMA error metrics +// TODO(crbug.com/1016655): add ability to override default rotation period +class KeyData { + public: + explicit KeyData(JsonPrefStore* key_store); + ~KeyData(); + + KeyData(const KeyData&) = delete; + KeyData& operator=(const KeyData&) = delete; + + // Returns a digest of |value| for |metric| in the context of |event|. + // Terminology: a metric is a (name, value) pair, and an event is a bundle of + // metrics. + // + // - |event| is the uint64 name hash of an event. + // - |metric| is the uint64 name hash of a metric within |event|. + // - |value| is the string value to hash. + // + // The result is the HMAC digest of the |value| salted with |metric|, using + // the key for |event|. That is: + // + // HMAC_SHA256(key(event), concat(value, hex(metric))) + // + // Returns 0u in case of an error. + uint64_t HashForEventMetric(uint64_t event, + uint64_t metric, + const std::string& value); + + // Returns an ID for this (user, |event|) pair. |event| is the name of an + // event, represented by the first 8 bytes of the MD5 hash of its name defined + // in structured.xml. + // + // The derived ID is the first 8 bytes of SHA256(key(event)). Returns 0u in + // case of an error. + // + // This ID is intended as the only ID for a particular structured metrics + // event. However, events are uploaded from the device alongside the UMA + // client ID, which is only removed after the event reaches the server. This + // means events are associated with the client ID when uploaded from the + // device. See the class comment of StructuredMetricsProvider for more + // details. + uint64_t UserEventId(uint64_t event); + + private: + int GetRotationPeriod(uint64_t event); + void SetRotationPeriod(uint64_t event, int rotation_period); + + int GetLastRotation(uint64_t event); + void SetLastRotation(uint64_t event, int last_rotation); + + // Ensure that a valid key exists for |event|, and return it. Either returns a + // string of size |kKeySize| or base::nullopt, which indicates an error. + base::Optional<std::string> ValidateAndGetKey(uint64_t event); + void SetKey(uint64_t event, const std::string& key); + + // Ensure that valid keys exist for all events. + void ValidateKeys(); + + // Storage for keys and rotation data. Must outlive the KeyData instance. + JsonPrefStore* key_store_; +}; + +} // namespace internal +} // namespace structured +} // namespace metrics + +#endif // COMPONENTS_METRICS_STRUCTURED_KEY_DATA_H_
diff --git a/components/metrics/structured/key_data_unittest.cc b/components/metrics/structured/key_data_unittest.cc new file mode 100644 index 0000000..0581cd5 --- /dev/null +++ b/components/metrics/structured/key_data_unittest.cc
@@ -0,0 +1,303 @@ +// Copyright 2019 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/metrics/structured/key_data.h" + +#include <memory> +#include <string> + +#include "base/containers/flat_set.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/scoped_mock_clock_override.h" +#include "base/test/task_environment.h" +#include "base/values.h" +#include "components/metrics/structured/event_base.h" +#include "components/metrics/structured/recorder.h" +#include "components/prefs/json_pref_store.h" +#include "components/prefs/persistent_pref_store.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace metrics { +namespace structured { +namespace internal { + +namespace { + +// 32 byte long test key, matching the size of a real key. +constexpr char kKey[] = "abcdefghijklmnopqrstuvwxyzabcdef"; + +// These event and metric names are used for testing. +// - event: TestEventOne +// - metric: TestValueOne +// - metric: TestValueTwo +// - event: TestEventTwo +// - metric: TestValueOne + +// The name hash of "TestEventOne". +constexpr uint64_t kEventOneHash = UINT64_C(15619026293081468407); +// The name hash of "TestEventTwo". +constexpr uint64_t kEventTwoHash = UINT64_C(15791833939776536363); + +// The name hash of "TestMetricOne". +constexpr uint64_t kMetricOneHash = UINT64_C(637929385654885975); +// The name hash of "TestMetricTwo". +constexpr uint64_t kMetricTwoHash = UINT64_C(14083999144141567134); + +// The hex-encoded frst 8 bytes of SHA256(kKey), ie. the user ID for key kKey. +constexpr char kUserId[] = "2070DF23E0D95759"; + +// Test values and their hashes. Hashes are the first 8 bytes of: +// +// HMAC_SHA256(concat(hex(kMetricNHash), kValueN), +// "abcdefghijklmnopqrstuvwxyzabcdef") +constexpr char kValueOne[] = "value one"; +constexpr char kValueTwo[] = "value two"; +constexpr char kValueOneHash[] = "805B8790DC69B773"; +constexpr char kValueTwoHash[] = "87CEF12FB15E0B3A"; + +std::string HashToHex(const uint64_t hash) { + return base::HexEncode(&hash, sizeof(uint64_t)); +} + +std::string KeyPath(const uint64_t event) { + return base::StrCat({"keys.", base::NumberToString(event), ".key"}); +} + +std::string LastRotationPath(const uint64_t event) { + return base::StrCat({"keys.", base::NumberToString(event), ".last_rotation"}); +} + +std::string RotationPeriodPath(const uint64_t event) { + return base::StrCat( + {"keys.", base::NumberToString(event), ".rotation_period"}); +} + +} // namespace + +class KeyDataTest : public testing::Test { + protected: + void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } + + void StandardSetup() { + MakeKeyStore(); + MakeKeyData(); + CommitKeyStore(); + } + + void ResetState() { + key_data_.reset(); + key_store_.reset(); + base::DeleteFile(GetKeyStorePath(), false); + ASSERT_FALSE(base::PathExists(GetKeyStorePath())); + } + + void MakeKeyStore() { + key_store_ = new JsonPrefStore(GetKeyStorePath()); + key_store_->ReadPrefs(); + } + + void MakeKeyData() { key_data_ = std::make_unique<KeyData>(GetKeyStore()); } + + void CommitKeyStore() { + key_store_->CommitPendingWrite(); + Wait(); + ASSERT_TRUE(base::PathExists(GetKeyStorePath())); + } + + JsonPrefStore* GetKeyStore() { return key_store_.get(); } + + base::FilePath GetKeyStorePath() { + return temp_dir_.GetPath().Append("keys.json"); + } + + std::string GetString(const std::string& path) { + const base::Value* value; + GetKeyStore()->GetValue(path, &value); + return value->GetString(); + } + + int GetInt(const std::string& path) { + const base::Value* value; + GetKeyStore()->GetValue(path, &value); + return value->GetInt(); + } + + void SetString(const std::string& path, const std::string& value) { + key_store_->SetValue(path, std::make_unique<base::Value>(value), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + CommitKeyStore(); + } + + void SetInt(const std::string& path, const int value) { + key_store_->SetValue(path, std::make_unique<base::Value>(value), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + CommitKeyStore(); + } + + void SetKeyData(const uint64_t event, + const std::string& key, + const int last_rotation, + const int rotation_period) { + SetString(KeyPath(event), key); + SetInt(LastRotationPath(event), last_rotation); + SetInt(RotationPeriodPath(event), rotation_period); + } + + void Wait() { task_environment_.RunUntilIdle(); } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::MainThreadType::UI, + base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED}; + base::ScopedTempDir temp_dir_; + base::ScopedMockClockOverride time_; + scoped_refptr<JsonPrefStore> key_store_; + + std::unique_ptr<KeyData> key_data_; +}; + +// If there is no key store file present, check that new keys are generated for +// each event, and those keys are of the right length and different from each +// other. +TEST_F(KeyDataTest, GeneratesKeysForEvents) { + StandardSetup(); + const std::string key_one = GetString(KeyPath(kEventOneHash)); + const std::string key_two = GetString(KeyPath(kEventTwoHash)); + + EXPECT_EQ(key_one.size(), 32ul); + EXPECT_EQ(key_two.size(), 32ul); + EXPECT_NE(key_one, key_two); +} + +// When repeatedly initialized with no key store file present, ensure the keys +// generated each time are distinct. +TEST_F(KeyDataTest, GeneratesDistinctKeys) { + base::flat_set<std::string> keys; + + for (int i = 0; i < 10; ++i) { + ResetState(); + StandardSetup(); + keys.insert(GetString(KeyPath(kEventOneHash))); + } + + EXPECT_EQ(keys.size(), 10ul); +} + +// If there is an existing key store file, check that its keys are not replaced. +TEST_F(KeyDataTest, ReuseExistingKeys) { + StandardSetup(); + const std::string key_one = GetString(KeyPath(kEventOneHash)); + CommitKeyStore(); + + key_data_.reset(); + key_store_.reset(); + StandardSetup(); + const std::string key_two = GetString(KeyPath(kEventOneHash)); + + EXPECT_EQ(key_one, key_two); +} + +// Check that different events have different hashes for the same metric and +// value. +TEST_F(KeyDataTest, DifferentEventsDifferentHashes) { + StandardSetup(); + // Even though + EXPECT_NE( + key_data_->HashForEventMetric(kEventOneHash, kMetricOneHash, "value"), + key_data_->HashForEventMetric(kEventTwoHash, kMetricOneHash, "value")); +} + +// Check that an event has different hashes for different values of the same +// metric. +TEST_F(KeyDataTest, DifferentMetricsDifferentHashes) { + StandardSetup(); + EXPECT_NE( + key_data_->HashForEventMetric(kEventOneHash, kMetricOneHash, "first"), + key_data_->HashForEventMetric(kEventOneHash, kMetricOneHash, "second")); +} + +// Check that an event has different hashes for different metrics with the same +// value. +TEST_F(KeyDataTest, DifferentValuesDifferentHashes) { + StandardSetup(); + EXPECT_NE( + key_data_->HashForEventMetric(kEventOneHash, kMetricOneHash, "value"), + key_data_->HashForEventMetric(kEventOneHash, kMetricTwoHash, "value")); +} + +// Ensure that KeyData::UserId is the expected value of SHA256(key). +TEST_F(KeyDataTest, CheckUserIDs) { + MakeKeyStore(); + SetKeyData(kEventOneHash, kKey, 0, 90); + CommitKeyStore(); + + MakeKeyData(); + EXPECT_EQ(HashToHex(key_data_->UserEventId(kEventOneHash)), kUserId); + EXPECT_NE(HashToHex(key_data_->UserEventId(kEventTwoHash)), kUserId); +} + +// Ensure that KeyData::Hash returns expected values for a known key and value. +TEST_F(KeyDataTest, CheckHashes) { + MakeKeyStore(); + SetString(KeyPath(kEventOneHash), kKey); + SetKeyData(kEventOneHash, kKey, 0, 90); + CommitKeyStore(); + + MakeKeyData(); + EXPECT_EQ(HashToHex(key_data_->HashForEventMetric(kEventOneHash, + kMetricOneHash, kValueOne)), + kValueOneHash); + EXPECT_EQ(HashToHex(key_data_->HashForEventMetric(kEventOneHash, + kMetricTwoHash, kValueTwo)), + kValueTwoHash); +} + +// Check that keys for a event are correctly rotated after the default 90 day +// rotation period. +TEST_F(KeyDataTest, KeysRotated) { + StandardSetup(); + const uint64_t first_id = key_data_->UserEventId(kEventOneHash); + const int start_day = (base::Time::Now() - base::Time::UnixEpoch()).InDays(); + + // TestEventOne has a default rotation period of 90 days. + EXPECT_EQ(GetInt(RotationPeriodPath(kEventOneHash)), 90); + + // Set the last rotation to today for testing. + SetInt(LastRotationPath(kEventOneHash), start_day); + + { + // Advancing by 50 days, the key should not be rotated. + key_data_.reset(); + time_.Advance(base::TimeDelta::FromDays(50)); + StandardSetup(); + EXPECT_EQ(key_data_->UserEventId(kEventOneHash), first_id); + EXPECT_EQ(GetInt(LastRotationPath(kEventOneHash)), start_day); + } + + { + // Advancing by another 50 days, the key should be rotated and the last + // rotation day should be incremented by 90. + key_data_.reset(); + time_.Advance(base::TimeDelta::FromDays(50)); + StandardSetup(); + EXPECT_NE(key_data_->UserEventId(kEventOneHash), first_id); + EXPECT_EQ(GetInt(LastRotationPath(kEventOneHash)), start_day + 90); + } + + { + // Advancing by 453 days, the last rotation day should now 6 periods of 90 + // days ahead. + key_data_.reset(); + time_.Advance(base::TimeDelta::FromDays(453)); + StandardSetup(); + EXPECT_EQ(GetInt(LastRotationPath(kEventOneHash)), start_day + 6 * 90); + } +} + +} // namespace internal +} // namespace structured +} // namespace metrics
diff --git a/components/metrics/structured/structured_metrics_provider.h b/components/metrics/structured/structured_metrics_provider.h index ec57468d..65ff1d8 100644 --- a/components/metrics/structured/structured_metrics_provider.h +++ b/components/metrics/structured/structured_metrics_provider.h
@@ -28,6 +28,13 @@ // thread safe and should only be called on the browser UI sequence, because // calls from the metrics service come on the UI sequence. // +// Each structured metrics event is sent with other UMA data, and so is +// associated with the UMA client ID when received by the UMA server. The client +// ID is stripped from the events after they reach the server, and so data at +// rest is not attached to the client ID. However, please note that structured +// events are *not* separated from the client ID at the point of upload from +// the device. +// // Currently, the structured metrics system is cros-only and relies on the cros // cryptohome to store keys and unsent logs, collectively called 'state'. This // means structured metrics collection cannot begin until a profile eligible
diff --git a/components/omnibox/browser/scored_history_match_unittest.cc b/components/omnibox/browser/scored_history_match_unittest.cc index 4b92625..203979fe 100644 --- a/components/omnibox/browser/scored_history_match_unittest.cc +++ b/components/omnibox/browser/scored_history_match_unittest.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <memory> +#include <numeric> #include <utility> #include "base/auto_reset.h" @@ -13,7 +14,9 @@ #include "base/i18n/break_iterator.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "components/omnibox/browser/omnibox_field_trial.h" +#include "components/omnibox/common/omnibox_features.h" #include "components/search_engines/search_terms_data.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -63,11 +66,12 @@ // Convenience function for GetTopicalityScore() that builds the term match // and word break information automatically that are needed to call - // GetTopicalityScore(). It only works for scoring a single term, not - // multiple terms. - float GetTopicalityScoreOfTermAgainstURLAndTitle(const base::string16& term, - const GURL& url, - const base::string16& title); + // GetTopicalityScore(). + float GetTopicalityScoreOfTermAgainstURLAndTitle( + const std::vector<const std::string>&, + const WordStarts term_word_starts, + const GURL& url, + const base::string16& title); }; history::URLRow ScoredHistoryMatchTest::MakeURLRow(const char* url, @@ -106,29 +110,29 @@ } float ScoredHistoryMatchTest::GetTopicalityScoreOfTermAgainstURLAndTitle( - const base::string16& term, + const std::vector<const std::string>& terms, + const WordStarts term_word_starts, const GURL& url, const base::string16& title) { - String16Vector term_vector = {term}; - WordStarts term_word_starts = {0}; - base::i18n::BreakIterator iter(term, base::i18n::BreakIterator::BREAK_WORD); - if (iter.Init()) { - // Find the first word start. - while (iter.Advance() && !iter.IsWord()) { - } - term_word_starts[0] = iter.prev(); - } + String16Vector term_vector; + std::transform(terms.begin(), terms.end(), std::back_inserter(term_vector), + [](auto term) { return base::UTF8ToUTF16(term); }); + std::string terms_joint = + std::accumulate(std::next(terms.begin()), terms.end(), terms[0], + [](std::string accumulator, std::string term) { + return accumulator + " " + term; + }); RowWordStarts row_word_starts; base::string16 url_string = base::UTF8ToUTF16(url.spec()); String16SetFromString16(url_string, &row_word_starts.url_word_starts_); String16SetFromString16(title, &row_word_starts.title_word_starts_); - ScoredHistoryMatch scored_match(history::URLRow(GURL(url)), VisitInfoVector(), - term, term_vector, term_word_starts, - row_word_starts, false, 1, base::Time::Max()); - scored_match.url_matches = MatchTermInString(term, url_string, 0); - scored_match.title_matches = MatchTermInString(term, title, 0); + auto row = history::URLRow(GURL(url)); + row.set_title(title); + ScoredHistoryMatch scored_match( + row, VisitInfoVector(), base::UTF8ToUTF16(terms_joint), term_vector, + term_word_starts, row_word_starts, false, 1, base::Time::Max()); scored_match.topicality_threshold_ = -1; - return scored_match.GetTopicalityScore(1, url, + return scored_match.GetTopicalityScore(term_vector.size(), url, base::OffsetAdjuster::Adjustments(), term_word_starts, row_word_starts); } @@ -410,10 +414,10 @@ TEST_F(ScoredHistoryMatchTest, GetTopicalityScoreTrailingSlash) { const float hostname = GetTopicalityScoreOfTermAgainstURLAndTitle( - ASCIIToUTF16("def"), GURL("http://abc.def.com/"), + {"def"}, {0}, GURL("http://abc.def.com/"), ASCIIToUTF16("Non-Matching Title")); const float hostname_no_slash = GetTopicalityScoreOfTermAgainstURLAndTitle( - ASCIIToUTF16("def"), GURL("http://abc.def.com"), + {"def"}, {0}, GURL("http://abc.def.com"), ASCIIToUTF16("Non-Matching Title")); EXPECT_EQ(hostname_no_slash, hostname); } @@ -524,14 +528,36 @@ // is a valid match at a word break. To recognize this, // |terms_to_word_starts_offsets| must record that the "word" in this term // starts at the second character. - terms_to_word_starts_offsets[0] = 1; term_matches.clear(); term_matches.push_back(TermMatch(0, 27, 1)); filtered_term_matches = ScoredHistoryMatch::FilterTermMatchesByWordStarts( - term_matches, terms_to_word_starts_offsets, word_starts, 15, + term_matches, /*terms_to_word_starts_offsets*/ {1}, word_starts, 15, std::string::npos); ASSERT_EQ(1u, filtered_term_matches.size()); EXPECT_EQ(27u, filtered_term_matches[0].offset); + + // Check "de" + "fa" + "lt" matches "defa" when |allow_midword_continuations| + // is true. + term_matches.clear(); + term_matches.push_back(TermMatch(0, 16, 2)); + term_matches.push_back(TermMatch(1, 18, 2)); + term_matches.push_back(TermMatch(2, 21, 2)); + filtered_term_matches = ScoredHistoryMatch::FilterTermMatchesByWordStarts( + term_matches, {0, 0, 0}, word_starts, 15, std::string::npos, true); + ASSERT_EQ(2u, filtered_term_matches.size()); + EXPECT_EQ(16u, filtered_term_matches[0].offset); + EXPECT_EQ(18u, filtered_term_matches[1].offset); + + // Check "de" + "fa" + "lt" matches "de" when |allow_midword_continuations| is + // false. + term_matches.clear(); + term_matches.push_back(TermMatch(0, 16, 2)); + term_matches.push_back(TermMatch(1, 18, 2)); + term_matches.push_back(TermMatch(2, 21, 2)); + filtered_term_matches = ScoredHistoryMatch::FilterTermMatchesByWordStarts( + term_matches, {0, 0, 0}, word_starts, 15, std::string::npos, false); + ASSERT_EQ(1u, filtered_term_matches.size()); + EXPECT_EQ(16u, filtered_term_matches[0].offset); } TEST_F(ScoredHistoryMatchTest, GetFrequency) { @@ -629,30 +655,31 @@ TEST_F(ScoredHistoryMatchTest, GetTopicalityScore) { GURL url("http://abc.def.com/path1/path2?arg1=val1&arg2=val2#hash_fragment"); base::string16 title = ASCIIToUTF16("here is a - title"); - auto Score = [&](const char* term) { - return GetTopicalityScoreOfTermAgainstURLAndTitle(ASCIIToUTF16(term), url, - title); + auto Score = [&](const std::vector<const std::string>& term_vector, + const WordStarts term_word_starts) { + return GetTopicalityScoreOfTermAgainstURLAndTitle( + term_vector, term_word_starts, url, title); }; - const float hostname_score = Score("abc"); - const float hostname_mid_word_score = Score("bc"); - const float hostname_score_preceeding_punctuation = Score("://abc"); - const float domain_name_score = Score("def"); - const float domain_name_mid_word_score = Score("ef"); - const float domain_name_score_preceeding_dot = Score(".def"); - const float tld_score = Score("com"); - const float tld_mid_word_score = Score("om"); - const float tld_score_preceeding_dot = Score(".com"); - const float path_score = Score("path1"); - const float path_mid_word_score = Score("ath1"); - const float path_score_preceeding_slash = Score("/path1"); - const float arg_score = Score("arg1"); - const float arg_mid_word_score = Score("rg1"); - const float arg_score_preceeding_question_mark = Score("?arg1"); - const float protocol_score = Score("htt"); - const float protocol_mid_word_score = Score("tt"); - const float title_score = Score("her"); - const float title_mid_word_score = Score("er"); - const float wordless_match_at_title_mid_word_score = Score("-"); + const float hostname_score = Score({"abc"}, {0}); + const float hostname_mid_word_score = Score({"bc"}, {0}); + const float hostname_score_preceeding_punctuation = Score({"://abc"}, {3}); + const float domain_name_score = Score({"def"}, {0}); + const float domain_name_mid_word_score = Score({"ef"}, {0}); + const float domain_name_score_preceeding_dot = Score({".def"}, {1}); + const float tld_score = Score({"com"}, {0}); + const float tld_mid_word_score = Score({"om"}, {0}); + const float tld_score_preceeding_dot = Score({".com"}, {1}); + const float path_score = Score({"path1"}, {0}); + const float path_mid_word_score = Score({"ath1"}, {0}); + const float path_score_preceeding_slash = Score({"/path1"}, {1}); + const float arg_score = Score({"arg1"}, {0}); + const float arg_mid_word_score = Score({"rg1"}, {0}); + const float arg_score_preceeding_question_mark = Score({"?arg1"}, {1}); + const float protocol_score = Score({"htt"}, {0}); + const float protocol_mid_word_score = Score({"tt"}, {0}); + const float title_score = Score({"her"}, {0}); + const float title_mid_word_score = Score({"er"}, {0}); + const float wordless_match_at_title_mid_word_score = Score({"-"}, {1}); // Verify hostname and domain name > path > arg. EXPECT_GT(hostname_score, path_score); EXPECT_GT(domain_name_score, path_score); @@ -684,7 +711,6 @@ EXPECT_EQ(protocol_mid_word_score, 0); EXPECT_EQ(title_mid_word_score, 0); EXPECT_GT(wordless_match_at_title_mid_word_score, 0); - // Verify matches not at word starts score non 0 when they contain no words. // Check that title matches fit somewhere reasonable compared to the // various types of URL matches. EXPECT_GT(title_score, arg_score); @@ -696,6 +722,46 @@ EXPECT_GT(hostname_mid_word_score, protocol_mid_word_score); EXPECT_GT(hostname_mid_word_score, tld_score); EXPECT_GT(hostname_mid_word_score, tld_mid_word_score); + + // Check that midword matches are not allowed when + // kHistoryQuickProviderAllowButDoNotScoreMidwordTerms is disabled. + { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature( + omnibox::kHistoryQuickProviderAllowButDoNotScoreMidwordTerms); + + const float wordstart = Score({"frag"}, {0u}); + const float midword = Score({"ment"}, {0u}); + const float wordstart_midword_continuation = + Score({"frag", "ment"}, {0u, 0u}); + const float wordstart_midword_disjoint = Score({"frag", "ent"}, {0u, 0u}); + + EXPECT_GT(wordstart, 0); + EXPECT_EQ(midword, 0); + EXPECT_EQ(wordstart_midword_continuation, 0); + EXPECT_EQ(wordstart_midword_disjoint, 0); + } + + // Check that midword matches are allowed but not scored when + // kHistoryQuickProviderAllowButDoNotScoreMidwordTerms is enabled. + { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + omnibox::kHistoryQuickProviderAllowButDoNotScoreMidwordTerms); + + const float wordstart = Score({"frag"}, {0u}); + const float midword = Score({"ment"}, {0u}); + const float wordstart_midword_continuation = + Score({"frag", "ment"}, {0u, 0u}); + const float wordstart_midword_disjoint = Score({"frag", "ent"}, {0u, 0u}); + + EXPECT_GT(wordstart, 0); + EXPECT_EQ(midword, 0); + EXPECT_GT(wordstart_midword_continuation, 0); + EXPECT_GT(wordstart_midword_disjoint, 0); + EXPECT_GT(wordstart, wordstart_midword_continuation); + EXPECT_EQ(wordstart_midword_continuation, wordstart_midword_disjoint); + } } // Test the function GetFinalRelevancyScore().
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index 78a55e14..72329942 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -294,19 +294,19 @@ const base::Feature kOmniboxExperimentalSuggestScoring{ "OmniboxExperimentalSuggestScoring", base::FEATURE_DISABLED_BY_DEFAULT}; -// If disabled, terms with no wordstart matches disqualify the suggestion. If -// enabled, terms with no wordstart matches are allowed but not scored. E.g., -// both inputs 'java script' and 'java cript' will match a suggestion titled -// 'javascript' and score equivalently. +// If disabled, terms with no wordstart matches disqualify the suggestion unless +// they occur in the URL host. If enabled, terms with no wordstart matches are +// allowed but not scored. E.g., both inputs 'java script' and 'java cript' will +// match a suggestion titled 'javascript' and score equivalently. const base::Feature kHistoryQuickProviderAllowButDoNotScoreMidwordTerms{ "OmniboxHistoryQuickProviderAllowButDoNotScoreMidwordTerms", base::FEATURE_DISABLED_BY_DEFAULT}; -// If disabled, midword matches are ignored and input terms with no wordstart -// matches are scored 0, resulting in an overall score of 0. If enabled, midword -// matches are allowed and scored when they begin immediately after the previous -// match ends. E.g. 'java script' will match a suggestion titled 'javascript' -// but the input 'java cript' won't. +// If disabled, midword matches are ignored except in the URL host, and input +// terms with no wordstart matches are scored 0, resulting in an overall score +// of 0. If enabled, midword matches are allowed and scored when they begin +// immediately after the previous match ends. E.g. 'java script' will match a +// suggestion titled 'javascript' but the input 'java cript' won't. const base::Feature kHistoryQuickProviderAllowMidwordContinuations{ "OmniboxHistoryQuickProviderAllowMidwordContinuations", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/optimization_guide/hints_fetcher.cc b/components/optimization_guide/hints_fetcher.cc index c2e52ee..bb29f82f7 100644 --- a/components/optimization_guide/hints_fetcher.cc +++ b/components/optimization_guide/hints_fetcher.cc
@@ -67,6 +67,14 @@ return valid_urls; } +void RecordRequestStatusHistogram(proto::RequestContext request_context, + HintsFetcherRequestStatus status) { + base::UmaHistogramEnumeration( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + + GetStringNameForRequestContext(request_context), + status); +} + } // namespace HintsFetcher::HintsFetcher( @@ -131,16 +139,16 @@ DCHECK_GT(optimization_types.size(), 0u); if (content::GetNetworkConnectionTracker()->IsOffline()) { - std::move(hints_fetched_callback) - .Run(request_context, HintsFetcherRequestStatus::kNetworkOffline, - base::nullopt); + RecordRequestStatusHistogram(request_context, + HintsFetcherRequestStatus::kNetworkOffline); + std::move(hints_fetched_callback).Run(base::nullopt); return false; } if (active_url_loader_) { - std::move(hints_fetched_callback) - .Run(request_context, HintsFetcherRequestStatus::kFetcherBusy, - base::nullopt); + RecordRequestStatusHistogram(request_context, + HintsFetcherRequestStatus::kFetcherBusy); + std::move(hints_fetched_callback).Run(base::nullopt); return false; } @@ -148,9 +156,9 @@ GetSizeLimitedHostsDueForHintsRefresh(hosts); std::vector<GURL> valid_urls = GetValidURLsForFetching(urls); if (filtered_hosts.empty() && valid_urls.empty()) { - std::move(hints_fetched_callback) - .Run(request_context, HintsFetcherRequestStatus::kNoHostsOrURLsToFetch, - base::nullopt); + RecordRequestStatusHistogram( + request_context, HintsFetcherRequestStatus::kNoHostsOrURLsToFetch); + std::move(hints_fetched_callback).Run(base::nullopt); return false; } @@ -158,33 +166,33 @@ filtered_hosts.size()); if (optimization_types.empty()) { - std::move(hints_fetched_callback) - .Run(request_context, - HintsFetcherRequestStatus::kNoSupportedOptimizationTypes, - base::nullopt); + RecordRequestStatusHistogram( + request_context, + HintsFetcherRequestStatus::kNoSupportedOptimizationTypes); + std::move(hints_fetched_callback).Run(base::nullopt); return false; } hints_fetch_start_time_ = base::TimeTicks::Now(); request_context_ = request_context; - get_hints_request_ = std::make_unique<proto::GetHintsRequest>(); + proto::GetHintsRequest get_hints_request; for (const auto& optimization_type : optimization_types) - get_hints_request_->add_supported_optimizations(optimization_type); + get_hints_request.add_supported_optimizations(optimization_type); - get_hints_request_->set_context(request_context_); + get_hints_request.set_context(request_context_); for (const auto& url : valid_urls) - get_hints_request_->add_urls()->set_url(url.spec()); + get_hints_request.add_urls()->set_url(url.spec()); for (const auto& host : filtered_hosts) { - proto::HostInfo* host_info = get_hints_request_->add_hosts(); + proto::HostInfo* host_info = get_hints_request.add_hosts(); host_info->set_host(host); } std::string serialized_request; - get_hints_request_->SerializeToString(&serialized_request); + get_hints_request.SerializeToString(&serialized_request); net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("hintsfetcher_gethintsrequest", R"( @@ -274,13 +282,13 @@ GetStringNameForRequestContext(request_context_), fetch_latency); UpdateHostsSuccessfullyFetched(); - std::move(hints_fetched_callback_) - .Run(request_context_, HintsFetcherRequestStatus::kSuccess, - std::move(get_hints_response)); + RecordRequestStatusHistogram(request_context_, + HintsFetcherRequestStatus::kSuccess); + std::move(hints_fetched_callback_).Run(std::move(get_hints_response)); } else { - std::move(hints_fetched_callback_) - .Run(request_context_, HintsFetcherRequestStatus::kResponseError, - base::nullopt); + RecordRequestStatusHistogram(request_context_, + HintsFetcherRequestStatus::kResponseError); + std::move(hints_fetched_callback_).Run(base::nullopt); } }
diff --git a/components/optimization_guide/hints_fetcher.h b/components/optimization_guide/hints_fetcher.h index 7bb8829..31118b4 100644 --- a/components/optimization_guide/hints_fetcher.h +++ b/components/optimization_guide/hints_fetcher.h
@@ -58,8 +58,6 @@ // to pass back the fetched hints response from the remote Optimization Guide // Service. using HintsFetchedCallback = base::OnceCallback<void( - optimization_guide::proto::RequestContext request_context, - HintsFetcherRequestStatus fetch_status, base::Optional<std::unique_ptr<proto::GetHintsResponse>>)>; // A class to handle requests for optimization hints from a remote Optimization @@ -135,10 +133,6 @@ std::vector<std::string> GetSizeLimitedHostsDueForHintsRefresh( const std::vector<std::string>& hosts) const; - // Used to hold the GetHintsRequest being constructed and sent as a remote - // request. - std::unique_ptr<proto::GetHintsRequest> get_hints_request_; - // Used to hold the callback while the SimpleURLLoader performs the request // asynchronously. HintsFetchedCallback hints_fetched_callback_;
diff --git a/components/optimization_guide/hints_fetcher_unittest.cc b/components/optimization_guide/hints_fetcher_unittest.cc index e554707..04be60d 100644 --- a/components/optimization_guide/hints_fetcher_unittest.cc +++ b/components/optimization_guide/hints_fetcher_unittest.cc
@@ -55,21 +55,14 @@ hints_fetcher_->SetTimeClockForTesting(task_environment_.GetMockClock()); } - ~HintsFetcherTest() override {} + ~HintsFetcherTest() override = default; - void OnHintsFetched( - optimization_guide::proto::RequestContext request_context, - optimization_guide::HintsFetcherRequestStatus fetcher_request_status, - base::Optional<std::unique_ptr<proto::GetHintsResponse>> - get_hints_response) { - fetcher_request_status_ = fetcher_request_status; + void OnHintsFetched(base::Optional<std::unique_ptr<proto::GetHintsResponse>> + get_hints_response) { if (get_hints_response) hints_fetched_ = true; } - optimization_guide::HintsFetcherRequestStatus fetcher_request_status() { - return fetcher_request_status_; - } bool hints_fetched() { return hints_fetched_; } void SetConnectionOffline() { @@ -150,8 +143,6 @@ base::RunLoop().RunUntilIdle(); } - optimization_guide::HintsFetcherRequestStatus fetcher_request_status_ = - optimization_guide::HintsFetcherRequestStatus::kUnknown; bool hints_fetched_ = false; base::test::TaskEnvironment task_environment_; @@ -172,8 +163,6 @@ EXPECT_TRUE(FetchHints({"foo.com"}, {} /* urls */)); VerifyHasPendingFetchRequests(); EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK)); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kSuccess, - fetcher_request_status()); EXPECT_TRUE(hints_fetched()); histogram_tester.ExpectTotalCount( @@ -181,6 +170,10 @@ histogram_tester.ExpectTotalCount( "OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency.BatchUpdate", 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kSuccess, 1); } // Tests to ensure that multiple hint fetches by the same object cannot be in @@ -189,19 +182,29 @@ base::SimpleTestClock test_clock; SetTimeClockForTesting(&test_clock); - std::string response_content; // Fetch back to back without waiting for Fetch to complete, // |fetch_in_progress_| should cause early exit. - EXPECT_TRUE(FetchHints({"foo.com"}, {} /* urls */)); - EXPECT_FALSE(FetchHints({"bar.com"}, {} /* urls */)); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kFetcherBusy, - fetcher_request_status()); + { + base::HistogramTester histogram_tester; + EXPECT_TRUE(FetchHints({"foo.com"}, {} /* urls */)); + EXPECT_FALSE(FetchHints({"bar.com"}, {} /* urls */)); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kFetcherBusy, 1); + } // Once response arrives, check to make sure a new fetch can start. - SimulateResponse(response_content, net::HTTP_OK); - EXPECT_TRUE(FetchHints({"bar.com"}, {} /* urls */)); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kSuccess, - fetcher_request_status()); + { + base::HistogramTester histogram_tester; + std::string response_content; + SimulateResponse(response_content, net::HTTP_OK); + EXPECT_TRUE(FetchHints({"bar.com"}, {} /* urls */)); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kSuccess, 1); + } } // Tests that the hints are refreshed again for hosts for whom hints were @@ -269,12 +272,14 @@ // Send a 404 to HintsFetcher. SimulateResponse(response_content, net::HTTP_NOT_FOUND); EXPECT_FALSE(hints_fetched()); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kResponseError, - fetcher_request_status()); - // Make sure histogram not recorded on bad response. + // Make sure histograms are recorded correctly on bad response. histogram_tester.ExpectTotalCount( "OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency", 0); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kResponseError, 1); } TEST_F(HintsFetcherTest, FetchReturnBadResponse) { @@ -285,12 +290,14 @@ VerifyHasPendingFetchRequests(); EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK)); EXPECT_FALSE(hints_fetched()); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kResponseError, - fetcher_request_status()); - // Make sure histogram not recorded on bad response. + // Make sure histograms are recorded correctly on bad response. histogram_tester.ExpectTotalCount( "OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency", 0); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kResponseError, 1); } TEST_F(HintsFetcherTest, FetchAttemptWhenNetworkOffline) { @@ -300,12 +307,14 @@ std::string response_content; EXPECT_FALSE(FetchHints({"foo.com"}, {} /* urls */)); EXPECT_FALSE(hints_fetched()); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kNetworkOffline, - fetcher_request_status()); - // Make sure histogram not recorded on bad response. + // Make sure histograms are recorded correctly on bad response. histogram_tester.ExpectTotalCount( "OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency", 0); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + HintsFetcherRequestStatus::kNetworkOffline, 1); SetConnectionOnline(); EXPECT_TRUE(FetchHints({"foo.com"}, {} /* urls */)); @@ -385,7 +394,6 @@ } TEST_F(HintsFetcherTest, HintsFetcherHostsCovered) { - base::HistogramTester histogram_tester; std::vector<std::string> hosts{"host1.com", "host2.com"}; base::Time host_invalid_time = base::Time::Now() + base::TimeDelta().FromHours(1); @@ -397,7 +405,6 @@ } TEST_F(HintsFetcherTest, HintsFetcherCoveredHostExpired) { - base::HistogramTester histogram_tester; std::string response_content; std::vector<std::string> hosts{"host1.com", "host2.com"}; base::Time host_invalid_time = @@ -430,7 +437,6 @@ } TEST_F(HintsFetcherTest, HintsFetcherHostNotCovered) { - base::HistogramTester histogram_tester; std::vector<std::string> hosts{"host1.com", "host2.com"}; base::Time host_invalid_time = base::Time::Now() + base::TimeDelta().FromHours(1); @@ -446,7 +452,6 @@ } TEST_F(HintsFetcherTest, HintsFetcherRemoveExpiredOnSuccessfullyFetched) { - base::HistogramTester histogram_tester; std::string response_content; std::vector<std::string> hosts_expired{"host1.com", "host2.com"}; base::Time host_invalid_time = @@ -475,7 +480,6 @@ } TEST_F(HintsFetcherTest, HintsFetcherSuccessfullyFetchedHostsFull) { - base::HistogramTester histogram_tester; std::string response_content; std::vector<std::string> hosts; size_t max_hosts = @@ -505,7 +509,6 @@ } TEST_F(HintsFetcherTest, MaxHostsForOptimizationGuideServiceHintsFetch) { - base::HistogramTester histogram_tester; std::string response_content; std::vector<std::string> all_hosts; @@ -546,8 +549,6 @@ EXPECT_TRUE(FetchHints({}, {GURL("https://baz.com/r/werd")})); VerifyHasPendingFetchRequests(); EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK)); - EXPECT_EQ(optimization_guide::HintsFetcherRequestStatus::kSuccess, - fetcher_request_status()); EXPECT_TRUE(hints_fetched()); histogram_tester.ExpectTotalCount( @@ -555,6 +556,10 @@ histogram_tester.ExpectTotalCount( "OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency.BatchUpdate", 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + static_cast<int>(HintsFetcherRequestStatus::kSuccess), 1); } TEST_F(HintsFetcherTest, NoHostsOrURLsToFetch) { @@ -564,9 +569,10 @@ EXPECT_FALSE(FetchHints({} /* hosts */, {} /* urls */ )); EXPECT_FALSE(hints_fetched()); - EXPECT_EQ( - optimization_guide::HintsFetcherRequestStatus::kNoHostsOrURLsToFetch, - fetcher_request_status()); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus." + "BatchUpdate", + static_cast<int>(HintsFetcherRequestStatus::kNoHostsOrURLsToFetch), 1); } } // namespace optimization_guide
diff --git a/components/safe_browsing/core/features.cc b/components/safe_browsing/core/features.cc index 6d922e8..64261588 100644 --- a/components/safe_browsing/core/features.cc +++ b/components/safe_browsing/core/features.cc
@@ -50,12 +50,15 @@ const base::Feature kPasswordProtectionShowDomainsForSavedPasswords{ "SafeBrowsingPasswordProtectionShowDomainsForSavedPasswords", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kPasswordProtectionForSignedInUsers{ "SafeBrowsingPasswordProtectionForSignedInUsers", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPromptAppForDeepScanning{ + "SafeBrowsingPromptAppForDeepScanning", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kRealTimeUrlLookupEnabled{ "SafeBrowsingRealTimeUrlLookupEnabled", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -85,7 +88,7 @@ const base::Feature kSendSampledPingsForAllowlistDomains{ "SafeBrowsingSendSampledPingsForAllowlistDomain", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; constexpr base::FeatureParam<bool> kShouldFillOldPhishGuardProto{ &kPasswordProtectionForSignedInUsers, "DeprecateOldProto", false}; @@ -109,7 +112,7 @@ namespace { // List of Safe Browsing features. Boolean value for each list member should be // set to true if the experiment state should be listed on -// chrome://safe-browsing. +// chrome://safe-browsing. Features should be listed in alphabetical order. constexpr struct { const base::Feature* feature; // True if the feature's state should be listed on chrome://safe-browsing. @@ -126,6 +129,7 @@ {&kPasswordProtectionForSavedPasswords, true}, {&kPasswordProtectionShowDomainsForSavedPasswords, true}, {&kPasswordProtectionForSignedInUsers, true}, + {&kPromptAppForDeepScanning, true}, {&kRealTimeUrlLookupEnabled, true}, {&kSendOnFocusPing, true}, {&kSendPasswordReusePing, true},
diff --git a/components/safe_browsing/core/features.h b/components/safe_browsing/core/features.h index 57b43a7..d0a5e71 100644 --- a/components/safe_browsing/core/features.h +++ b/components/safe_browsing/core/features.h
@@ -18,7 +18,8 @@ } // namespace base namespace safe_browsing { -// Features list +// Features list, in alphabetical order. + // Controls whether we send RIND reports when a popup originating from a Google // Ad is blocked. extern const base::Feature kAdPopupTriggerFeature; @@ -51,11 +52,6 @@ // sent for scanning. extern const base::Feature kMalwareScanEnabled; -// Controls whether the user has forcibly enabled AP download protection. This -// flag will enable AP downloads protections even for users not enrolled in -// APP. -extern const base::Feature kForceUseAPDownloadProtection; - // Enable password protection for non-Google accounts. extern const base::Feature kPasswordProtectionForSavedPasswords; @@ -67,6 +63,9 @@ // Enable GAIA password protection for signed-in users. extern const base::Feature kPasswordProtectionForSignedInUsers; +// Controls whether Chrome prompts Advanced Protection users for deep scanning. +extern const base::Feature kPromptAppForDeepScanning; + // Controls whether Chrome sends on focus ping. extern const base::Feature kSendOnFocusPing;
diff --git a/components/viz/service/frame_sinks/video_detector_unittest.cc b/components/viz/service/frame_sinks/video_detector_unittest.cc index 588f9c0..df4c9f5 100644 --- a/components/viz/service/frame_sinks/video_detector_unittest.cc +++ b/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -84,7 +84,7 @@ false, false) {} - ~VideoDetectorTest() override {} + ~VideoDetectorTest() override = default; void SetUp() override { mock_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
diff --git a/content/browser/background_sync/background_sync_scheduler.cc b/content/browser/background_sync/background_sync_scheduler.cc index 56c324e..8e782e8e 100644 --- a/content/browser/background_sync/background_sync_scheduler.cc +++ b/content/browser/background_sync/background_sync_scheduler.cc
@@ -85,7 +85,17 @@ DCHECK(storage_partition); auto& delayed_processing_info = GetDelayedProcessingInfoMap(sync_type); - delayed_processing_info.erase(storage_partition); + if (delayed_processing_info.count(storage_partition)) { + base::TimeTicks run_time = + delayed_processing_info[storage_partition]->desired_run_time(); + + // If this storage partition was scheduling the next wakeup, reset the + // wakeup time for |sync_type|. + if (scheduled_wakeup_time_[sync_type] == run_time) + scheduled_wakeup_time_[sync_type] = base::TimeTicks::Max(); + + delayed_processing_info.erase(storage_partition); + } #if defined(OS_ANDROID) ScheduleOrCancelBrowserWakeupForSyncType(sync_type, storage_partition); @@ -108,13 +118,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); std::move(delayed_task).Run(); - - auto& delayed_processing_info = GetDelayedProcessingInfoMap(sync_type); - delayed_processing_info.erase(storage_partition); - -#if defined(OS_ANDROID) - ScheduleOrCancelBrowserWakeupForSyncType(sync_type, storage_partition); -#endif + CancelDelayedProcessing(storage_partition, sync_type); } #if defined(OS_ANDROID) @@ -133,6 +137,7 @@ // If no more scheduled tasks remain, cancel browser wakeup. // Canceling when there's no task scheduled is a no-op. if (delayed_processing_info.empty()) { + scheduled_wakeup_time_[sync_type] = base::TimeTicks::Max(); controller->CancelBrowserWakeup(sync_type); return; } @@ -144,6 +149,15 @@ return (lhs.second->desired_run_time() - base::TimeTicks::Now()) < (rhs.second->desired_run_time() - base::TimeTicks::Now()); }); + + base::TimeTicks next_time = min_info.second->desired_run_time(); + if (next_time >= scheduled_wakeup_time_[sync_type]) { + // There's an earlier wakeup time scheduled, no need to inform the + // scheduler. + return; + } + + scheduled_wakeup_time_[sync_type] = next_time; controller->ScheduleBrowserWakeUpWithDelay( sync_type, min_info.second->desired_run_time() - base::TimeTicks::Now()); }
diff --git a/content/browser/background_sync/background_sync_scheduler.h b/content/browser/background_sync/background_sync_scheduler.h index 7dc71fd..99a76b28 100644 --- a/content/browser/background_sync/background_sync_scheduler.h +++ b/content/browser/background_sync/background_sync_scheduler.h
@@ -57,6 +57,7 @@ friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; friend class base::DeleteHelper<BackgroundSyncScheduler>; + friend class BackgroundSyncSchedulerTest; std::map<StoragePartitionImpl*, std::unique_ptr<base::OneShotTimer>>& GetDelayedProcessingInfoMap(blink::mojom::BackgroundSyncType sync_type); @@ -74,6 +75,12 @@ std::map<StoragePartitionImpl*, std::unique_ptr<base::OneShotTimer>> delayed_processing_info_periodic_; + std::map<blink::mojom::BackgroundSyncType, base::TimeTicks> + scheduled_wakeup_time_{ + {blink::mojom::BackgroundSyncType::ONE_SHOT, base::TimeTicks::Max()}, + {blink::mojom::BackgroundSyncType::PERIODIC, base::TimeTicks::Max()}, + }; + base::WeakPtrFactory<BackgroundSyncScheduler> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(BackgroundSyncScheduler);
diff --git a/content/browser/background_sync/background_sync_scheduler_unittest.cc b/content/browser/background_sync/background_sync_scheduler_unittest.cc index 6fa5d95..9d9bcc3 100644 --- a/content/browser/background_sync/background_sync_scheduler_unittest.cc +++ b/content/browser/background_sync/background_sync_scheduler_unittest.cc
@@ -93,6 +93,14 @@ return GetController()->GetBrowserWakeupDelay(sync_type); } + base::TimeTicks GetBrowserWakeupTime() { + auto* scheduler = BackgroundSyncScheduler::GetFor(&test_browser_context_); + DCHECK(scheduler); + + return scheduler + ->scheduled_wakeup_time_[blink::mojom::BackgroundSyncType::ONE_SHOT]; + } + void SetUp() override { original_client_ = SetBrowserClientForTesting(&browser_client_); } @@ -281,6 +289,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT), base::TimeDelta::FromSeconds(1)); + auto wakeup_time1 = GetBrowserWakeupTime(); CancelDelayedProcessing(GURL(kUrl_2), blink::mojom::BackgroundSyncType::ONE_SHOT); @@ -290,6 +299,7 @@ base::TimeDelta::FromMinutes(1)); EXPECT_GT(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(wakeup_time1, GetBrowserWakeupTime()); } #endif
diff --git a/content/browser/frame_host/navigation_request_browsertest.cc b/content/browser/frame_host/navigation_request_browsertest.cc index 1ff7285..38de5db 100644 --- a/content/browser/frame_host/navigation_request_browsertest.cc +++ b/content/browser/frame_host/navigation_request_browsertest.cc
@@ -1643,7 +1643,7 @@ EXPECT_TRUE(observer.has_committed()); EXPECT_TRUE(observer.is_error()); - EXPECT_EQ(net::ERR_DNS_TIMED_OUT, observer.net_error_code()); + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, observer.net_error_code()); EXPECT_EQ(net::ERR_DNS_TIMED_OUT, observer.resolve_error_info().error); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index ba06a9c..91922e42 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2603,12 +2603,6 @@ NOTIMPLEMENTED(); } -void RenderFrameHostImpl::DocumentOnLoadCompleted() { - // This message is only sent for top-level frames. TODO(avi): when frame tree - // mirroring works correctly, add a check here to enforce it. - delegate_->DocumentOnLoadCompleted(this); -} - void RenderFrameHostImpl::DidChangeActiveSchedulerTrackedFeatures( uint64_t features_mask) { renderer_reported_scheduler_tracked_features_ = features_mask; @@ -3647,6 +3641,14 @@ } } +void RenderFrameHostImpl::DocumentOnLoadCompleted() { + // This message is only sent for top-level frames. + // + // TODO(avi): when frame tree mirroring works correctly, add a check here + // to enforce it. + delegate_->DocumentOnLoadCompleted(this); +} + void RenderFrameHostImpl::OnForwardResourceTimingToParent( const ResourceTimingInfo& resource_timing) { // Don't forward the resource timing if this RFH is pending deletion. This can
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index c99cba0..a196d800 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1326,6 +1326,7 @@ void HandleAccessibilityFindInPageResult( blink::mojom::FindInPageResultAXParamsPtr params) override; void HandleAccessibilityFindInPageTermination() override; + void DocumentOnLoadCompleted() override; protected: friend class RenderFrameHostFactory; @@ -1596,7 +1597,6 @@ void CancelInitialHistoryLoad() override; void UpdateEncoding(const std::string& encoding) override; void FrameSizeChanged(const gfx::Size& frame_size) override; - void DocumentOnLoadCompleted() override; void DidAddMessageToConsole(blink::mojom::ConsoleMessageLevel log_level, const base::string16& message, int32_t line_no,
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index a0fb380..fb236fb4 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -831,6 +831,9 @@ void MediaSessionImpl::Initialize() { delegate_ = AudioFocusDelegate::Create(this); delegate_->MediaSessionInfoChanged(GetMediaSessionInfoSync()); + + DCHECK(web_contents()); + DidUpdateFaviconURL(web_contents()->GetFaviconURLs()); } AudioFocusDelegate::AudioFocusResult MediaSessionImpl::RequestSystemAudioFocus(
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index 2c14e47..482c1dd 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -34,8 +34,6 @@ #include "base/android/scoped_java_ref.h" #endif // defined(OS_ANDROID) -class MediaSessionImplBrowserTest; - namespace media { enum class MediaContentType; } // namespace media @@ -273,7 +271,7 @@ private: friend class content::WebContentsUserData<MediaSessionImpl>; - friend class ::MediaSessionImplBrowserTest; + friend class MediaSessionImplBrowserTest; friend class content::MediaSessionImplVisibilityBrowserTest; friend class content::AudioFocusManagerTest; friend class content::MediaSessionImplServiceRoutingTest;
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc index 237f43690..2133f30 100644 --- a/content/browser/media/session/media_session_impl_browsertest.cc +++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -17,9 +17,11 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_tick_clock.h" #include "build/build_config.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/session/audio_focus_delegate.h" #include "content/browser/media/session/mock_media_session_player_observer.h" #include "content/browser/media/session/mock_media_session_service_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/media_session.h" #include "content/public/browser/web_contents.h" #include "content/public/common/favicon_url.h" @@ -33,14 +35,6 @@ #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "testing/gmock/include/gmock/gmock.h" -using content::WebContents; -using content::MediaSession; -using content::MediaSessionImpl; -using content::AudioFocusDelegate; -using content::MediaSessionPlayerObserver; -using content::MediaSessionUmaHelper; -using content::MockMediaSessionPlayerObserver; - using media_session::mojom::AudioFocusType; using media_session::mojom::MediaPlaybackState; using media_session::mojom::MediaSessionInfo; @@ -61,9 +55,10 @@ constexpr gfx::Size kDefaultFaviconSize = gfx::Size(16, 16); -class MockAudioFocusDelegate : public AudioFocusDelegate { +class MockAudioFocusDelegate : public content::AudioFocusDelegate { public: - MockAudioFocusDelegate(MediaSessionImpl* media_session, bool async_mode) + MockAudioFocusDelegate(content::MediaSessionImpl* media_session, + bool async_mode) : media_session_(media_session), async_mode_(async_mode) {} MOCK_METHOD0(AbandonAudioFocus, void()); @@ -109,7 +104,7 @@ AudioFocusDelegate::AudioFocusResult sync_result_ = AudioFocusDelegate::AudioFocusResult::kSuccess; - MediaSessionImpl* media_session_; + content::MediaSessionImpl* media_session_; const bool async_mode_ = false; std::list<AudioFocusType> requests_; @@ -118,7 +113,9 @@ } // namespace -class MediaSessionImplBrowserTest : public content::ContentBrowserTest { +namespace content { + +class MediaSessionImplBrowserTest : public ContentBrowserTest { protected: MediaSessionImplBrowserTest() = default; @@ -220,9 +217,8 @@ void SystemStopDucking() { media_session_->StopDucking(); } void EnsureMediaSessionService() { - mock_media_session_service_.reset( - new NiceMock<content::MockMediaSessionServiceImpl>( - shell()->web_contents()->GetMainFrame())); + mock_media_session_service_.reset(new NiceMock<MockMediaSessionServiceImpl>( + shell()->web_contents()->GetMainFrame())); } void SetPlaybackState(blink::mojom::MediaSessionPlaybackState state) { @@ -277,8 +273,7 @@ protected: MediaSessionImpl* media_session_; MockAudioFocusDelegate* mock_audio_focus_delegate_; - std::unique_ptr<content::MockMediaSessionServiceImpl> - mock_media_session_service_; + std::unique_ptr<MockMediaSessionServiceImpl> mock_media_session_service_; DISALLOW_COPY_AND_ASSIGN(MediaSessionImplBrowserTest); }; @@ -2479,7 +2474,7 @@ } IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, MetadataWhenFileUrlScheme) { - base::FilePath path = content::GetTestFilePath(nullptr, "title1.html"); + base::FilePath path = GetTestFilePath(nullptr, "title1.html"); GURL file_url = net::FilePathToFileURL(path); EXPECT_TRUE(NavigateToURL(shell(), file_url)); @@ -2496,27 +2491,24 @@ valid_sizes.push_back(gfx::Size(100, 100)); valid_sizes.push_back(gfx::Size(200, 200)); - std::vector<content::FaviconURL> favicons; - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon1.png"), - content::FaviconURL::IconType::kInvalid, valid_sizes)); - favicons.push_back(content::FaviconURL( - GURL(), content::FaviconURL::IconType::kFavicon, valid_sizes)); - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon2.png"), - content::FaviconURL::IconType::kFavicon, std::vector<gfx::Size>())); - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon3.png"), - content::FaviconURL::IconType::kFavicon, valid_sizes)); - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon4.png"), - content::FaviconURL::IconType::kTouchIcon, valid_sizes)); - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon5.png"), - content::FaviconURL::IconType::kTouchPrecomposedIcon, valid_sizes)); - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon6.png"), - content::FaviconURL::IconType::kTouchIcon, std::vector<gfx::Size>())); + std::vector<FaviconURL> favicons; + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon1.png"), + FaviconURL::IconType::kInvalid, valid_sizes)); + favicons.push_back( + FaviconURL(GURL(), FaviconURL::IconType::kFavicon, valid_sizes)); + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon2.png"), + FaviconURL::IconType::kFavicon, + std::vector<gfx::Size>())); + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon3.png"), + FaviconURL::IconType::kFavicon, valid_sizes)); + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon4.png"), + FaviconURL::IconType::kTouchIcon, valid_sizes)); + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon5.png"), + FaviconURL::IconType::kTouchPrecomposedIcon, + valid_sizes)); + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon6.png"), + FaviconURL::IconType::kTouchIcon, + std::vector<gfx::Size>())); media_session_->DidUpdateFaviconURL(favicons); @@ -2545,7 +2537,7 @@ { media_session::test::MockMediaSessionMojoObserver observer(*media_session_); - media_session_->DidUpdateFaviconURL(std::vector<content::FaviconURL>()); + media_session_->DidUpdateFaviconURL(std::vector<FaviconURL>()); observer.WaitForExpectedImagesOfType( media_session::mojom::MediaSessionImageType::kSourceIcon, std::vector<media_session::MediaImage>()); @@ -2554,10 +2546,10 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UpdateFaviconURL_ClearOnNavigate) { - std::vector<content::FaviconURL> favicons; - favicons.push_back(content::FaviconURL( - GURL("https://www.example.org/favicon1.png"), - content::FaviconURL::IconType::kFavicon, std::vector<gfx::Size>())); + std::vector<FaviconURL> favicons; + favicons.push_back(FaviconURL(GURL("https://www.example.org/favicon1.png"), + FaviconURL::IconType::kFavicon, + std::vector<gfx::Size>())); media_session_->DidUpdateFaviconURL(favicons); @@ -2592,6 +2584,69 @@ } } +class MediaSessionFaviconBrowserTest : public ContentBrowserTest { + protected: + MediaSessionFaviconBrowserTest() = default; + + void SetUpOnMainThread() override { + ContentBrowserTest::SetUpOnMainThread(); + + host_resolver()->AddRule("*", "127.0.0.1"); + } +}; + +// Helper class that waits to receive a favicon from the renderer process. +class FaviconWaiter : public WebContentsObserver { + public: + explicit FaviconWaiter(WebContents* web_contents) + : WebContentsObserver(web_contents) {} + + void DidUpdateFaviconURL(const std::vector<FaviconURL>& candidates) override { + received_favicon_ = true; + run_loop_.Quit(); + } + + void Wait() { + if (received_favicon_) + return; + run_loop_.Run(); + } + + private: + bool received_favicon_ = false; + base::RunLoop run_loop_; +}; + +IN_PROC_BROWSER_TEST_F(MediaSessionFaviconBrowserTest, StartupInitalization) { + ASSERT_TRUE(embedded_test_server()->Start()); + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("example.com", "/title1.html"))); + + std::unique_ptr<FaviconWaiter> favicon_waiter( + new FaviconWaiter(shell()->web_contents())); + + // Insert the favicon dynamically. + ASSERT_TRUE(content::ExecuteScript( + shell()->web_contents(), + "let l = document.createElement('link'); " + "l.rel='icon'; l.type='image/png'; l.href='single_face.jpg'; " + "document.head.appendChild(l)")); + + // Wait until it's received by the browser process. + favicon_waiter->Wait(); + + // The MediaSession should be created with the favicon already available. + MediaSession* media_session = MediaSessionImpl::Get(shell()->web_contents()); + + media_session::MediaImage icon; + icon.src = embedded_test_server()->GetURL("example.com", "/single_face.jpg"); + icon.sizes.push_back({16, 16}); + + media_session::test::MockMediaSessionMojoObserver observer(*media_session); + observer.WaitForExpectedImagesOfType( + media_session::mojom::MediaSessionImageType::kSourceIcon, {icon}); +} + IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, PositionStateRouteWithTwoPlayers) { media_session::MediaPosition expected_position( @@ -2794,3 +2849,5 @@ observer.WaitForEmptyPosition(); } } + +} // namespace content
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index dce2284..2d567fe 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -483,10 +483,6 @@ [EnableIf=is_android] UpdateUserGestureCarryoverInfo(); - // Sent after the onload handler has been invoked for the document - // in this frame. Sent for top-level frames. - DocumentOnLoadCompleted(); - // Blink and JavaScript error messages to log to the console or debugger UI. DidAddMessageToConsole( blink.mojom.ConsoleMessageLevel log_level,
diff --git a/content/public/test/test_host_resolver.cc b/content/public/test/test_host_resolver.cc index 4c040d2..3d13d11 100644 --- a/content/public/test/test_host_resolver.cc +++ b/content/public/test/test_host_resolver.cc
@@ -45,6 +45,8 @@ // queries, rather than perform them. // If you really need to make an external DNS query, use // net::RuleBasedHostResolverProc and its AllowDirectLookup method. + // TODO(crbug.com/1040686): Simulate failure using ERR_NAME_NOT_RESOLVED + // rather than ERR_NOT_IMPLEMENTED. if (!local) { DVLOG(1) << "To avoid external dependencies, simulating failure for " "external DNS lookup of "
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index eb9eb19..6d4992c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4709,9 +4709,6 @@ } void RenderFrameImpl::DidHandleOnloadEvents() { - if (!frame_->Parent()) { - GetFrameHost()->DocumentOnLoadCompleted(); - } for (auto& observer : observers_) observer.DidHandleOnloadEvents(); }
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 1b345b7..ca587d4 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -170,6 +170,8 @@ "browser/web_test/test_info_extractor.h", "browser/web_test/web_test_background_fetch_delegate.cc", "browser/web_test/web_test_background_fetch_delegate.h", + "browser/web_test/web_test_blink_test_client.cc", + "browser/web_test/web_test_blink_test_client.h", "browser/web_test/web_test_bluetooth_adapter_provider.cc", "browser/web_test/web_test_bluetooth_adapter_provider.h", "browser/web_test/web_test_bluetooth_chooser_factory.cc",
diff --git a/content/shell/browser/web_test/blink_test_controller.cc b/content/shell/browser/web_test/blink_test_controller.cc index d07d6fd..594a585 100644 --- a/content/shell/browser/web_test/blink_test_controller.cc +++ b/content/shell/browser/web_test/blink_test_controller.cc
@@ -803,28 +803,9 @@ bool handled = true; IPC_BEGIN_MESSAGE_MAP(BlinkTestController, message) IPC_MESSAGE_HANDLER(BlinkTestHostMsg_PrintMessage, OnPrintMessage) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_PrintMessageToStderr, - OnPrintMessageToStderr) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_InitiateLayoutDump, - OnInitiateLayoutDump) IPC_MESSAGE_HANDLER(BlinkTestHostMsg_OverridePreferences, OnOverridePreferences) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_SetPopupBlockingEnabled, - OnSetPopupBlockingEnabled) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_NavigateSecondaryWindow, - OnNavigateSecondaryWindow) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_GoToOffset, OnGoToOffset) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_Reload, OnReload) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_LoadURLForFrame, OnLoadURLForFrame) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_CloseRemainingWindows, - OnCloseRemainingWindows) IPC_MESSAGE_HANDLER(BlinkTestHostMsg_ResetDone, OnResetDone) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_SetBluetoothManualChooser, - OnSetBluetoothManualChooser) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_GetBluetoothManualChooserEvents, - OnGetBluetoothManualChooserEvents) - IPC_MESSAGE_HANDLER(BlinkTestHostMsg_SendBluetoothManualChooserEvent, - OnSendBluetoothManualChooserEvent) IPC_MESSAGE_HANDLER(WebTestHostMsg_BlockThirdPartyCookies, OnBlockThirdPartyCookies) IPC_MESSAGE_UNHANDLED(handled = false)
diff --git a/content/shell/browser/web_test/blink_test_controller.h b/content/shell/browser/web_test/blink_test_controller.h index 4b62a9f..57dfac9 100644 --- a/content/shell/browser/web_test/blink_test_controller.h +++ b/content/shell/browser/web_test/blink_test_controller.h
@@ -184,6 +184,20 @@ return accumulated_web_test_runtime_flags_changes_; } + void OnInitiateLayoutDump(); + void OnResetDone(); + void OnPrintMessageToStderr(const std::string& message); + void OnReload(); + void OnCloseRemainingWindows(); + void OnGoToOffset(int offset); + void OnSetBluetoothManualChooser(bool enable); + void OnGetBluetoothManualChooserEvents(); + void OnSendBluetoothManualChooserEvent(const std::string& event, + const std::string& argument); + void OnSetPopupBlockingEnabled(bool block_popups); + void OnLoadURLForFrame(const GURL& url, const std::string& frame_name); + void OnNavigateSecondaryWindow(const GURL& url); + private: enum TestPhase { BETWEEN_TESTS, DURING_TEST, CLEAN_UP }; @@ -211,26 +225,13 @@ void OnAudioDump(const std::vector<unsigned char>& audio_dump); void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image); void OnTextDump(const std::string& dump); - void OnInitiateLayoutDump(); void OnDumpFrameLayoutResponse(int frame_tree_node_id, const std::string& dump); - void OnPrintMessageToStderr(const std::string& message); void OnPrintMessage(const std::string& message); void OnOverridePreferences(const WebPreferences& prefs); - void OnSetPopupBlockingEnabled(bool block_popups); void OnTestFinished(); - void OnNavigateSecondaryWindow(const GURL& url); - void OnGoToOffset(int offset); - void OnReload(); - void OnLoadURLForFrame(const GURL& url, const std::string& frame_name); void OnCaptureSessionHistory(); - void OnCloseRemainingWindows(); - void OnResetDone(); void OnLeakDetectionDone(const LeakDetector::LeakDetectionReport& report); - void OnSetBluetoothManualChooser(bool enable); - void OnGetBluetoothManualChooserEvents(); - void OnSendBluetoothManualChooserEvent(const std::string& event, - const std::string& argument); void OnBlockThirdPartyCookies(bool block); mojo::AssociatedRemote<mojom::WebTestControl>& GetWebTestControlRemote( RenderFrameHost* frame);
diff --git a/content/shell/browser/web_test/web_test_blink_test_client.cc b/content/shell/browser/web_test/web_test_blink_test_client.cc new file mode 100644 index 0000000..b23aae5 --- /dev/null +++ b/content/shell/browser/web_test/web_test_blink_test_client.cc
@@ -0,0 +1,72 @@ +// Copyright 2020 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/shell/browser/web_test/web_test_blink_test_client.h" + +#include <memory> +#include <string> +#include <utility> + +#include "content/shell/browser/web_test/blink_test_controller.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace content { + +// static +void WebTestBlinkTestClient::Create( + mojo::PendingReceiver<mojom::WebTestClient> receiver) { + mojo::MakeSelfOwnedReceiver(std::make_unique<WebTestBlinkTestClient>(), + std::move(receiver)); +} + +void WebTestBlinkTestClient::InitiateLayoutDump() { + BlinkTestController::Get()->OnInitiateLayoutDump(); +} + +void WebTestBlinkTestClient::PrintMessageToStderr(const std::string& message) { + BlinkTestController::Get()->OnPrintMessageToStderr(message); +} + +void WebTestBlinkTestClient::Reload() { + BlinkTestController::Get()->OnReload(); +} + +void WebTestBlinkTestClient::CloseRemainingWindows() { + BlinkTestController::Get()->OnCloseRemainingWindows(); +} + +void WebTestBlinkTestClient::GoToOffset(int offset) { + BlinkTestController::Get()->OnGoToOffset(offset); +} + +void WebTestBlinkTestClient::SendBluetoothManualChooserEvent( + const std::string& event, + const std::string& argument) { + BlinkTestController::Get()->OnSendBluetoothManualChooserEvent(event, + argument); +} + +void WebTestBlinkTestClient::SetBluetoothManualChooser(bool enable) { + BlinkTestController::Get()->OnSetBluetoothManualChooser(enable); +} + +void WebTestBlinkTestClient::GetBluetoothManualChooserEvents() { + BlinkTestController::Get()->OnGetBluetoothManualChooserEvents(); +} + +void WebTestBlinkTestClient::SetPopupBlockingEnabled(bool block_popups) { + BlinkTestController::Get()->OnSetPopupBlockingEnabled(block_popups); +} + +void WebTestBlinkTestClient::LoadURLForFrame(const GURL& url, + const std::string& frame_name) { + BlinkTestController::Get()->OnLoadURLForFrame(url, frame_name); +} + +void WebTestBlinkTestClient::NavigateSecondaryWindow(const GURL& url) { + BlinkTestController::Get()->OnNavigateSecondaryWindow(url); +} + +} // namespace content
diff --git a/content/shell/browser/web_test/web_test_blink_test_client.h b/content/shell/browser/web_test/web_test_blink_test_client.h new file mode 100644 index 0000000..bea0c79 --- /dev/null +++ b/content/shell/browser/web_test/web_test_blink_test_client.h
@@ -0,0 +1,42 @@ +// Copyright 2020 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_SHELL_BROWSER_WEB_TEST_WEB_TEST_BLINK_TEST_CLIENT_H_ +#define CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_BLINK_TEST_CLIENT_H_ + +#include "base/macros.h" +#include "content/shell/common/web_test.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "url/gurl.h" + +namespace content { + +class WebTestBlinkTestClient : public mojom::WebTestClient { + public: + WebTestBlinkTestClient() = default; + ~WebTestBlinkTestClient() override = default; + + static void Create(mojo::PendingReceiver<mojom::WebTestClient> receiver); + + private: + // WebTestClient implementation. + void InitiateLayoutDump() override; + void PrintMessageToStderr(const std::string& message) override; + void Reload() override; + void CloseRemainingWindows() override; + void GoToOffset(int offset) override; + void SendBluetoothManualChooserEvent(const std::string& event, + const std::string& argument) override; + void SetBluetoothManualChooser(bool enable) override; + void GetBluetoothManualChooserEvents() override; + void SetPopupBlockingEnabled(bool block_popups) override; + void LoadURLForFrame(const GURL& url, const std::string& frame_name) override; + void NavigateSecondaryWindow(const GURL& url) override; + + DISALLOW_COPY_AND_ASSIGN(WebTestBlinkTestClient); +}; + +} // namespace content + +#endif // CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_BLINK_TEST_CLIENT_H_
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.cc b/content/shell/browser/web_test/web_test_content_browser_client.cc index 62ae14ae..4497b2d0 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.cc +++ b/content/shell/browser/web_test/web_test_content_browser_client.cc
@@ -30,6 +30,7 @@ #include "content/shell/browser/web_test/fake_bluetooth_chooser.h" #include "content/shell/browser/web_test/fake_bluetooth_chooser_factory.h" #include "content/shell/browser/web_test/mojo_web_test_helper.h" +#include "content/shell/browser/web_test/web_test_blink_test_client.h" #include "content/shell/browser/web_test/web_test_bluetooth_fake_adapter_setter_impl.h" #include "content/shell/browser/web_test/web_test_browser_context.h" #include "content/shell/browser/web_test/web_test_browser_main_parts.h" @@ -156,6 +157,9 @@ base::BindRepeating(&WebTestBluetoothFakeAdapterSetterImpl::Create), ui_task_runner); + registry->AddInterface(base::BindRepeating(&WebTestBlinkTestClient::Create), + ui_task_runner); + registry->AddInterface(base::BindRepeating(&bluetooth::FakeBluetooth::Create), ui_task_runner); // This class outlives |render_process_host|, which owns |registry|. Since
diff --git a/content/shell/common/web_test.mojom b/content/shell/common/web_test.mojom index bab5d6f..bcccfbf 100644 --- a/content/shell/common/web_test.mojom +++ b/content/shell/common/web_test.mojom
@@ -49,6 +49,7 @@ gfx.mojom.Rect selection_rect; }; +// Blink test messages sent from the browser process to the renderer. interface WebTestControl { CaptureDump() => (WebTestDump result); @@ -85,3 +86,49 @@ // Reply Bluetooth manual events to BlinkTestRunner. ReplyBluetoothManualChooserEvents(array<string> events); }; + +// Blink test messages sent from the renderer process to the browser. +interface WebTestClient { + // Asks the browser process to perform a layout dump spanning all the + // (potentially cross-process) frames. This goes through multiple + // WebTestControl.DumpFrameLayout calls and ends with sending of + // BlinkTestMsg_LayoutDumpCompleted. + InitiateLayoutDump(); + + // Add a message to stderr (not saved to expected output files, for debugging + // only). + PrintMessageToStderr(string message); + + // Trigger a reload navigation on the main WebView. + Reload(); + + // Invoked when the embedder should close all but the main WebView. + CloseRemainingWindows(); + + // Trigger a GoToOffset navigation on the main WebView. + GoToOffset(int32 offset); + + // Calls the BluetoothChooser::EventHandler with the arguments here. Valid + // event strings are: + // * "cancel" - simulates the user canceling the chooser. + // * "select" - simulates the user selecting a device whose device ID is in + // |argument|. + SendBluetoothManualChooserEvent(string event, string argument); + + // If |enable| is true makes the Bluetooth chooser record its input and wait + // for instructions from the test program on how to proceed. Otherwise + // fall backs to the browser's default chooser. + SetBluetoothManualChooser(bool enable); + + // Returns the events recorded since the last call to this function. + GetBluetoothManualChooserEvents(); + + // Manages the popup blocking setting to used for web tests. + SetPopupBlockingEnabled(bool block_popups); + + // Trigger a loadURL navigation on the main WebView. + LoadURLForFrame(url.mojom.Url url, string frame_name); + + // Naivgate a URL on the secondary window. + NavigateSecondaryWindow(url.mojom.Url url); +};
diff --git a/content/shell/common/web_test/blink_test_messages.h b/content/shell/common/web_test/blink_test_messages.h index 3bccc2b..5080ab24 100644 --- a/content/shell/common/web_test/blink_test_messages.h +++ b/content/shell/common/web_test/blink_test_messages.h
@@ -15,37 +15,11 @@ #define IPC_MESSAGE_START BlinkTestMsgStart -// Asks the browser process to perform a layout dump spanning all the -// (potentially cross-process) frames. This goes through multiple -// WebTestControl.DumpFrameLayout calls and ends with sending of -// LayoutDumpCompleted. -// TODO(crbug.com/1039247): LayoutDumpCompleted call should be removed and the -// callback should happen part of LayoutDump call on the host interface. -IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_InitiateLayoutDump) - IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_ResetDone) // WebTestDelegate related. IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_OverridePreferences, content::WebPreferences /* preferences */) IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_PrintMessage, std::string /* message */) -IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_PrintMessageToStderr, - std::string /* message */) -IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_NavigateSecondaryWindow, GURL /* url */) -IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_GoToOffset, int /* offset */) -IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_Reload) -IPC_MESSAGE_ROUTED2(BlinkTestHostMsg_LoadURLForFrame, - GURL /* url */, - std::string /* frame_name */) -IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_CloseRemainingWindows) - -IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_SetBluetoothManualChooser, - bool /* enable */) -IPC_MESSAGE_ROUTED0(BlinkTestHostMsg_GetBluetoothManualChooserEvents) -IPC_MESSAGE_ROUTED2(BlinkTestHostMsg_SendBluetoothManualChooserEvent, - std::string /* event */, - std::string /* argument */) -IPC_MESSAGE_ROUTED1(BlinkTestHostMsg_SetPopupBlockingEnabled, - bool /* block_popups */) #endif // CONTENT_SHELL_COMMON_WEB_TEST_BLINK_TEST_MESSAGES_H_
diff --git a/content/shell/renderer/web_test/blink_test_runner.cc b/content/shell/renderer/web_test/blink_test_runner.cc index 2e88791..4d82037 100644 --- a/content/shell/renderer/web_test/blink_test_runner.cc +++ b/content/shell/renderer/web_test/blink_test_runner.cc
@@ -182,7 +182,7 @@ } void BlinkTestRunner::PrintMessageToStderr(const std::string& message) { - Send(new BlinkTestHostMsg_PrintMessageToStderr(routing_id(), message)); + GetWebTestClientRemote().PrintMessageToStderr(message); } void BlinkTestRunner::PrintMessage(const std::string& message) { @@ -260,8 +260,7 @@ } void BlinkTestRunner::SetPopupBlockingEnabled(bool block_popups) { - Send( - new BlinkTestHostMsg_SetPopupBlockingEnabled(routing_id(), block_popups)); + GetWebTestClientRemote().SetPopupBlockingEnabled(block_popups); } void BlinkTestRunner::UseUnfortunateSynchronousResizeMode(bool enable) { @@ -289,7 +288,7 @@ } void BlinkTestRunner::NavigateSecondaryWindow(const GURL& url) { - Send(new BlinkTestHostMsg_NavigateSecondaryWindow(routing_id(), url)); + GetWebTestClientRemote().NavigateSecondaryWindow(url); } void BlinkTestRunner::InspectSecondaryWindow() { @@ -358,20 +357,19 @@ } void BlinkTestRunner::SetBluetoothManualChooser(bool enable) { - Send(new BlinkTestHostMsg_SetBluetoothManualChooser(routing_id(), enable)); + GetWebTestClientRemote().SetBluetoothManualChooser(enable); } void BlinkTestRunner::GetBluetoothManualChooserEvents( base::OnceCallback<void(const std::vector<std::string>&)> callback) { get_bluetooth_events_callbacks_.push_back(std::move(callback)); - Send(new BlinkTestHostMsg_GetBluetoothManualChooserEvents(routing_id())); + GetWebTestClientRemote().GetBluetoothManualChooserEvents(); } void BlinkTestRunner::SendBluetoothManualChooserEvent( const std::string& event, const std::string& argument) { - Send(new BlinkTestHostMsg_SendBluetoothManualChooserEvent(routing_id(), event, - argument)); + GetWebTestClientRemote().SendBluetoothManualChooserEvent(event, argument); } void BlinkTestRunner::SetFocus(blink::WebView* web_view, bool focus) { @@ -527,7 +525,7 @@ // TODO(vmpstr): Since CaptureDump is called from the browser, we can be // smart and move this logic directly to the browser. waiting_for_layout_dump_results_ = true; - Send(new BlinkTestHostMsg_InitiateLayoutDump(routing_id())); + GetWebTestClientRemote().InitiateLayoutDump(); } } @@ -588,7 +586,7 @@ } void BlinkTestRunner::CloseRemainingWindows() { - Send(new BlinkTestHostMsg_CloseRemainingWindows(routing_id())); + GetWebTestClientRemote().CloseRemainingWindows(); } void BlinkTestRunner::DeleteAllCookies() { @@ -600,16 +598,16 @@ } void BlinkTestRunner::GoToOffset(int offset) { - Send(new BlinkTestHostMsg_GoToOffset(routing_id(), offset)); + GetWebTestClientRemote().GoToOffset(offset); } void BlinkTestRunner::Reload() { - Send(new BlinkTestHostMsg_Reload(routing_id())); + GetWebTestClientRemote().Reload(); } void BlinkTestRunner::LoadURLForFrame(const WebURL& url, const std::string& frame_name) { - Send(new BlinkTestHostMsg_LoadURLForFrame(routing_id(), url, frame_name)); + GetWebTestClientRemote().LoadURLForFrame(url, frame_name); } bool BlinkTestRunner::AllowExternalPages() { @@ -740,6 +738,14 @@ return *bluetooth_fake_adapter_setter_; } +mojom::WebTestClient& BlinkTestRunner::GetWebTestClientRemote() { + if (!web_test_client_remote_) { + RenderThread::Get()->BindHostReceiver( + web_test_client_remote_.BindNewPipeAndPassReceiver()); + } + return *web_test_client_remote_; +} + void BlinkTestRunner::OnSetupSecondaryRenderer() { DCHECK(!is_main_window_);
diff --git a/content/shell/renderer/web_test/blink_test_runner.h b/content/shell/renderer/web_test/blink_test_runner.h index abf4eba..0266180 100644 --- a/content/shell/renderer/web_test/blink_test_runner.h +++ b/content/shell/renderer/web_test/blink_test_runner.h
@@ -180,6 +180,9 @@ mojo::Remote<mojom::WebTestBluetoothFakeAdapterSetter> bluetooth_fake_adapter_setter_; + mojom::WebTestClient& GetWebTestClientRemote(); + mojo::Remote<mojom::WebTestClient> web_test_client_remote_; + test_runner::TestPreferences prefs_; mojom::ShellTestConfigurationPtr test_config_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index d4deef7..a7dfe19 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1081,6 +1081,7 @@ "//components/discardable_memory/client", "//components/discardable_memory/common", "//components/discardable_memory/service", + "//components/favicon/content", "//components/network_session_configurator/common", "//components/payments/mojom", "//components/services/quarantine:test_support",
diff --git a/content/test/data/gpu/pixel_reflected_div.html b/content/test/data/gpu/pixel_reflected_div.html new file mode 100644 index 0000000..a401a200 --- /dev/null +++ b/content/test/data/gpu/pixel_reflected_div.html
@@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta name="viewport" content="initial-scale=1"> +<title>A div with its reflection below which results in multiple render passes</title> +<style type="text/css"> +body { + margin: 0px auto; +} + +/* Both will-change and -webkit-box-reflect are needed to ensure multiple render + passes. */ +#main { + position: absolute; + background-color: #FF8000; + width: 100px; + height: 400px; + will-change: transform; + -webkit-box-reflect: below 100px; +} +</style> +<script> +var frame = 0; + +// It's necessary to do an animation prior to sending SUCCESS in order to +// reliably reproduce https://crbug.com/1033279. +function animate() { + frame++; + document.getElementById('main').style.top = '-' + frame + 'px'; + if (frame == 300) { + domAutomationController.send("SUCCESS"); + return; + } + // Use setTimeout() because window.requestAnimationFrame() doesn't reliably + // reproduce https://crbug.com/1033279. + setTimeout(animate, 20); +} +</script> +</head> +<body onload="animate()"> +<div id="main"></div> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 01271d4..9b3f3a5 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -151,6 +151,31 @@ test_rect=[20, 20, 370, 370]), PixelTestPage( + 'pixel_reflected_div.html', + base_name + '_ReflectedDiv', + test_rect=[0, 0, 100, 300], + expected_colors=[ + { + 'comment': 'inside original div, orange', + 'location': [0, 0], + 'size': [100, 99], + 'color': [255, 128, 0], + }, + { + 'comment': 'outside both div and reflection, in between, white', + 'location': [0, 101], + 'size': [100, 98], + 'color': [255, 255, 255], + }, + { + 'comment': 'inside reflection, orange', + 'location': [0, 201], + 'size': [100, 99], + 'color': [255, 128, 0], + } + ]), + + PixelTestPage( 'pixel_canvas2d.html', base_name + '_Canvas2DRedBox', test_rect=[0, 0, 300, 300]),
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index ea78514..ffc3aca7 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -552,6 +552,8 @@ crbug.com/957807 [ chromeos ] conformance/uniforms/uniform-samplers-test.html [ Skip ] crbug.com/957807 [ chromeos ] deqp/data/gles2/shaders/conversions.html [ Skip ] crbug.com/957807 [ chromeos ] deqp/data/gles2/shaders/swizzles.html [ Skip ] +# There is a crash, likely in this test, causing all following tests in the shard to fail. +crbug.com/1043953 [ chromeos ] conformance/textures/misc/texture-size-limit.html [ Skip ] # ChromeOS: AMD crbug.com/995652 [ chromeos amd ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Skip ]
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index f384d4159..cc1f1ff 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -168,8 +168,6 @@ void CancelInitialHistoryLoad() override {} - void DocumentOnLoadCompleted() override {} - void UpdateEncoding(const std::string& encoding_name) override {} void FrameSizeChanged(const gfx::Size& frame_size) override {}
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher.cc b/extensions/browser/api/declarative_net_request/composite_matcher.cc index 9db8fab..eed6e9f 100644 --- a/extensions/browser/api/declarative_net_request/composite_matcher.cc +++ b/extensions/browser/api/declarative_net_request/composite_matcher.cc
@@ -9,6 +9,8 @@ #include <utility> #include "base/metrics/histogram_macros.h" +#include "base/time/time.h" +#include "base/timer/elapsed_timer.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" #include "extensions/browser/api/declarative_net_request/request_action.h" #include "extensions/browser/api/declarative_net_request/request_params.h" @@ -44,6 +46,22 @@ return true; } +// Helper to log the time taken in CompositeMatcher::GetBeforeRequestAction. +class ScopedGetBeforeRequestActionTimer { + public: + ScopedGetBeforeRequestActionTimer() = default; + ~ScopedGetBeforeRequestActionTimer() { + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime." + "SingleExtension2", + timer_.Elapsed(), base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromMilliseconds(50), 50); + } + + private: + base::ElapsedTimer timer_; +}; + } // namespace ActionInfo::ActionInfo(base::Optional<RequestAction> action, @@ -92,10 +110,7 @@ ActionInfo CompositeMatcher::GetBeforeRequestAction( const RequestParams& params, PageAccess page_access) const { - // TODO(karandeepb): change this to report time in micro-seconds. - SCOPED_UMA_HISTOGRAM_TIMER( - "Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime." - "SingleExtension"); + ScopedGetBeforeRequestActionTimer timer; bool notify_request_withheld = false; for (const auto& matcher : matchers_) {
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc index f3b58de..9c021db 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -13,6 +13,8 @@ #include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "base/stl_util.h" +#include "base/time/time.h" +#include "base/timer/elapsed_timer.h" #include "components/web_cache/browser/web_cache_manager.h" #include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/constants.h" @@ -167,6 +169,21 @@ request.render_process_id, request.frame_id, extension_id); } +// Helper to log the time taken in RulesetManager::EvaluateRequestInternal. +class ScopedEvaluateRequestTimer { + public: + ScopedEvaluateRequestTimer() = default; + ~ScopedEvaluateRequestTimer() { + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3", + timer_.Elapsed(), base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromMilliseconds(50), 50); + } + + private: + base::ElapsedTimer timer_; +}; + } // namespace RulesetManager::RulesetManager(content::BrowserContext* browser_context) @@ -451,8 +468,7 @@ if (rulesets_.empty()) return actions; - SCOPED_UMA_HISTOGRAM_TIMER( - "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"); + ScopedEvaluateRequestTimer timer; const RequestParams params(request); const int tab_id = request.frame_data.tab_id;
diff --git a/extensions/browser/api/dns/dns_apitest.cc b/extensions/browser/api/dns/dns_apitest.cc index 4e88dd6..10974fc 100644 --- a/extensions/browser/api/dns/dns_apitest.cc +++ b/extensions/browser/api/dns/dns_apitest.cc
@@ -128,7 +128,7 @@ network::DnsLookupResult result2 = network::BlockingDnsLookup(network_context, host_port_pair, std::move(params), net::NetworkIsolationKey()); - EXPECT_EQ(net::ERR_DNS_CACHE_MISS, result2.error); + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, result2.error); } IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsExtension) {
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc index 2f8fa8f..c71e5de 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_apitest.cc
@@ -132,7 +132,7 @@ network::DnsLookupResult result2 = network::BlockingDnsLookup(network_context, host_port_pair, std::move(params), net::NetworkIsolationKey()); - EXPECT_EQ(net::ERR_DNS_CACHE_MISS, result2.error); + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, result2.error); } IN_PROC_BROWSER_TEST_F(SocketsTcpApiTest, SocketTcpExtensionTLS) {
diff --git a/extensions/browser/computed_hashes.cc b/extensions/browser/computed_hashes.cc index 1c3bf0c..4139bb15 100644 --- a/extensions/browser/computed_hashes.cc +++ b/extensions/browser/computed_hashes.cc
@@ -45,6 +45,54 @@ } // namespace +ComputedHashes::Data::Data() = default; +ComputedHashes::Data::~Data() = default; +ComputedHashes::Data::Data(ComputedHashes::Data&& data) = default; +ComputedHashes::Data& ComputedHashes::Data::operator=( + ComputedHashes::Data&& data) = default; + +ComputedHashes::Data::HashInfo::HashInfo(int block_size, + std::vector<std::string> hashes, + base::FilePath relative_unix_path) + : block_size(block_size), + hashes(std::move(hashes)), + relative_unix_path(std::move(relative_unix_path)) {} +ComputedHashes::Data::HashInfo::~HashInfo() = default; + +ComputedHashes::Data::HashInfo::HashInfo(ComputedHashes::Data::HashInfo&&) = + default; +ComputedHashes::Data::HashInfo& ComputedHashes::Data::HashInfo::operator=( + ComputedHashes::Data::HashInfo&&) = default; + +const ComputedHashes::Data::HashInfo* ComputedHashes::Data::GetItem( + const base::FilePath& relative_path) const { + base::FilePath::StringType canonicalized_path = + content_verifier_utils::CanonicalizeRelativePath(relative_path); + auto iter = items_.find(canonicalized_path); + return iter == items_.end() ? nullptr : &iter->second; +} + +void ComputedHashes::Data::Add(const base::FilePath& relative_path, + int block_size, + std::vector<std::string> hashes) { + base::FilePath::StringType canonicalized_path = + content_verifier_utils::CanonicalizeRelativePath(relative_path); + items_.insert( + std::make_pair(canonicalized_path, + HashInfo(block_size, std::move(hashes), + relative_path.NormalizePathSeparatorsTo('/')))); +} + +void ComputedHashes::Data::Remove(const base::FilePath& relative_path) { + base::FilePath::StringType canonicalized_path = + content_verifier_utils::CanonicalizeRelativePath(relative_path); + items_.erase(canonicalized_path); +} + +const std::map<base::FilePath::StringType, ComputedHashes::Data::HashInfo>& +ComputedHashes::Data::items() const { + return items_; +} ComputedHashes::ComputedHashes(Data&& data) : data_(std::move(data)) {} ComputedHashes::~ComputedHashes() = default; @@ -102,8 +150,6 @@ base::FilePath relative_path = base::FilePath::FromUTF8Unsafe(*relative_path_utf8); - relative_path = relative_path.NormalizePathSeparatorsTo('/'); - std::vector<std::string> hashes; for (const base::Value& value : block_hashes->GetList()) { @@ -116,7 +162,7 @@ if (!base::Base64Decode(encoded, decoded)) return base::nullopt; } - data[relative_path] = HashInfo(*block_size, std::move(hashes)); + data.Add(relative_path, *block_size, std::move(hashes)); } uma_recorder.RecordSuccess(); return ComputedHashes(std::move(data)); @@ -144,23 +190,21 @@ // Now iterate over all the paths in sorted order and compute the block hashes // for each one. - std::map<base::FilePath, HashInfo> data; + Data data; for (const auto& full_path : paths) { if (is_cancelled && is_cancelled.Run()) return base::nullopt; - base::FilePath relative_unix_path; - extension_root.AppendRelativePath(full_path, &relative_unix_path); - relative_unix_path = relative_unix_path.NormalizePathSeparatorsTo('/'); + base::FilePath relative_path; + extension_root.AppendRelativePath(full_path, &relative_path); - if (!should_compute_hashes_for_resource.Run(relative_unix_path)) + if (!should_compute_hashes_for_resource.Run(relative_path)) continue; base::Optional<std::vector<std::string>> hashes = - ComputeAndCheckResourceHash(full_path, relative_unix_path, block_size); + ComputeAndCheckResourceHash(full_path, block_size); if (hashes) - data[relative_unix_path] = - HashInfo(block_size, std::move(hashes.value())); + data.Add(relative_path, block_size, std::move(hashes.value())); } return data; @@ -169,50 +213,12 @@ bool ComputedHashes::GetHashes(const base::FilePath& relative_path, int* block_size, std::vector<std::string>* hashes) const { - base::FilePath path = relative_path.NormalizePathSeparatorsTo('/'); - // TODO(lazyboy): Align treatment of |data_| with that of - // VerifiedContents::root_hashes_, so that we don't have to perform the linear - // lookup below. - auto find_data = [&](const base::FilePath& normalized_path) { - auto i = data_.find(normalized_path); - if (i == data_.end() && - !content_verifier_utils::IsFileAccessCaseSensitive()) { - // If we didn't find the entry using exact match, it's possible the - // developer is using a path with some letters in the incorrect case, - // which happens to work on windows/osx. So try doing a linear scan to - // look for a case-insensitive match. In practice most extensions don't - // have that big a list of files so the performance penalty is probably - // not too big here. Also for crbug.com/29941 we plan to start warning - // developers when they are making this mistake, since their extension - // will be broken on linux/chromeos. - for (i = data_.begin(); i != data_.end(); ++i) { - const base::FilePath& entry = i->first; - if (base::FilePath::CompareEqualIgnoreCase(entry.value(), - normalized_path.value())) { - break; - } - } - } - return i; - }; - auto i = find_data(path); - if (i == data_.end() && - content_verifier_utils::IsDotSpaceFilenameSuffixIgnored()) { - base::FilePath::StringType trimmed_path_value; - // Also search for path with (.| )+ suffix trimmed as they are ignored in - // windows. This matches the canonicalization behavior of - // VerifiedContents::Create. - if (content_verifier_utils::TrimDotSpaceSuffix(path.value(), - &trimmed_path_value)) { - i = find_data(base::FilePath(trimmed_path_value)); - } - } - if (i == data_.end()) + const Data::HashInfo* hash_info = data_.GetItem(relative_path); + if (!hash_info) return false; - const HashInfo& info = i->second; - *block_size = info.first; - *hashes = info.second; + *block_size = hash_info->block_size; + *hashes = hash_info->hashes; return true; } @@ -222,10 +228,10 @@ return false; base::Value file_list(base::Value::Type::LIST); - for (const auto& resource_info : data_) { - const base::FilePath& relative_path = resource_info.first; - int block_size = resource_info.second.first; - const std::vector<std::string>& hashes = resource_info.second.second; + for (const auto& resource_info : data_.items()) { + const Data::HashInfo& hash_info = resource_info.second; + int block_size = hash_info.block_size; + const std::vector<std::string>& hashes = hash_info.hashes; base::Value::ListStorage block_hashes; block_hashes.reserve(hashes.size()); @@ -236,9 +242,8 @@ } base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey( - computed_hashes::kPathKey, - relative_path.NormalizePathSeparatorsTo('/').AsUTF8Unsafe()); + dict.SetStringKey(computed_hashes::kPathKey, + hash_info.relative_unix_path.AsUTF8Unsafe()); dict.SetIntKey(computed_hashes::kBlockSizeKey, block_size); dict.SetKey(computed_hashes::kBlockHashesKey, base::Value(std::move(block_hashes))); @@ -298,7 +303,6 @@ base::Optional<std::vector<std::string>> ComputedHashes::ComputeAndCheckResourceHash( const base::FilePath& full_path, - const base::FilePath& relative_unix_path, int block_size) { std::string contents; if (!base::ReadFileToString(full_path, &contents)) {
diff --git a/extensions/browser/computed_hashes.h b/extensions/browser/computed_hashes.h index 950f3d0..7e4e7ca 100644 --- a/extensions/browser/computed_hashes.h +++ b/extensions/browser/computed_hashes.h
@@ -13,12 +13,9 @@ #include <vector> #include "base/callback.h" +#include "base/files/file_path.h" #include "base/optional.h" -namespace base { -class FilePath; -} - namespace extensions { using IsCancelledCallback = base::RepeatingCallback<bool(void)>; @@ -29,8 +26,60 @@ // computed over the files inside an extension. class ComputedHashes { public: - using HashInfo = std::pair<int, std::vector<std::string>>; - using Data = std::map<base::FilePath, HashInfo>; + // Hashes data for relative paths. + // System specific path canonicalization is taken care of inside this class. + class Data { + public: + struct HashInfo { + int block_size; + std::vector<std::string> hashes; + // The relative unix style path. + // Note that we use canonicalized paths as keys to HashInfo's container + // |items_|. + // + // TODO(http://crbug.com/796395#c28): Consider removing this once + // ContentVerifier::ShouldVerifyAnyPaths works with canonicalized relative + // paths. + base::FilePath relative_unix_path; + HashInfo(int block_size, + std::vector<std::string> hashes, + base::FilePath relative_unix_path); + ~HashInfo(); + + HashInfo(const HashInfo&) = delete; + HashInfo& operator=(const HashInfo&) = delete; + HashInfo(HashInfo&&); + HashInfo& operator=(HashInfo&&); + }; + using Items = std::map<base::FilePath::StringType, HashInfo>; + + Data(); + ~Data(); + + Data(const Data&) = delete; + Data& operator=(const Data&) = delete; + Data(Data&&); + Data& operator=(Data&&); + + // For |relative_path|, adds hash information with |block_size| and + // |hashes|. + // Note that |relative_path| will be canonicalized. + void Add(const base::FilePath& relative_path, + int block_size, + std::vector<std::string> hashes); + + // Removes the item that corresponds to |relative_path|. + void Remove(const base::FilePath& relative_path); + + // Returns HashInfo* for |relative_path| or nullptr if not found. + const HashInfo* GetItem(const base::FilePath& relative_path) const; + + const Items& items() const; + + private: + // All items, stored by canonicalized FilePath::StringType key. + Items items_; + }; explicit ComputedHashes(Data&& data); ComputedHashes(const ComputedHashes&) = delete; @@ -79,7 +128,6 @@ // added to computed_hashes.json for this resource. static base::Optional<std::vector<std::string>> ComputeAndCheckResourceHash( const base::FilePath& full_path, - const base::FilePath& relative_unix_path, int block_size); Data data_;
diff --git a/extensions/browser/computed_hashes_unittest.cc b/extensions/browser/computed_hashes_unittest.cc index 95bab6f..02aa0ca 100644 --- a/extensions/browser/computed_hashes_unittest.cc +++ b/extensions/browser/computed_hashes_unittest.cc
@@ -43,10 +43,8 @@ base::FilePath computed_hashes_path = scoped_dir.GetPath().AppendASCII("computed_hashes.json"); extensions::ComputedHashes::Data computed_hashes_data; - for (const auto& info : hash_infos) { - computed_hashes_data[info.path] = - extensions::ComputedHashes::HashInfo(info.block_size, info.hashes); - } + for (const auto& info : hash_infos) + computed_hashes_data.Add(info.path, info.block_size, info.hashes); if (!extensions::ComputedHashes(std::move(computed_hashes_data)) .WriteToFile(computed_hashes_path)) {
diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h index 972c093..f39849f5 100644 --- a/extensions/browser/content_verifier.h +++ b/extensions/browser/content_verifier.h
@@ -39,6 +39,25 @@ // Used for managing overall content verification - both fetching content // hashes as needed, and supplying job objects to verify file contents as they // are read. +// +// Some notes about extension resource paths: +// An extension resource path is a path relative to it's extension root +// directory. For the purposes of content verification system, there can be +// several transformations of the relative path: +// 1. Relative path: Relative path as is. This is base::FilePath that simply +// is the relative path of the resource. +// 2. Relative unix path: Some underlying parts of content-verification +// require uniform separator, we use '/' as separator so it is effectively +// unix style. Note that this is a reversible transformation. +// 3. Canonicalized relative_path: Canonicalized paths are used as keys of +// maps within VerifiedContents and ComputedHashes. This takes care of OS +// specific file access issues: +// - windows/mac is case insensitive while accessing files. +// - windows ignores (.| )+ suffixes in filename while accessing a file. +// Canonicalization consists of normalizing the separators, lower casing +// the filepath in case-insensitive systems and trimming ignored suffixes +// if appropriate. +// See content_verifier_utils::CanonicalizeRelativePath() for details. class ContentVerifier : public base::RefCountedThreadSafe<ContentVerifier>, public ExtensionRegistryObserver { public:
diff --git a/extensions/browser/content_verifier/content_hash.cc b/extensions/browser/content_verifier/content_hash.cc index 45d6773..692275f 100644 --- a/extensions/browser/content_verifier/content_hash.cc +++ b/extensions/browser/content_verifier/content_hash.cc
@@ -329,14 +329,15 @@ std::set<base::FilePath> mismatched_hashes; - for (const auto& resource_info : *computed_hashes_data) { - const base::FilePath& relative_unix_path = resource_info.first; - const std::vector<std::string>& hashes = resource_info.second.second; + for (const auto& resource_info : computed_hashes_data->items()) { + const ComputedHashes::Data::HashInfo& hash_info = resource_info.second; - std::string root = - ComputeTreeHashRoot(hashes, block_size_ / crypto::kSHA256Length); - if (!verified_contents_->TreeHashRootEquals(relative_unix_path, root)) - mismatched_hashes.insert(relative_unix_path); + std::string root = ComputeTreeHashRoot(hash_info.hashes, + block_size_ / crypto::kSHA256Length); + if (!verified_contents_->TreeHashRootEquals(hash_info.relative_unix_path, + root)) { + mismatched_hashes.insert(hash_info.relative_unix_path); + } } return mismatched_hashes; @@ -365,7 +366,7 @@ VLOG(1) << "content mismatch for " << relative_unix_path.AsUTF8Unsafe(); // Remove hash entry to keep computed_hashes.json file clear of mismatched // hashes. - computed_hashes_data->erase(relative_unix_path); + computed_hashes_data->Remove(relative_unix_path); } hash_mismatch_unix_paths_ = std::move(hashes_mismatch); }
diff --git a/extensions/browser/content_verifier/content_hash_unittest.cc b/extensions/browser/content_verifier/content_hash_unittest.cc index 42fbe22..9a3a708b 100644 --- a/extensions/browser/content_verifier/content_hash_unittest.cc +++ b/extensions/browser/content_verifier/content_hash_unittest.cc
@@ -59,8 +59,7 @@ for (const auto& resource : extension_resources_) { std::vector<std::string> hashes = ComputedHashes::GetHashesForContent(resource.contents, block_size); - computed_hashes_data[resource.relative_path] = - ComputedHashes::HashInfo(block_size, hashes); + computed_hashes_data.Add(resource.relative_path, block_size, hashes); } ASSERT_TRUE(ComputedHashes(std::move(computed_hashes_data))
diff --git a/extensions/browser/content_verifier/content_verifier_utils.cc b/extensions/browser/content_verifier/content_verifier_utils.cc index 3e800cbb..cd1b780a 100644 --- a/extensions/browser/content_verifier/content_verifier_utils.cc +++ b/extensions/browser/content_verifier/content_verifier_utils.cc
@@ -22,9 +22,10 @@ return true; } -base::FilePath::StringType CanonicalizeFilePath(const base::FilePath& path) { +base::FilePath::StringType CanonicalizeRelativePath( + const base::FilePath& relative_path) { base::FilePath::StringType canonicalized_path = - path.NormalizePathSeparatorsTo('/').value(); + relative_path.NormalizePathSeparatorsTo('/').value(); if (!IsFileAccessCaseSensitive()) canonicalized_path = base::ToLowerASCII(canonicalized_path); if (IsDotSpaceFilenameSuffixIgnored())
diff --git a/extensions/browser/content_verifier/content_verifier_utils.h b/extensions/browser/content_verifier/content_verifier_utils.h index c97c1bd..1114fbc5 100644 --- a/extensions/browser/content_verifier/content_verifier_utils.h +++ b/extensions/browser/content_verifier/content_verifier_utils.h
@@ -37,9 +37,10 @@ #endif } -// Returns platform specific canonicalized version of |path| for content -// verification system. -base::FilePath::StringType CanonicalizeFilePath(const base::FilePath& path); +// Returns platform specific canonicalized version of |relative_path| for +// content verification system. +base::FilePath::StringType CanonicalizeRelativePath( + const base::FilePath& relative_path); } // namespace content_verifier_utils } // namespace extensions
diff --git a/extensions/browser/content_verify_job_unittest.cc b/extensions/browser/content_verify_job_unittest.cc index c667340..eb3c653 100644 --- a/extensions/browser/content_verify_job_unittest.cc +++ b/extensions/browser/content_verify_job_unittest.cc
@@ -76,8 +76,7 @@ for (const auto& resource : contents) { std::vector<std::string> hashes = ComputedHashes::GetHashesForContent(resource.second, block_size); - computed_hashes_data[resource.first] = - ComputedHashes::HashInfo(block_size, hashes); + computed_hashes_data.Add(resource.first, block_size, std::move(hashes)); } base::CreateDirectory(extension_root.Append(kMetadataFolder)); @@ -365,8 +364,8 @@ const std::string kFakeContents = "fake contents"; std::vector<std::string> hashes = ComputedHashes::GetHashesForContent(kFakeContents, block_size); - incorrect_computed_hashes_data[resource_path] = - ComputedHashes::HashInfo(block_size, hashes); + incorrect_computed_hashes_data.Add(resource_path, block_size, + std::move(hashes)); ASSERT_TRUE( ComputedHashes(std::move(incorrect_computed_hashes_data))
diff --git a/extensions/browser/url_loader_factory_manager.cc b/extensions/browser/url_loader_factory_manager.cc index adf43375..ed4852e 100644 --- a/extensions/browser/url_loader_factory_manager.cc +++ b/extensions/browser/url_loader_factory_manager.cc
@@ -44,6 +44,11 @@ namespace { +bool ShouldAllowlistAlsoApplyToOorCors() { + return base::FeatureList::IsEnabled( + extensions_features::kCorbAllowlistAlsoAppliesToOorCors); +} + enum class FactoryUser { kContentScript, kExtensionProcess, @@ -52,14 +57,14 @@ // The allowlist contains HashedExtensionId of extensions discovered via // Extensions.CrossOriginFetchFromContentScript2 Rappor data. When the data was // gathered, these extensions relied on making cross-origin requests from -// content scripts (which requires relaxing CORB). Going forward, these -// extensions should migrate to making those requests from elsewhere (e.g. from -// a background page, or in the future from extension service workers) at which -// point they can be removed from the allowlist. +// content scripts (which requires relaxing CORB and CORS). Going forward, +// these extensions should migrate to making those requests from elsewhere (e.g. +// from a background page, or in the future from extension service workers) at +// which point they can be removed from the allowlist. // // Migration plan for extension developers is described at // https://chromium.org/Home/chromium-security/extension-content-script-fetches -const char* kHardcodedPartOfCorbAllowlist[] = { +const char* kHardcodedPartOfAllowlist[] = { "039F93DD1DF836F1D4E2084C1BEFDB46A854A9D1", "03E5D80A49C309F7B55ED6BD2B0EDEB38021ED4E", "072D729E856B1F2C9894AEEC3A5DF65E519D6BEE", @@ -251,8 +256,8 @@ } // Append extensions from the hardcoded allowlist. - allowlist.reserve(base::size(kHardcodedPartOfCorbAllowlist)); - for (const char* hash : kHardcodedPartOfCorbAllowlist) { + allowlist.reserve(base::size(kHardcodedPartOfAllowlist)); + for (const char* hash : kHardcodedPartOfAllowlist) { DCHECK(IsValidHashedExtensionId(hash)); // It also validates the length. allowlist.push_back(std::string(hash, kHashedExtensionIdLength)); } @@ -261,7 +266,7 @@ } // Returns a set of HashedExtensionId of extensions that depend on relaxed CORB -// behavior in their content scripts. +// or CORS behavior in their content scripts. base::flat_set<std::string>& GetExtensionsAllowlist() { static base::NoDestructor<base::flat_set<std::string>> s_allowlist([] { base::flat_set<std::string> result(CreateExtensionAllowlist()); @@ -271,14 +276,14 @@ return *s_allowlist; } -bool DoContentScriptsDependOnRelaxedCorb(const Extension& extension) { +bool DoContentScriptsDependOnRelaxedCorbOrCors(const Extension& extension) { // Content scripts injected by Chrome Apps (e.g. into <webview> tag) need to // run with relaxed CORB. if (extension.is_platform_app()) return true; - // Content scripts in the current version of extensions might depend on - // relaxed CORB. + // Content scripts in manifest v2 might be allowlisted to depend on relaxed + // CORB and/or CORS. if (extension.manifest_version() <= 2) { const std::string& hash = extension.hashed_id().value(); DCHECK(IsValidHashedExtensionId(hash)); @@ -289,44 +294,86 @@ return false; } -bool DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins( - const Extension& extension) { - // TODO(lukasza): https://crbug.com/1016904: Return false if the |extension| - // doesn't need a special URLLoaderFactory based on |extension| permissions. - // For now we conservatively assume that all extensions need relaxed CORS/CORB +bool DoExtensionPermissionsCoverHttpOrHttpsOrigins(const Extension& extension) { + // TODO(lukasza): https://crbug.com/1016904: Return false if the |extension|'s + // permissions do not actually cover http or https origins. For now we + // conservatively return true so that *all* extensions get relaxed CORS/CORB // treatment. return true; } -bool IsSpecialURLLoaderFactoryRequired(const Extension& extension, - FactoryUser factory_user) { +// Returns whether the default URLLoaderFactoryParams::is_corb_enabled should be +// overridden and changed to false. +bool ShouldDisableCorb(const Extension& extension, FactoryUser factory_user) { + if (!DoExtensionPermissionsCoverHttpOrHttpsOrigins(extension)) + return false; + switch (factory_user) { case FactoryUser::kContentScript: - return DoContentScriptsDependOnRelaxedCorb(extension) && - DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins(extension); + return DoContentScriptsDependOnRelaxedCorbOrCors(extension); case FactoryUser::kExtensionProcess: - return DoExtensionPermissionsCoverCorsOrCorbRelatedOrigins(extension); + return true; } } +// Returns whether URLLoaderFactoryParams::ignore_isolated_world_origin should +// be overridden and changed to false. +bool ShouldInspectIsolatedWorldOrigin(const Extension& extension, + FactoryUser factory_user) { + if (!DoExtensionPermissionsCoverHttpOrHttpsOrigins(extension)) + return false; + + switch (factory_user) { + case FactoryUser::kContentScript: + // If |extensions_features::kCorbAllowlistAlsoAppliesToOorCors| is + // disabled, then go back to the legacy CORS behavior for all extensions. + if (!ShouldAllowlistAlsoApplyToOorCors()) + return true; + + // Otherwise, make an |extension|-specific decision. + return DoContentScriptsDependOnRelaxedCorbOrCors(extension); + case FactoryUser::kExtensionProcess: + return false; + } +} + +bool ShouldCreateSeparateFactoryForContentScripts(const Extension& extension) { + return ShouldDisableCorb(extension, FactoryUser::kContentScript) || + ShouldInspectIsolatedWorldOrigin(extension, + FactoryUser::kContentScript); +} + void OverrideFactoryParams(const Extension& extension, FactoryUser factory_user, network::mojom::URLLoaderFactoryParams* params) { - // Setup factory bound allow list that overwrites per-profile common list - // to allow tab specific permissions only for this newly created factory. - params->factory_bound_access_patterns = - network::mojom::CorsOriginAccessPatterns::New(); - params->factory_bound_access_patterns->source_origin = - url::Origin::Create(extension.url()); - params->factory_bound_access_patterns->allow_patterns = - CreateCorsOriginAccessAllowList( - extension, - PermissionsData::EffectiveHostPermissionsMode::kIncludeTabSpecific); + if (ShouldDisableCorb(extension, factory_user)) { + // TODO(lukasza): https://crbug.com/1016904: Use more granular CORB + // enforcement based on the specific |extension|'s permissions reflected + // in the |factory_bound_access_patterns| above. + params->is_corb_enabled = false; - // TODO(lukasza): https://crbug.com/1016904: Use more granular CORB - // enforcement based on the specific |extension|'s permissions. - params->is_corb_enabled = false; + // Setup factory bound allow list that overwrites per-profile common list to + // allow tab specific permissions only for this newly created factory. + // + // TODO(lukasza): Setting |factory_bound_access_patterns| together with + // |is_corb_enabled| seems accidental. + params->factory_bound_access_patterns = + network::mojom::CorsOriginAccessPatterns::New(); + params->factory_bound_access_patterns->source_origin = + url::Origin::Create(extension.url()); + params->factory_bound_access_patterns->allow_patterns = + CreateCorsOriginAccessAllowList( + extension, + PermissionsData::EffectiveHostPermissionsMode::kIncludeTabSpecific); + params->factory_bound_access_patterns->block_patterns = + CreateCorsOriginAccessBlockList(extension); + } + if (ShouldInspectIsolatedWorldOrigin(extension, factory_user)) + params->ignore_isolated_world_origin = false; + + // TODO(lukasza): Do not override |unsafe_non_webby_initiator| unless + // DoExtensionPermissionsCoverHttpOrHttpsOrigins(extension). if (factory_user == FactoryUser::kExtensionProcess) params->unsafe_non_webby_initiator = true; } @@ -456,8 +503,7 @@ if (!DoContentScriptsMatchNavigatingFrame(extension, frame, url)) continue; - if (!IsSpecialURLLoaderFactoryRequired(extension, - FactoryUser::kContentScript)) + if (!ShouldCreateSeparateFactoryForContentScripts(extension)) continue; initiators_requiring_separate_factory.push_back( @@ -489,8 +535,7 @@ registry->enabled_extensions().GetByID(host_id.id()); DCHECK(extension); // Guaranteed by the caller - see the doc comment. - if (!IsSpecialURLLoaderFactoryRequired(*extension, - FactoryUser::kContentScript)) + if (!ShouldCreateSeparateFactoryForContentScripts(*extension)) return; // When WillExecuteCode runs, the frame already received the initial @@ -535,13 +580,10 @@ return; } - // Don't change |factory_params| unless required. + // Identify and set |factory_params| that need to be overridden. FactoryUser factory_user = is_for_isolated_world ? FactoryUser::kContentScript : FactoryUser::kExtensionProcess; - if (!IsSpecialURLLoaderFactoryRequired(*extension, factory_user)) - return; - OverrideFactoryParams(*extension, factory_user, factory_params); }
diff --git a/extensions/browser/verified_contents.cc b/extensions/browser/verified_contents.cc index a80acc1..73ccd07 100644 --- a/extensions/browser/verified_contents.cc +++ b/extensions/browser/verified_contents.cc
@@ -172,7 +172,7 @@ } base::FilePath::StringType canonicalized_path = - content_verifier_utils::CanonicalizeFilePath( + content_verifier_utils::CanonicalizeRelativePath( base::FilePath::FromUTF8Unsafe(*file_path_string)); auto i = verified_contents->root_hashes_.insert( std::make_pair(canonicalized_path, std::string())); @@ -189,13 +189,14 @@ const base::FilePath& relative_path) const { return base::Contains( root_hashes_, - content_verifier_utils::CanonicalizeFilePath(relative_path)); + content_verifier_utils::CanonicalizeRelativePath(relative_path)); } bool VerifiedContents::TreeHashRootEquals(const base::FilePath& relative_path, const std::string& expected) const { return TreeHashRootEqualsImpl( - content_verifier_utils::CanonicalizeFilePath(relative_path), expected); + content_verifier_utils::CanonicalizeRelativePath(relative_path), + expected); } // We're loosely following the "JSON Web Signature" draft spec for signing
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 8c5d90c..1cffd0e 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -28,6 +28,15 @@ const char kPrivacyMessage[] = "1"; const char kNeutralMessage[] = "2"; +// Controls whether the CORB allowlist [1] is also applied to OOR-CORS (e.g. +// whether non-allowlisted content scripts can bypass CORS in OOR-CORS mode). +// See also: https://crbug.com/920638 +// +// [1] +// https://www.chromium.org/Home/chromium-security/extension-content-script-fetches +const base::Feature kCorbAllowlistAlsoAppliesToOorCors{ + "CorbAllowlistAlsoAppliesToOorCors", base::FEATURE_DISABLED_BY_DEFAULT}; + // Forces requests to go through WebRequestProxyingURLLoaderFactory. const base::Feature kForceWebRequestProxyForTest{ "ForceWebRequestProxyForTest", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h index b3983c0..4be1737f 100644 --- a/extensions/common/extension_features.h +++ b/extensions/common/extension_features.h
@@ -18,6 +18,7 @@ extern const char kPrivacyMessage[]; extern const char kNeutralMessage[]; +extern const base::Feature kCorbAllowlistAlsoAppliesToOorCors; extern const base::Feature kForceWebRequestProxyForTest; } // namespace extensions_features
diff --git a/fuchsia/engine/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc index 402d9d6..31799b8 100644 --- a/fuchsia/engine/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -127,6 +127,23 @@ return std::move(*config); } +void AppendFeature(base::StringPiece features_flag, + base::StringPiece feature_string, + base::CommandLine* command_line) { + if (!command_line->HasSwitch(features_flag)) { + command_line->AppendSwitchNative(features_flag.as_string(), + feature_string.as_string()); + return; + } + + std::string new_feature_string = + command_line->GetSwitchValueASCII(features_flag); + new_feature_string.append(",").append(feature_string.as_string()); + command_line->RemoveSwitch(features_flag); + command_line->AppendSwitchNative(features_flag.as_string(), + new_feature_string); +} + // Returns false if the config is present but has invalid contents. bool MaybeAddCommandLineArgsFromConfig(const base::Value& config, base::CommandLine* command_line) { @@ -135,6 +152,7 @@ return true; static const base::StringPiece kAllowedArgs[] = { + switches::kDisableFeatures, switches::kDisableGpuWatchdog, switches::kEnableFeatures, switches::kEnableFuchsiaAudioConsumer, @@ -156,6 +174,8 @@ LOG(ERROR) << "Config command-line arg must be a string: " << arg.first; return false; } + + DCHECK(!command_line->HasSwitch(arg.first)); command_line->AppendSwitchNative(arg.first, arg.second.GetString()); // TODO(https://crbug.com/1023012): enable-low-end-device-mode currently @@ -260,6 +280,13 @@ base::CommandLine launch_command = *base::CommandLine::ForCurrentProcess(); std::vector<zx::channel> devtools_listener_channels; + base::Value web_engine_config = + config_for_test_.is_none() ? LoadConfig() : std::move(config_for_test_); + if (!MaybeAddCommandLineArgsFromConfig(web_engine_config, &launch_command)) { + context_request.Close(ZX_ERR_INTERNAL); + return; + } + if (params.has_remote_debugging_port()) { launch_command.AppendSwitchNative( switches::kRemoteDebuggingPort, @@ -332,8 +359,8 @@ launch_command.AppendSwitch(switches::kUseVulkan); const std::vector<base::StringPiece> enabled_features = { features::kUseSkiaRenderer.name, features::kVulkan.name}; - launch_command.AppendSwitchASCII(switches::kEnableFeatures, - base::JoinString(enabled_features, ",")); + AppendFeature(switches::kEnableFeatures, + base::JoinString(enabled_features, ","), &launch_command); // SkiaRenderer requires out-of-process rasterization be enabled. launch_command.AppendSwitch(switches::kEnableOopRasterization); @@ -350,9 +377,6 @@ launch_command.AppendSwitch(switches::kDisableSoftwareRasterizer); } - base::Value web_engine_config = - config_for_test_.is_none() ? LoadConfig() : std::move(config_for_test_); - bool allow_protected_graphics = web_engine_config.FindBoolPath("allow-protected-graphics") .value_or(false); @@ -411,11 +435,6 @@ launch_command.AppendSwitch(switches::kDisableSoftwareVideoDecoders); } - if (!MaybeAddCommandLineArgsFromConfig(web_engine_config, &launch_command)) { - context_request.Close(ZX_ERR_INTERNAL); - return; - } - // Validate embedder-supplied product, and optional version, and pass it to // the Context to include in the UserAgent. if (params.has_user_agent_product()) { @@ -463,8 +482,8 @@ // TODO(crbug.com/1039788): Re-enable OutOfBlinkCors when custom HTTP header // preflight validation errors are fixed. - launch_command.AppendSwitchASCII("disable-features", - network::features::kOutOfBlinkCors.name); + AppendFeature(switches::kDisableFeatures, + network::features::kOutOfBlinkCors.name, &launch_command); if (launch_for_test_) launch_for_test_.Run(launch_command, launch_options);
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index 04883fc..433a6bd7 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc
@@ -221,11 +221,6 @@ delayed_watchdog_enable = true; #endif - // PreSandbox is mainly for resource handling and not related to the GPU - // driver, it doesn't need the GPU watchdog. The loadLibrary may take long - // time that killing and restarting the GPU process will not help. - sandbox_helper_->PreSandboxStartup(); - // Start the GPU watchdog only after anything that is expected to be time // consuming has completed, otherwise the process is liable to be aborted. if (enable_watchdog && !delayed_watchdog_enable) { @@ -308,6 +303,14 @@ return false; } + // The ContentSandboxHelper is currently the only one implementation of + // gpu::GpuSandboxHelper and it has no dependency. Except on Linux where + // VaapiWrapper checks the GL implementation to determine which display + // to use. So call PreSandboxStartup after GL initialization. But make + // sure the watchdog is still in pause as loadLibrary may take a long time + // and restarting the GPU process will not help. + sandbox_helper_->PreSandboxStartup(); + if (watchdog_thread_) watchdog_thread_->ResumeWatchdog(); if (gl::GetGLImplementation() != gl::kGLImplementationDisabled) {
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 0908d19c..42e0ecd 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -362,7 +362,6 @@ triggers: "linux-blink-heap-verification" triggers: "linux-chromeos-dbg" triggers: "linux-chromium-tests-staging-builder" - triggers: "linux-code-coverage" triggers: "linux-archive-dbg" triggers: "linux-gcc-rel" triggers: "linux-ozone-rel" @@ -2555,16 +2554,6 @@ } job { - id: "linux-code-coverage" - acl_sets: "default" - buildbucket: { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "linux-code-coverage" - } -} - -job { id: "linux-archive-dbg" acl_sets: "default" buildbucket: {
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg index 0908d19c..42e0ecd 100644 --- a/infra/config/luci-scheduler.cfg +++ b/infra/config/luci-scheduler.cfg
@@ -362,7 +362,6 @@ triggers: "linux-blink-heap-verification" triggers: "linux-chromeos-dbg" triggers: "linux-chromium-tests-staging-builder" - triggers: "linux-code-coverage" triggers: "linux-archive-dbg" triggers: "linux-gcc-rel" triggers: "linux-ozone-rel" @@ -2555,16 +2554,6 @@ } job { - id: "linux-code-coverage" - acl_sets: "default" - buildbucket: { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "linux-code-coverage" - } -} - -job { id: "linux-archive-dbg" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index e73c4b6..7e479f9 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -186,6 +186,8 @@ "//ios/chrome/browser/content_settings", "//ios/chrome/browser/crash_report", "//ios/chrome/browser/crash_report:crash_report_internal", + "//ios/chrome/browser/crash_report/breadcrumbs", + "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", "//ios/chrome/browser/download", "//ios/chrome/browser/external_files", "//ios/chrome/browser/favicon",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index f08bf7c..5a63d9f 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -72,8 +72,12 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/chrome_url_util.h" #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" +#include "ios/chrome/browser/crash_report/crash_report_helper.h" #include "ios/chrome/browser/download/download_directory_util.h" #import "ios/chrome/browser/external_files/external_file_remover_factory.h" #import "ios/chrome/browser/external_files/external_file_remover_impl.h" @@ -586,6 +590,13 @@ // Initialize and set the main browser state. [self initializeBrowserState:chromeBrowserState]; self.mainBrowserState = chromeBrowserState; + + if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { + breakpad::MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( + self.mainBrowserState)); + } + [self.browserViewWrangler shutdown]; self.browserViewWrangler = [[BrowserViewWrangler alloc] initWithBrowserState:self.mainBrowserState @@ -786,6 +797,17 @@ [_spotlightManager shutdown]; _spotlightManager = nil; + if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { + if (self.mainBrowserState->HasOffTheRecordChromeBrowserState()) { + breakpad::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( + self.mainBrowserState->GetOffTheRecordChromeBrowserState())); + } + breakpad::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( + self.mainBrowserState)); + } + // Invariant: The UI is stopped before the model is shutdown. DCHECK(!_mainCoordinator); [self.browserViewWrangler shutdown];
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 39b7478..21d4f0b 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -218,6 +218,9 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state:browser_state_impl", "//ios/chrome/browser/component_updater", + "//ios/chrome/browser/crash_report/breadcrumbs", + "//ios/chrome/browser/crash_report/breadcrumbs:application_breadcrumbs_logger", + "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", "//ios/chrome/browser/first_run", "//ios/chrome/browser/flags", "//ios/chrome/browser/gcm",
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc index 8498eb7..377f319 100644 --- a/ios/chrome/browser/application_context_impl.cc +++ b/ios/chrome/browser/application_context_impl.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/macros.h" @@ -42,6 +43,9 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.h" #include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/component_updater/ios_component_updater_configurator.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/ios_chrome_io_thread.h" @@ -182,6 +186,13 @@ ukm::UkmService* ukm_service = GetMetricsServicesManager()->GetUkmService(); if (ukm_service) ukm_service->OnAppEnterForeground(); + + if (base::FeatureList::IsEnabled(kLogBreadcrumbs) && !breadcrumb_manager_) { + breadcrumb_manager_ = std::make_unique<BreadcrumbManager>(); + application_breadcrumbs_logger_ = + std::make_unique<ApplicationBreadcrumbsLogger>( + breadcrumb_manager_.get()); + } } void ApplicationContextImpl::OnAppEnterBackground() {
diff --git a/ios/chrome/browser/application_context_impl.h b/ios/chrome/browser/application_context_impl.h index 5a7a49f..e0a53cd 100644 --- a/ios/chrome/browser/application_context_impl.h +++ b/ios/chrome/browser/application_context_impl.h
@@ -18,6 +18,9 @@ class SequencedTaskRunner; } +class BreadcrumbManager; +class ApplicationBreadcrumbsLogger; + namespace network { class NetworkChangeManager; } @@ -80,6 +83,14 @@ void CreateGCMDriver(); base::ThreadChecker thread_checker_; + + // Breadcrumb manager used to store application wide breadcrumb events. Will + // be null if breadcrumbs feature is not enabled. + std::unique_ptr<BreadcrumbManager> breadcrumb_manager_; + // Logger which observers and logs application wide events to + // |breadcrumb_manager_|. Will be null if breadcrumbs feature is not enabled. + std::unique_ptr<ApplicationBreadcrumbsLogger> application_breadcrumbs_logger_; + std::unique_ptr<PrefService> local_state_; std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn index 11f8845..0df897af 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn +++ b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn
@@ -49,10 +49,27 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("application_breadcrumbs_logger") { + sources = [ + "application_breadcrumbs_logger.h", + "application_breadcrumbs_logger.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":breadcrumbs", + "//base", + "//ios/chrome/browser/crash_report:crash_report_internal", + "//ios/chrome/browser/crash_report/breadcrumbs", + ] +} + source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true deps = [ + ":application_breadcrumbs_logger", ":breadcrumbs", "//base/test:test_support", "//ios/chrome/browser/browser_state:test_support", @@ -68,6 +85,7 @@ ] sources = [ + "application_breadcrumbs_logger_unittest.mm", "breadcrumb_manager_browser_agent_unittest.mm", "breadcrumb_manager_keyed_service_unittest.mm", "breadcrumb_manager_observer_bridge_unittest.mm",
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h new file mode 100644 index 0000000..0864daf7 --- /dev/null +++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h
@@ -0,0 +1,42 @@ +// Copyright 2020 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_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_ +#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_ + +#include <memory> + +#include "base/memory/memory_pressure_listener.h" +#include "base/metrics/user_metrics.h" + +class BreadcrumbManager; + +// Listens for and logs application wide breadcrumb events to the +// BreadcrumbManager passed in the constructor. +class ApplicationBreadcrumbsLogger { + public: + explicit ApplicationBreadcrumbsLogger(BreadcrumbManager* breadcrumb_manager); + ~ApplicationBreadcrumbsLogger(); + + private: + ApplicationBreadcrumbsLogger(const ApplicationBreadcrumbsLogger&) = delete; + + // Callback which processes and logs the user action |action| to + // |breadcrumb_manager_|. + void OnUserAction(const std::string& action); + + // Callback which processes and logs memory pressure warnings to + // |breadcrumb_manager_|. + void OnMemoryPressure( + base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); + + // The BreadcrumbManager to log events. + BreadcrumbManager* breadcrumb_manager_; + // The callback invoked whenever a user action is registered. + base::ActionCallback user_action_callback_; + // A memory pressure listener which observes memory pressure events. + std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; +}; + +#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm new file mode 100644 index 0000000..ed9c2e70 --- /dev/null +++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm
@@ -0,0 +1,63 @@ +// Copyright 2020 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 "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h" + +#include "base/bind.h" +#include "base/strings/stringprintf.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#import "ios/chrome/browser/crash_report/crash_report_helper.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +ApplicationBreadcrumbsLogger::ApplicationBreadcrumbsLogger( + BreadcrumbManager* breadcrumb_manager) + : breadcrumb_manager_(breadcrumb_manager), + user_action_callback_( + base::BindRepeating(&ApplicationBreadcrumbsLogger::OnUserAction, + base::Unretained(this))), + memory_pressure_listener_(std::make_unique<base::MemoryPressureListener>( + base::BindRepeating(&ApplicationBreadcrumbsLogger::OnMemoryPressure, + base::Unretained(this)))) { + base::AddActionCallback(user_action_callback_); + breakpad::MonitorBreadcrumbManager(breadcrumb_manager_); +} + +ApplicationBreadcrumbsLogger::~ApplicationBreadcrumbsLogger() { + base::RemoveActionCallback(user_action_callback_); + breakpad::StopMonitoringBreadcrumbManager(breadcrumb_manager_); +} + +void ApplicationBreadcrumbsLogger::OnUserAction(const std::string& action) { + // Filter out unwanted actions. + if (action.find("InProductHelp.") == 0) { + // InProductHelp actions are very noisy. + return; + } + + std::string event = base::StringPrintf("UserAction: %s", action.c_str()); + breadcrumb_manager_->AddEvent(event); +} + +void ApplicationBreadcrumbsLogger::OnMemoryPressure( + base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { + std::string pressure_string = ""; + switch (memory_pressure_level) { + case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: + pressure_string = "None"; + break; + case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: + pressure_string = "Moderate"; + break; + case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: + pressure_string = "Critical"; + break; + } + + std::string event = + base::StringPrintf("Memory Pressure: %s", pressure_string.c_str()); + breadcrumb_manager_->AddEvent(event); +}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger_unittest.mm new file mode 100644 index 0000000..cada6e7 --- /dev/null +++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger_unittest.mm
@@ -0,0 +1,80 @@ +// Copyright 2020 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 "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h" + +#include "base/memory/memory_pressure_listener.h" +#include "base/metrics/user_metrics_action.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// The particular UserActions used here are not important, but real UserAction +// names are used to prevent a presubmit warning. +const char kUserAction1Name[] = "MobileMenuNewTab"; +const char kUserAction2Name[] = "MobileTabClosed"; +// An "InProductHelp.*" user action. +const char kInProductHelpUserActionName[] = "InProductHelp.Dismissed"; +} // namespace + +using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel; + +// Test fixture for testing ApplicationBreadcrumbsLogger class. +class ApplicationBreadcrumbsLoggerTest : public PlatformTest { + protected: + ApplicationBreadcrumbsLoggerTest() + : logger_(std::make_unique<ApplicationBreadcrumbsLogger>( + &breadcrumb_manager_)) {} + + base::test::TaskEnvironment task_environment_; + BreadcrumbManager breadcrumb_manager_; + std::unique_ptr<ApplicationBreadcrumbsLogger> logger_; +}; + +// Tests that a recorded UserAction is logged by the +// ApplicationBreadcrumbsLogger. +TEST_F(ApplicationBreadcrumbsLoggerTest, UserAction) { + base::RecordAction(base::UserMetricsAction(kUserAction1Name)); + base::RecordAction(base::UserMetricsAction(kUserAction2Name)); + + std::list<std::string> events = breadcrumb_manager_.GetEvents(0); + ASSERT_EQ(2ul, events.size()); + EXPECT_NE(std::string::npos, events.front().find(kUserAction1Name)); + // Ensure UserAction events are labeled as such. + EXPECT_NE(std::string::npos, events.front().find("UserAction: ")); + events.pop_front(); + EXPECT_NE(std::string::npos, events.front().find(kUserAction2Name)); +} + +// Tests that "InProductHelp" UserActions are not logged by +// ApplicationBreadcrumbsLogger as they are very noisy. +TEST_F(ApplicationBreadcrumbsLoggerTest, SkipInProductHelpUserActions) { + base::RecordAction(base::UserMetricsAction(kInProductHelpUserActionName)); + + std::list<std::string> events = breadcrumb_manager_.GetEvents(0); + ASSERT_EQ(0ul, events.size()); +} + +// Tests that memory pressure events are logged by ApplicationBreadcrumbsLogger. +TEST_F(ApplicationBreadcrumbsLoggerTest, MemoryPressure) { + base::MemoryPressureListener::SimulatePressureNotification( + MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE); + base::MemoryPressureListener::SimulatePressureNotification( + MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL); + base::RunLoop().RunUntilIdle(); + + std::list<std::string> events = breadcrumb_manager_.GetEvents(0); + ASSERT_EQ(2ul, events.size()); + EXPECT_NE(std::string::npos, events.front().find("Moderate")); + // Ensure UserAction events are labeled as such. + EXPECT_NE(std::string::npos, events.front().find("Memory Pressure: ")); + events.pop_front(); + EXPECT_NE(std::string::npos, events.front().find("Critical")); +}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h index 55102684..1be634d 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h
@@ -7,13 +7,10 @@ #include "base/no_destructor.h" #include "components/keyed_service/ios/browser_state_keyed_service_factory.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h" class BreadcrumbManagerKeyedService; -namespace ios { -class ChromeBrowserState; -} - class BreadcrumbManagerKeyedServiceFactory : public BrowserStateKeyedServiceFactory { public:
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h index 364cf7c7..e27068c6 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h
@@ -7,13 +7,10 @@ #include "base/no_destructor.h" #include "components/keyed_service/ios/browser_state_keyed_service_factory.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h" class BreadcrumbPersistentStorageKeyedService; -namespace ios { -class ChromeBrowserState; -} - class BreadcrumbPersistentStorageKeyedServiceFactory : public BrowserStateKeyedServiceFactory { public:
diff --git a/ios/chrome/browser/crash_report/crash_report_helper.h b/ios/chrome/browser/crash_report/crash_report_helper.h index 259c8f6..524604a 100644 --- a/ios/chrome/browser/crash_report/crash_report_helper.h +++ b/ios/chrome/browser/crash_report/crash_report_helper.h
@@ -9,6 +9,9 @@ @class NSString; +class BreadcrumbManager; +class BreadcrumbManagerKeyedService; + namespace web { class WebState; } // namespace web @@ -44,15 +47,21 @@ // be called when the WebStateList is deactivated. void ClearStateForWebStateList(WebStateList* web_state_list); -// Starts listening for breadcrumbs logged to |browser_state|'s -// BreadcrumbManagerKeyedService. Collected breadcrumbs will be attached to -// crash reports. -void MonitorBreadcrumbsForBrowserState(ios::ChromeBrowserState* browser_state); +// Starts listening for breadcrumbs logged to |breadcrumb_manager|. Collected +// breadcrumbs will be attached to crash reports. +void MonitorBreadcrumbManager(BreadcrumbManager* breadcrumb_manager); -// Stops listening for breadcrumbs logged to |browser_state|'s -// BreadcrumbManagerKeyedService. -void StopMonitoringBreadcrumbsForBrowserState( - ios::ChromeBrowserState* browser_state); +// Stops listening for breadcrumbs logged to |breadcrumb_manager|. +void StopMonitoringBreadcrumbManager(BreadcrumbManager* breadcrumb_manager); + +// Starts listening for breadcrumbs logged to |breadcrumb_manager_service|. +// Collected breadcrumbs will be attached to crash reports. +void MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedService* breadcrumb_manager_service); + +// Stops listening for breadcrumbs logged to |breadcrumb_manager_service|. +void StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* breadcrumb_manager_service); } // namespace breakpad
diff --git a/ios/chrome/browser/crash_report/crash_report_helper.mm b/ios/chrome/browser/crash_report/crash_report_helper.mm index b78b545..0df584d 100644 --- a/ios/chrome/browser/crash_report/crash_report_helper.mm +++ b/ios/chrome/browser/crash_report/crash_report_helper.mm
@@ -439,15 +439,26 @@ } } -void MonitorBreadcrumbsForBrowserState(ios::ChromeBrowserState* browser_state) { +void MonitorBreadcrumbManager(BreadcrumbManager* breadcrumb_manager) { [[CrashReporterBreadcrumbObserver uniqueInstance] - observeBrowserState:browser_state]; + observeBreadcrumbManager:breadcrumb_manager]; } -void StopMonitoringBreadcrumbsForBrowserState( - ios::ChromeBrowserState* browser_state) { +void StopMonitoringBreadcrumbManager(BreadcrumbManager* breadcrumb_manager) { [[CrashReporterBreadcrumbObserver uniqueInstance] - stopObservingBrowserState:browser_state]; + stopObservingBreadcrumbManager:breadcrumb_manager]; +} + +void MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedService* breadcrumb_manager_service) { + [[CrashReporterBreadcrumbObserver uniqueInstance] + observeBreadcrumbManagerService:breadcrumb_manager_service]; +} + +void StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* breadcrumb_manager_service) { + [[CrashReporterBreadcrumbObserver uniqueInstance] + stopObservingBreadcrumbManagerService:breadcrumb_manager_service]; } } // namespace breakpad
diff --git a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h index d7a74f9d..e8cfa1fc 100644 --- a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h +++ b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h
@@ -13,8 +13,8 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h" #import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer_bridge.h" -// Combines breadcrumbs from multiple ChromeBrowserState instances and sends the -// merged breadcrumb events to breakpad for attachment to crash reports. +// Combines breadcrumbs from multiple BreadcrumbManagers and sends the merged +// breadcrumb events to breakpad for attachment to crash reports. @interface CrashReporterBreadcrumbObserver : NSObject <BreadcrumbManagerObserving> { } @@ -22,10 +22,19 @@ // Creates a singleton instance. + (CrashReporterBreadcrumbObserver*)uniqueInstance; -// Starts collecting breadcrumb events associated with |browserState|. -- (void)observeBrowserState:(ios::ChromeBrowserState*)browserState; -// Stops collecting breadcrumb events associated with |browserState|. -- (void)stopObservingBrowserState:(ios::ChromeBrowserState*)browserState; +// Starts collecting breadcrumb events logged to |breadcrumbManager|. +- (void)observeBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager; + +// Stops collecting breadcrumb events logged to |breadcrumbManager|. +- (void)stopObservingBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager; + +// Starts collecting breadcrumb events logged to |breadcrumbManagerService|. +- (void)observeBreadcrumbManagerService: + (BreadcrumbManagerKeyedService*)breadcrumbManagerService; + +// Stops collecting breadcrumb events logged to |breadcrumbManagerService|. +- (void)stopObservingBreadcrumbManagerService: + (BreadcrumbManagerKeyedService*)breadcrumbManagerService; @end
diff --git a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.mm b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.mm index 288556f..70803aab 100644 --- a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.mm +++ b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.mm
@@ -4,9 +4,8 @@ #include "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer_bridge.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -22,11 +21,17 @@ } @interface CrashReporterBreadcrumbObserver () { - // Map associating the observed ChromeBrowserStates with the corresponding + // Map associating the observed BreadcrumbManager with the corresponding // observer bridge instances. - std::map<ios::ChromeBrowserState*, - std::unique_ptr<BreadcrumbManagerObserverBridge>> + std::map<BreadcrumbManager*, std::unique_ptr<BreadcrumbManagerObserverBridge>> _breadcrumbManagerObservers; + + // Map associating the observed BreadcrumbManagerKeyedServices with the + // corresponding observer bridge instances. + std::map<BreadcrumbManagerKeyedService*, + std::unique_ptr<BreadcrumbManagerObserverBridge>> + _breadcrumbManagerServiceObservers; + // A string which stores the received breadcrumbs. Since breakpad will // truncate this string anyway, it is truncated when a new event is added in // order to reduce overall memory usage. @@ -49,17 +54,30 @@ return self; } -- (void)observeBrowserState:(ios::ChromeBrowserState*)browserState { - DCHECK(!_breadcrumbManagerObservers[browserState]); +- (void)observeBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager { + DCHECK(!_breadcrumbManagerObservers[breadcrumbManager]); - BreadcrumbManagerKeyedService* service = - BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(browserState); - _breadcrumbManagerObservers[browserState] = - std::make_unique<BreadcrumbManagerObserverBridge>(service, self); + _breadcrumbManagerObservers[breadcrumbManager] = + std::make_unique<BreadcrumbManagerObserverBridge>(breadcrumbManager, + self); } -- (void)stopObservingBrowserState:(ios::ChromeBrowserState*)browserState { - _breadcrumbManagerObservers[browserState] = nullptr; +- (void)stopObservingBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager { + _breadcrumbManagerObservers.erase(breadcrumbManager); +} + +- (void)observeBreadcrumbManagerService: + (BreadcrumbManagerKeyedService*)breadcrumbManagerService { + DCHECK(!_breadcrumbManagerServiceObservers[breadcrumbManagerService]); + + _breadcrumbManagerServiceObservers[breadcrumbManagerService] = + std::make_unique<BreadcrumbManagerObserverBridge>( + breadcrumbManagerService, self); +} + +- (void)stopObservingBreadcrumbManagerService: + (BreadcrumbManagerKeyedService*)breadcrumbManagerService { + _breadcrumbManagerServiceObservers[breadcrumbManagerService] = nullptr; } #pragma mark - BreadcrumbManagerObserving protocol
diff --git a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm index ae2ae76..ea5893a 100644 --- a/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm +++ b/ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer_unittest.mm
@@ -95,15 +95,13 @@ [[mock_breakpad_controller_ expect] start:NO]; breakpad_helper::SetEnabled(true); - CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer = - [[CrashReporterBreadcrumbObserver alloc] init]; - [crash_reporter_breadcrumb_observer - observeBrowserState:chrome_browser_state_.get()]; - - const std::string event = std::string("Breadcrumb Event"); BreadcrumbManagerKeyedService* breadcrumb_service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( chrome_browser_state_.get()); + CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer = + [[CrashReporterBreadcrumbObserver alloc] init]; + [crash_reporter_breadcrumb_observer + observeBreadcrumbManagerService:breadcrumb_service]; id breadcrumbs_param_vaidation_block = [OCMArg checkWithBlock:^(id value) { if (![value isKindOfClass:[NSString class]]) { @@ -121,7 +119,7 @@ addUploadParameter:breadcrumbs_param_vaidation_block forKey:@"browser_state_breadcrumbs"]; - breadcrumb_service->AddEvent(event); + breadcrumb_service->AddEvent(std::string("Breadcrumb Event")); EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); } @@ -136,14 +134,13 @@ const std::string event = std::string("Breadcrumb Event"); NSString* event_nsstring = base::SysUTF8ToNSString(event); - CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer = - [[CrashReporterBreadcrumbObserver alloc] init]; - - [crash_reporter_breadcrumb_observer - observeBrowserState:chrome_browser_state_.get()]; BreadcrumbManagerKeyedService* breadcrumb_service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( chrome_browser_state_.get()); + CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer = + [[CrashReporterBreadcrumbObserver alloc] init]; + [crash_reporter_breadcrumb_observer + observeBreadcrumbManagerService:breadcrumb_service]; [[mock_breakpad_controller_ expect] addUploadParameter:StringParameterValidatorWithCountOfSubstring( @@ -153,10 +150,11 @@ ios::ChromeBrowserState* otr_browser_state = chrome_browser_state_->GetOffTheRecordChromeBrowserState(); - [crash_reporter_breadcrumb_observer observeBrowserState:otr_browser_state]; BreadcrumbManagerKeyedService* otr_breadcrumb_service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( otr_browser_state); + [crash_reporter_breadcrumb_observer + observeBreadcrumbManagerService:otr_breadcrumb_service]; [[mock_breakpad_controller_ expect] addUploadParameter:StringParameterValidatorWithCountOfSubstring( @@ -167,11 +165,11 @@ TestChromeBrowserState::Builder test_cbs_builder; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_2 = test_cbs_builder.Build(); - [crash_reporter_breadcrumb_observer - observeBrowserState:chrome_browser_state_2.get()]; BreadcrumbManagerKeyedService* breadcrumb_service_2 = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( chrome_browser_state_2.get()); + [crash_reporter_breadcrumb_observer + observeBreadcrumbManagerService:breadcrumb_service_2]; [[mock_breakpad_controller_ expect] addUploadParameter:StringParameterValidatorWithCountOfSubstring(
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 6ec7371..2e9bdda 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -593,6 +593,10 @@ {"clear-synced-data", flag_descriptions::kClearSyncedDataName, flag_descriptions::kClearSyncedDataDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kClearSyncedData)}, + {"ssl-committed-interstitials", + flag_descriptions::kSSLCommittedInterstitialsName, + flag_descriptions::kSSLCommittedInterstitialsDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(web::features::kSSLCommittedInterstitials)}, }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index ac4cf54..e2afe0c 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -344,6 +344,12 @@ const char kSnapshotDrawViewDescription[] = "When enabled, snapshots will be taken using |-drawViewHierarchy:|."; +const char kSSLCommittedInterstitialsName[] = + "Enable SSL committed interstitials"; +const char kSSLCommittedInterstitialsDescription[] = + "When enabled, SSL interstitial pages will be committed rather than using " + "an overlay on the page."; + const char kForceStartupSigninPromoName[] = "Display the startup sign-in promo"; const char kForceStartupSigninPromoDescription[] = "When enabled, the startup sign-in promo is always displayed when starting "
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index a5f3da0..16b5fa8 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -303,6 +303,10 @@ extern const char kSnapshotDrawViewName[]; extern const char kSnapshotDrawViewDescription[]; +// Title and description for the flag to enable SSL committed interstitials. +extern const char kSSLCommittedInterstitialsName[]; +extern const char kSSLCommittedInterstitialsDescription[]; + // Title and description for the flag to trigger the startup sign-in promo. extern const char kForceStartupSigninPromoName[]; extern const char kForceStartupSigninPromoDescription[];
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm index b6c4e75ee..f08b05b5 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm
@@ -20,7 +20,7 @@ InfobarOverlayBrowserAgent* browser_agent = InfobarOverlayBrowserAgent::FromBrowser(browser); browser_agent->AddInfobarInteractionHandler( - std::make_unique<PasswordInfobarInteractionHandler>()); + std::make_unique<PasswordInfobarInteractionHandler>(browser)); // TODO(crbug.com/1030357): Add InfobarInteractionHandlers for each // InfobarType when implemented. }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/BUILD.gn b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/BUILD.gn index a249a4a9..2820a301 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/BUILD.gn +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/BUILD.gn
@@ -21,10 +21,12 @@ "//ios/chrome/browser/infobars/overlays:util", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common", + "//ios/chrome/browser/main:public", "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/passwords:infobar_delegates", + "//ios/chrome/browser/ui/commands", ] } @@ -46,15 +48,21 @@ "//ios/chrome/browser/infobars:public", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/test", "//ios/chrome/browser/infobars/test", + "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/common/infobars", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/overlays/test", "//ios/chrome/browser/passwords:infobar_delegates", "//ios/chrome/browser/passwords/test", + "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/infobars/test", + "//ios/chrome/browser/web_state_list", + "//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/test:test_support", + "//ios/web/public/test", "//ios/web/public/test/fakes", "//testing/gtest", + "//third_party/ocmock", ] }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.h index 4697defc..4db9c91a 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.h +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.h
@@ -9,11 +9,13 @@ #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/infobar_interaction_handler.h" +class Browser; + // An InfobarInteractionHandler that updates the model layer for interaction // events with the UI for password infobars. class PasswordInfobarInteractionHandler : public InfobarInteractionHandler { public: - PasswordInfobarInteractionHandler(); + PasswordInfobarInteractionHandler(Browser* browser); ~PasswordInfobarInteractionHandler() override; };
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm index 22a901c..c6b5292a 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_interaction_handler.mm
@@ -13,12 +13,13 @@ #error "This file requires ARC support." #endif -PasswordInfobarInteractionHandler::PasswordInfobarInteractionHandler() +PasswordInfobarInteractionHandler::PasswordInfobarInteractionHandler( + Browser* browser) : InfobarInteractionHandler( InfobarType::kInfobarTypePasswordSave, std::make_unique<PasswordInfobarBannerInteractionHandler>(), /*sheet_handler=*/nullptr, - std::make_unique<PasswordInfobarModalInteractionHandler>()) {} + std::make_unique<PasswordInfobarModalInteractionHandler>(browser)) {} PasswordInfobarInteractionHandler::~PasswordInfobarInteractionHandler() = default;
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.h index 50c58649..29dbfc0d 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.h +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.h
@@ -7,12 +7,14 @@ #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_modal_interaction_handler.h" +@protocol ApplicationSettingsCommands; +class Browser; class IOSChromeSavePasswordInfoBarDelegate; class PasswordInfobarModalInteractionHandler : public InfobarModalInteractionHandler { public: - PasswordInfobarModalInteractionHandler(); + PasswordInfobarModalInteractionHandler(Browser* browser); ~PasswordInfobarModalInteractionHandler() override; // Instructs the handler to update the credentials with |username| and @@ -43,6 +45,12 @@ // InfobarInteractionHandler::Handler: void InfobarVisibilityChanged(InfoBarIOS* infobar, bool visible) override; + protected: + // TODO(crbug.com/1040653): This class is only subclassed as a mock for use in + // tests. This constructor can be removed once the password infobar delegate + // is refactored for testing and this class no longer needs to be mocked. + PasswordInfobarModalInteractionHandler(); + private: // InfobarModalInteractionHandler: std::unique_ptr<InfobarModalOverlayRequestCallbackInstaller> @@ -50,6 +58,9 @@ // Returns the password delegate from |infobar|. IOSChromeSavePasswordInfoBarDelegate* GetDelegate(InfoBarIOS* infobar); + + // Dispatcher used to open the password settings. + id<ApplicationSettingsCommands> settings_command_handler_ = nil; }; #endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_PASSWORDS_PASSWORD_INFOBAR_MODAL_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.mm index 5ef4334..5c305577 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler.mm
@@ -6,7 +6,10 @@ #include "ios/chrome/browser/infobars/infobar_ios.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_overlay_request_callback_installer.h" +#include "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h" +#include "ios/chrome/browser/ui/commands/application_commands.h" +#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -15,6 +18,14 @@ PasswordInfobarModalInteractionHandler:: PasswordInfobarModalInteractionHandler() = default; +PasswordInfobarModalInteractionHandler::PasswordInfobarModalInteractionHandler( + Browser* browser) + : settings_command_handler_( + HandlerForProtocol(browser->GetCommandDispatcher(), + ApplicationSettingsCommands)) { + DCHECK(settings_command_handler_); +} + PasswordInfobarModalInteractionHandler:: ~PasswordInfobarModalInteractionHandler() = default; @@ -34,7 +45,7 @@ void PasswordInfobarModalInteractionHandler::PresentPasswordsSettings( InfoBarIOS* infobar) { - // TODO(crbug.com/1033154): Show the passwords settings. + [settings_command_handler_ showSavedPasswordsSettingsFromViewController:nil]; } void PasswordInfobarModalInteractionHandler::PerformMainAction(
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler_unittest.mm index e86bab7..3e3b115 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler_unittest.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/passwords/password_infobar_modal_interaction_handler_unittest.mm
@@ -7,10 +7,19 @@ #include "base/test/scoped_feature_list.h" #include "components/infobars/core/infobar_feature.h" #import "ios/chrome/browser/infobars/test/fake_infobar_ios.h" +#import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/overlays/public/overlay_request_queue.h" #import "ios/chrome/browser/passwords/test/mock_ios_chrome_save_passwords_infobar_delegate.h" +#import "ios/chrome/browser/ui/commands/application_commands.h" +#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/infobars/test/fake_infobar_ui_delegate.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/browser/web_state_list/web_state_opener.h" +#import "ios/web/public/test/fakes/test_web_state.h" +#include "ios/web/public/test/web_task_environment.h" #include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -20,11 +29,23 @@ class PasswordInfobarModalInteractionHandlerTest : public PlatformTest { public: PasswordInfobarModalInteractionHandlerTest() - : infobar_( + : mock_command_receiver_( + OCMStrictProtocolMock(@protocol(ApplicationSettingsCommands))), + infobar_( [[FakeInfobarUIDelegate alloc] init], MockIOSChromeSavePasswordInfoBarDelegate::Create(@"username", @"password")) { scoped_feature_list_.InitWithFeatures({kIOSInfobarUIReboot}, {}); + [browser_.GetCommandDispatcher() + startDispatchingToTarget:mock_command_receiver_ + forProtocol:@protocol(ApplicationSettingsCommands)]; + handler_ = + std::make_unique<PasswordInfobarModalInteractionHandler>(&browser_); + } + ~PasswordInfobarModalInteractionHandlerTest() override { + [browser_.GetCommandDispatcher() + stopDispatchingToTarget:mock_command_receiver_]; + EXPECT_OCMOCK_VERIFY(mock_command_receiver_); } MockIOSChromeSavePasswordInfoBarDelegate& mock_delegate() { @@ -34,8 +55,11 @@ protected: base::test::ScopedFeatureList scoped_feature_list_; + web::WebTaskEnvironment task_environment_; + TestBrowser browser_; + id mock_command_receiver_ = nil; InfoBarIOS infobar_; - PasswordInfobarModalInteractionHandler handler_; + std::unique_ptr<PasswordInfobarModalInteractionHandler> handler_; }; // Tests that UpdateCredentials() forwards the call to the mock delegate. @@ -43,13 +67,20 @@ NSString* username = @"username"; NSString* password = @"password"; EXPECT_CALL(mock_delegate(), UpdateCredentials(username, password)); - handler_.UpdateCredentials(&infobar_, username, password); + handler_->UpdateCredentials(&infobar_, username, password); } // Tests that NeverSaveCredentials() forwards the call to the mock delegate. TEST_F(PasswordInfobarModalInteractionHandlerTest, NeverSaveCredentials) { EXPECT_CALL(mock_delegate(), Cancel()); - handler_.NeverSaveCredentials(&infobar_); + handler_->NeverSaveCredentials(&infobar_); +} + +// Tests that PresentPasswordsSettings() forwards the call to the mock delegate. +TEST_F(PasswordInfobarModalInteractionHandlerTest, PresentPasswordsSettings) { + OCMExpect([mock_command_receiver_ + showSavedPasswordsSettingsFromViewController:nil]); + handler_->PresentPasswordsSettings(&infobar_); } // Tests PerformMainAction() calls Accept() on the mock delegate and resets @@ -57,7 +88,7 @@ TEST_F(PasswordInfobarModalInteractionHandlerTest, MainAction) { ASSERT_FALSE(infobar_.accepted()); EXPECT_CALL(mock_delegate(), Accept()).WillOnce(testing::Return(true)); - handler_.PerformMainAction(&infobar_); + handler_->PerformMainAction(&infobar_); EXPECT_TRUE(infobar_.accepted()); } @@ -65,7 +96,7 @@ // InfobarDismissed() on the mock delegate. TEST_F(PasswordInfobarModalInteractionHandlerTest, InfobarVisibilityChanged) { EXPECT_CALL(mock_delegate(), InfobarPresenting(/*automatic=*/false)); - handler_.InfobarVisibilityChanged(&infobar_, true); + handler_->InfobarVisibilityChanged(&infobar_, true); EXPECT_CALL(mock_delegate(), InfobarDismissed()); - handler_.InfobarVisibilityChanged(&infobar_, false); + handler_->InfobarVisibilityChanged(&infobar_, false); }
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h index e6655b1..b1b3ca7 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.h +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -7,9 +7,7 @@ #import <UIKit/UIKit.h> -namespace ios { -class ChromeBrowserState; -} +#include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h" @protocol BubblePresenterDelegate; @class BubbleViewControllerPresenter;
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index 982ce12..f493b04 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -41,6 +41,9 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browsing_data", "//ios/chrome/browser/crash_report", + "//ios/chrome/browser/crash_report:crash_report_internal", + "//ios/chrome/browser/crash_report/breadcrumbs", + "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", "//ios/chrome/browser/main", "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/payments", @@ -87,8 +90,6 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browsing_data", "//ios/chrome/browser/crash_report:crash_report_internal", - "//ios/chrome/browser/crash_report/breadcrumbs", - "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", "//ios/chrome/browser/device_sharing", "//ios/chrome/browser/download", "//ios/chrome/browser/main",
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm index f7627af..20e9420b 100644 --- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm +++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -9,8 +9,6 @@ #include "base/strings/sys_string_conversions.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/crash_report/crash_report_helper.h" #import "ios/chrome/browser/device_sharing/device_sharing_manager.h" #import "ios/chrome/browser/main/browser.h" @@ -165,9 +163,6 @@ (id<BrowserStateStorageSwitching>)storageSwitcher { if ((self = [super init])) { _browserState = browserState; - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - breakpad::MonitorBreadcrumbsForBrowserState(_browserState); - } _applicationCommandEndpoint = applicationCommandEndpoint; _browsingDataCommandEndpoint = browsingDataCommandEndpoint; _appURLLoadingService = appURLLoadingService; @@ -269,10 +264,6 @@ if (_mainBrowser.get()) { TabModel* tabModel = self.mainBrowser->GetTabModel(); WebStateList* webStateList = self.mainBrowser->GetWebStateList(); - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - BreadcrumbManagerBrowserAgent::FromBrowser(self.mainBrowser) - ->SetLoggingEnabled(false); - } breakpad::StopMonitoringTabStateForWebStateList(webStateList); breakpad::StopMonitoringURLsForWebStateList(webStateList); [tabModel disconnect]; @@ -288,10 +279,6 @@ if (_otrBrowser.get()) { TabModel* tabModel = self.otrBrowser->GetTabModel(); WebStateList* webStateList = self.otrBrowser->GetWebStateList(); - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - BreadcrumbManagerBrowserAgent::FromBrowser(self.otrBrowser) - ->SetLoggingEnabled(false); - } breakpad::StopMonitoringTabStateForWebStateList(webStateList); [tabModel disconnect]; _activeWebStateObservationForwarders[webStateList] = nullptr; @@ -365,10 +352,6 @@ // Stop watching the OTR webStateList's state for crashes. breakpad::StopMonitoringTabStateForWebStateList( self.otrBrowser->GetWebStateList()); - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - breakpad::StopMonitoringBreadcrumbsForBrowserState( - self.otrBrowser->GetBrowserState()); - } // At this stage, a new incognitoBrowserCoordinator shouldn't be lazily // constructed by calling the property getter. @@ -429,13 +412,6 @@ [self setMainBrowser:nullptr]; [self setOtrBrowser:nullptr]; - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - if (_browserState->HasOffTheRecordChromeBrowserState()) { - breakpad::StopMonitoringBreadcrumbsForBrowserState( - _browserState->GetOffTheRecordChromeBrowserState()); - } - breakpad::StopMonitoringBreadcrumbsForBrowserState(_browserState); - } _browserState = nullptr; } @@ -447,9 +423,6 @@ ios::ChromeBrowserState* otrBrowserState = _browserState->GetOffTheRecordChromeBrowserState(); DCHECK(otrBrowserState); - if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - breakpad::MonitorBreadcrumbsForBrowserState(otrBrowserState); - } std::unique_ptr<Browser> browser = Browser::Create(otrBrowserState); BrowserList* browserList =
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 4f5dae13..c1f7323 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -24,7 +24,12 @@ #include "ios/chrome/browser/browsing_data/browsing_data_remover_factory.h" #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/chrome_url_util.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" +#include "ios/chrome/browser/crash_report/crash_report_helper.h" #include "ios/chrome/browser/main/browser.h" #include "ios/chrome/browser/ntp/features.h" #include "ios/chrome/browser/payments/ios_payment_instrument_launcher.h" @@ -479,6 +484,11 @@ // TODO(crbug.com/779791) : Remove show settings commands from MainController. - (void)showSavedPasswordsSettingsFromViewController: (UIViewController*)baseViewController { + if (!baseViewController) { + // TODO(crbug.com/779791): Don't pass base view controller through + // dispatched command. + baseViewController = [self.mainController currentBVC]; + } DCHECK(!self.signinInteractionCoordinator.isSettingsViewPresented); if (self.settingsNavigationController) { [self.settingsNavigationController @@ -1287,19 +1297,35 @@ BOOL otrBVCIsCurrent = (self.interfaceProvider.mainInterface.bvc == self.interfaceProvider.incognitoInterface.bvc); - // Clear the OTR tab model and notify the _tabSwitcher that its otrBVC will - // be destroyed. + // Clear the Incognito Browser and notify the _tabSwitcher that its otrBrowser + // will be destroyed. [self.mainController.tabSwitcher setOtrBrowser:nil]; + if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { + BreadcrumbManagerBrowserAgent::FromBrowser(self.incognitoInterface.browser) + ->SetLoggingEnabled(false); + + breakpad::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( + self.incognitoInterface.browserState)); + } + [self.mainController.browserViewWrangler destroyAndRebuildIncognitoBrowser]; + if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { + breakpad::MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( + self.incognitoInterface.browserState)); + } + if (otrBVCIsCurrent) { [self activateBVCAndMakeCurrentBVCPrimary]; } - // Always set the new otr tab model for the tablet or grid switcher. - // Notify the _tabSwitcher with the new otrBVC. - [self.mainController.tabSwitcher setOtrBrowser:self.mainInterface.browser]; + // Always set the new otr Browser for the tablet or grid switcher. + // Notify the _tabSwitcher with the new Incognito Browser. + [self.mainController.tabSwitcher + setOtrBrowser:self.incognitoInterface.browser]; // This seems the best place to deem the destroying and rebuilding the // incognito browser state to be completed.
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc index c075f337..db2dfae 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -2160,7 +2160,7 @@ // imported frame into another one that we can destruct. scoped_refptr<VideoFrame> wrapped_frame = VideoFrame::WrapVideoFrame( output_frame, output_frame->format(), output_frame->visible_rect(), - output_frame->coded_size()); + output_frame->visible_rect().size()); DCHECK(wrapped_frame); image_processor_->Process(
diff --git a/media/gpu/vaapi/vaapi_picture.cc b/media/gpu/vaapi/vaapi_picture.cc index f3236a4..c9d5d22 100644 --- a/media/gpu/vaapi/vaapi_picture.cc +++ b/media/gpu/vaapi/vaapi_picture.cc
@@ -18,6 +18,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target) @@ -25,6 +26,7 @@ make_context_current_cb_(make_context_current_cb), bind_image_cb_(bind_image_cb), size_(size), + visible_size_(visible_size), texture_id_(texture_id), client_texture_id_(client_texture_id), texture_target_(texture_target),
diff --git a/media/gpu/vaapi/vaapi_picture.h b/media/gpu/vaapi/vaapi_picture.h index 0ae1e3c..0364163 100644 --- a/media/gpu/vaapi/vaapi_picture.h +++ b/media/gpu/vaapi/vaapi_picture.h
@@ -59,6 +59,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target); @@ -69,6 +70,7 @@ const BindGLImageCallback bind_image_cb_; const gfx::Size size_; + const gfx::Size visible_size_; const uint32_t texture_id_; const uint32_t client_texture_id_; const uint32_t texture_target_;
diff --git a/media/gpu/vaapi/vaapi_picture_factory.cc b/media/gpu/vaapi/vaapi_picture_factory.cc index 77a5242..ea01697 100644 --- a/media/gpu/vaapi/vaapi_picture_factory.cc +++ b/media/gpu/vaapi/vaapi_picture_factory.cc
@@ -44,7 +44,8 @@ scoped_refptr<VaapiWrapper> vaapi_wrapper, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const PictureBuffer& picture_buffer) { + const PictureBuffer& picture_buffer, + const gfx::Size& visible_size) { // ARC++ sends |picture_buffer| with no texture_target(). DCHECK(picture_buffer.texture_target() == GetGLTextureTarget() || picture_buffer.texture_target() == 0u); @@ -70,15 +71,17 @@ case kVaapiImplementationDrm: picture.reset(new VaapiPictureNativePixmapOzone( std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb, - picture_buffer.id(), picture_buffer.size(), service_texture_id, - client_texture_id, picture_buffer.texture_target())); + picture_buffer.id(), picture_buffer.size(), visible_size, + service_texture_id, client_texture_id, + picture_buffer.texture_target())); break; #elif defined(USE_EGL) case kVaapiImplementationDrm: picture.reset(new VaapiPictureNativePixmapEgl( std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb, - picture_buffer.id(), picture_buffer.size(), service_texture_id, - client_texture_id, picture_buffer.texture_target())); + picture_buffer.id(), picture_buffer.size(), visible_size, + service_texture_id, client_texture_id, + picture_buffer.texture_target())); break; #endif @@ -86,8 +89,9 @@ case kVaapiImplementationX11: picture.reset(new VaapiTFPPicture( std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb, - picture_buffer.id(), picture_buffer.size(), service_texture_id, - client_texture_id, picture_buffer.texture_target())); + picture_buffer.id(), picture_buffer.size(), visible_size, + service_texture_id, client_texture_id, + picture_buffer.texture_target())); break; #endif // USE_X11
diff --git a/media/gpu/vaapi/vaapi_picture_factory.h b/media/gpu/vaapi/vaapi_picture_factory.h index 6b3867a..09edc66 100644 --- a/media/gpu/vaapi/vaapi_picture_factory.h +++ b/media/gpu/vaapi/vaapi_picture_factory.h
@@ -36,7 +36,8 @@ scoped_refptr<VaapiWrapper> vaapi_wrapper, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const PictureBuffer& picture_buffer); + const PictureBuffer& picture_buffer, + const gfx::Size& visible_size); // Return the type of the VaapiPicture implementation for the given GL // implementation.
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc index e76693c..941f24cc 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
@@ -21,6 +21,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target) @@ -29,6 +30,7 @@ bind_image_cb, picture_buffer_id, size, + visible_size, texture_id, client_texture_id, texture_target) {}
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.h b/media/gpu/vaapi/vaapi_picture_native_pixmap.h index 4904e0a..a77583a 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.h
@@ -31,6 +31,7 @@ const BindGLImageCallback& bind_image_cb_, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target);
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc index 157980c..edcd25c 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc
@@ -21,6 +21,7 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, + const gfx::Size& visible_size, const gfx::Size& size, uint32_t texture_id, uint32_t client_texture_id, @@ -30,6 +31,7 @@ bind_image_cb, picture_buffer_id, size, + visible_size, texture_id, client_texture_id, texture_target) { @@ -75,7 +77,8 @@ if (make_context_current_cb_ && !make_context_current_cb_.Run()) return false; - auto image = base::MakeRefCounted<gl::GLImageNativePixmap>(size_, format); + auto image = + base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format); // Create an EGLImage from a gl texture if (!image->InitializeFromTexture(texture_id_)) { DLOG(ERROR) << "Failed to initialize eglimage from texture id: " @@ -90,6 +93,14 @@ return false; } + if (size_.width() > static_cast<int>(native_pixmap_handle.planes[0].stride) || + size_.GetArea() > static_cast<int>(native_pixmap_handle.planes[0].size)) { + DLOG(ERROR) << "EGLImage (stride=" << native_pixmap_handle.planes[0].stride + << ", size=" << native_pixmap_handle.planes[0].size + << "is smaller than size_=" << size_.ToString(); + return false; + } + // Convert NativePixmapHandle to NativePixmapDmaBuf. scoped_refptr<gfx::NativePixmap> native_pixmap_dmabuf( new gfx::NativePixmapDmaBuf(size_, format,
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h index 17708683..6b838cc3 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h
@@ -32,6 +32,7 @@ const BindGLImageCallback& bind_image_cb_, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target);
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc index 51e20c6..0e71833 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc
@@ -22,6 +22,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target) @@ -30,6 +31,7 @@ bind_image_cb, picture_buffer_id, size, + visible_size, texture_id, client_texture_id, texture_target) { @@ -71,11 +73,13 @@ const gfx::BufferFormat format = pixmap->GetBufferFormat(); - auto image = base::MakeRefCounted<gl::GLImageNativePixmap>(size_, format); + auto image = + base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format); if (!image->Initialize(std::move(pixmap))) { LOG(ERROR) << "Failed to create GLImage"; return false; } + gl_image_ = image; if (!gl_image_->BindTexImage(texture_target_)) { LOG(ERROR) << "Failed to bind texture to GLImage"; @@ -113,6 +117,15 @@ gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const auto& plane = gpu_memory_buffer_handle.native_pixmap_handle.planes[0]; + if (size_.width() > static_cast<int>(plane.stride) || + size_.GetArea() > static_cast<int>(plane.size)) { + DLOG(ERROR) << "GpuMemoryBufferHandle (stride=" << plane.stride + << ", size=" << plane.size + << "is smaller than size_=" << size_.ToString(); + return false; + } + ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); // CreateNativePixmapFromHandle() will take ownership of the handle.
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h index 2aefab03..3abdc84b 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h
@@ -31,6 +31,7 @@ const BindGLImageCallback& bind_image_cb_, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target);
diff --git a/media/gpu/vaapi/vaapi_picture_tfp.cc b/media/gpu/vaapi/vaapi_picture_tfp.cc index a42f19b..227c31b 100644 --- a/media/gpu/vaapi/vaapi_picture_tfp.cc +++ b/media/gpu/vaapi/vaapi_picture_tfp.cc
@@ -19,6 +19,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target) @@ -27,6 +28,7 @@ bind_image_cb, picture_buffer_id, size, + visible_size, texture_id, client_texture_id, texture_target),
diff --git a/media/gpu/vaapi/vaapi_picture_tfp.h b/media/gpu/vaapi/vaapi_picture_tfp.h index 78eb8361..830cb6e 100644 --- a/media/gpu/vaapi/vaapi_picture_tfp.h +++ b/media/gpu/vaapi/vaapi_picture_tfp.h
@@ -30,6 +30,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target);
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index 5498ab8..065fdedf 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -688,7 +688,8 @@ (buffer_allocation_mode_ == BufferAllocationMode::kNone) ? vaapi_wrapper_ : vpp_vaapi_wrapper_, - make_context_current_cb_, bind_image_cb_, buffer); + make_context_current_cb_, bind_image_cb_, buffer, + decoder_->GetVisibleRect().size()); RETURN_AND_NOTIFY_ON_FAILURE(picture, "Failed creating a VaapiPicture", PLATFORM_FAILURE, );
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index 83dcc61e..175b03b 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -89,6 +89,7 @@ const BindGLImageCallback& bind_image_cb, int32_t picture_buffer_id, const gfx::Size& size, + const gfx::Size& visible_size, uint32_t texture_id, uint32_t client_texture_id, uint32_t texture_target) @@ -97,6 +98,7 @@ bind_image_cb, picture_buffer_id, size, + visible_size, texture_id, client_texture_id, texture_target) {} @@ -124,19 +126,22 @@ MockVaapiPictureFactory() = default; ~MockVaapiPictureFactory() override = default; - MOCK_METHOD2(MockCreateVaapiPicture, void(VaapiWrapper*, const gfx::Size&)); + MOCK_METHOD3(MockCreateVaapiPicture, + void(VaapiWrapper*, const gfx::Size&, const gfx::Size&)); std::unique_ptr<VaapiPicture> Create( scoped_refptr<VaapiWrapper> vaapi_wrapper, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const PictureBuffer& picture_buffer) override { + const PictureBuffer& picture_buffer, + const gfx::Size& visible_size) override { const uint32_t service_texture_id = picture_buffer.service_texture_ids()[0]; const uint32_t client_texture_id = picture_buffer.client_texture_ids()[0]; - MockCreateVaapiPicture(vaapi_wrapper.get(), picture_buffer.size()); + MockCreateVaapiPicture(vaapi_wrapper.get(), picture_buffer.size(), + visible_size); return std::make_unique<MockVaapiPicture>( std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb, - picture_buffer.id(), picture_buffer.size(), service_texture_id, - client_texture_id, picture_buffer.texture_target()); + picture_buffer.id(), picture_buffer.size(), visible_size, + service_texture_id, client_texture_id, picture_buffer.texture_target()); } }; @@ -288,9 +293,11 @@ if (GetParam().decode_using_client_picture_buffers) { EXPECT_CALL(*mock_vaapi_wrapper_, CreateContext(picture_size)) .WillOnce(Return(true)); - EXPECT_CALL( - *mock_vaapi_picture_factory_, - MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), picture_size)) + EXPECT_CALL(*mock_decoder_, GetVisibleRect()) + .WillRepeatedly(Return(gfx::Rect(picture_size))); + EXPECT_CALL(*mock_vaapi_picture_factory_, + MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), + picture_size, picture_size)) .Times(num_pictures); } else { EXPECT_EQ( @@ -308,8 +315,10 @@ va_surface_ids->resize(kNumReferenceFrames); })), Return(true))); + EXPECT_CALL(*mock_decoder_, GetVisibleRect()) + .WillRepeatedly(Return(gfx::Rect(picture_size))); EXPECT_CALL(*mock_vaapi_picture_factory_, - MockCreateVaapiPicture(_, picture_size)) + MockCreateVaapiPicture(_, picture_size, picture_size)) .Times(num_pictures); }
diff --git a/net/base/net_errors.cc b/net/base/net_errors.cc index 41d8bee..1682fa6 100644 --- a/net/base/net_errors.cc +++ b/net/base/net_errors.cc
@@ -63,8 +63,8 @@ } bool IsHostnameResolutionError(int error) { - return (error == ERR_NAME_NOT_RESOLVED || - error == ERR_NAME_RESOLUTION_FAILED); + DCHECK_NE(ERR_NAME_RESOLUTION_FAILED, error); + return error == ERR_NAME_NOT_RESOLVED; } Error FileErrorToNetError(base::File::Error file_error) {
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc index 76b9bc6..ad7299cf 100644 --- a/net/dns/host_resolver.cc +++ b/net/dns/host_resolver.cc
@@ -242,8 +242,12 @@ // static int HostResolver::SquashErrorCode(int error) { - if (error == OK || error == ERR_IO_PENDING || - error == ERR_NAME_NOT_RESOLVED) { + // TODO(crbug.com/1040686): Once InProcessBrowserTests do not use + // ERR_NOT_IMPLEMENTED to simulate DNS failures, it should be ok to squash + // ERR_NOT_IMPLEMENTED. + // TODO(crbug.com/1043281): Consider squashing ERR_INTERNET_DISCONNECTED. + if (error == OK || error == ERR_IO_PENDING || error == ERR_NOT_IMPLEMENTED || + error == ERR_INTERNET_DISCONNECTED || error == ERR_NAME_NOT_RESOLVED) { return error; } else { return ERR_NAME_NOT_RESOLVED;
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h index 092ac6f..264ab583 100644 --- a/net/dns/host_resolver.h +++ b/net/dns/host_resolver.h
@@ -66,12 +66,9 @@ // On any other returned value, the request was handled synchronously and // |callback| will not be invoked. // - // Results in ERR_NAME_NOT_RESOLVED if the hostname is invalid, or if it is - // an incompatible IP literal (e.g. IPv6 is disabled and it is an IPv6 - // literal). - // - // Results in ERR_DNS_CACHE_MISS if only fast local sources are to be - // queried and a cache lookup attempt fails. + // Results in ERR_NAME_NOT_RESOLVED if the hostname is not resolved. More + // detail about the underlying error can be retrieved using + // GetResolveErrorInfo(). // // The parent HostResolver must still be alive when Start() is called, but // if it is destroyed before an asynchronous result completes, the request
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 884d3ff..632f5b4 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -650,7 +650,7 @@ LogFinishRequest(error); DCHECK(callback_); - std::move(callback_).Run(error); + std::move(callback_).Run(HostResolver::SquashErrorCode(error)); } Job* job() const { return job_; } @@ -3015,7 +3015,7 @@ effective_secure_dns_mode, base::TimeDelta()); request->set_error_info(results.error(), false /* is_secure_network_error */); - return results.error(); + return HostResolver::SquashErrorCode(results.error()); } CreateAndStartJob(effective_query_type, effective_host_resolver_flags,
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 023cae1..1d113c3 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -4261,7 +4261,6 @@ { "name": "brandon.so", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "brightstarkids.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bsidessf.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bunbun.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "burtrum.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "buzzconf.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bytejail.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -5292,7 +5291,6 @@ { "name": "codabix.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "creditkarma.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cryptify.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "crystalchandelierservices.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cwagner.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cyberkov.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cyberpunk.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -6834,7 +6832,6 @@ { "name": "onepluscamps.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "oneway.ga", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "onlinepollsph.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "onqproductions.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "opensrd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "opperwall.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "opus-codium.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -7007,7 +7004,6 @@ { "name": "umidev.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "upboard.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ur-lauber.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "usakitchensandflooring.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "usbtypeccompliant.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "val-sec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "valethound.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -9692,7 +9688,6 @@ { "name": "pxx.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pyol.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pysays.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "qccareerschool.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qcdesignschool.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qceventplanning.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qcmakeupacademy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11070,7 +11065,6 @@ { "name": "nodecompat.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "niouininon.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nippombashi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "nowlas.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "novawave.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nordiccasinocommunity.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "norrliden.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12861,7 +12855,6 @@ { "name": "ingalls.run", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ins1gn1a.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "insertcoins.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "instinctiveads.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "intafe.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "integraxor.com.tw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "intencje.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -13826,7 +13819,6 @@ { "name": "2cv-fahrer.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "al-f.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "1k8b.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "41844.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "alicestudio.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "4-it.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aigcev.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -15135,7 +15127,6 @@ { "name": "sepalandseed.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sequiturs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "significados.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sift-tool.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "shux.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "skyline.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "selectary.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16917,7 +16908,6 @@ { "name": "analyticsinmotion.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "androticsdirect.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "alfa-tech.su", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "adrianseo.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "alfa24.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "anotherfatgeek.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "alisonisrealestate.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -18775,7 +18765,6 @@ { "name": "threecrownsllp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thetrendspotter.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tofilmhub.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "tarsashaz-biztositas.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tloxygen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thriveta.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tosainu.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22059,7 +22048,6 @@ { "name": "l0re.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lambauer.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lanna.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "lasrecetasdeguada.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lastrada-minden.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "law-peters.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lawrence-institute.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22454,7 +22442,6 @@ { "name": "touchscreen-handy.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tpms4u.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "trabajarenperu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "trabajarenremoto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tracalada.cl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "transl8.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "travel-kuban.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22709,7 +22696,6 @@ { "name": "adlerweb.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "administratorserwera.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "admongo.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "adnseguros.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "adrafinil.wiki", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "adriancohea.ninja", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "advantagehomeexteriors.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22831,7 +22817,6 @@ { "name": "anymetrix.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "anyon.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aozora.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "apertis.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "apila.care", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aplikaceproandroid.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aplu.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -23163,7 +23148,6 @@ { "name": "chanoyu-gakkai.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "chaos.run", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "chaospott.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "chaouby.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "charbonnel.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "charles-darwin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "charlestonfacialplastic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -24036,7 +24020,6 @@ { "name": "hulsoft.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "human-clone.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "humanenrich.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "humans.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "humanzee.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "humblebee.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "humblebee.foundation", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -24239,7 +24222,6 @@ { "name": "jrtapsell.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jslidong.top", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "juan23.edu.uy", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "juanmaguitar.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "juergen-elbert.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "juka.pp.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "julegoerke.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -26161,7 +26143,6 @@ { "name": "888lu.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "100-downloads.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "5533445.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "33445.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "8888av.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "0xdc.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "023sec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -29727,7 +29708,6 @@ { "name": "bonaccorso.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "boueki.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "booox.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bodsch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "biomodra.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "breadandlife.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bitroll.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -31843,7 +31823,6 @@ { "name": "fr0zenbits.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "frugalfamilyhome.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gallicrooster.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "geaskb.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "geleia-real.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "giftmaniabrilhos.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "globalprojetores.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -38373,7 +38352,6 @@ { "name": "america.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ameriikanpoijat.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amielucha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "amitpatra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ammanagingdirectors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amosng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "andariegocusco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -39463,7 +39441,6 @@ { "name": "passvanille-reservation.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "patentados.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "patika-biztositas.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pay.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcdocjim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peaceispossible.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pearlcohen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -39807,7 +39784,6 @@ { "name": "trade-arcade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "travel1x1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "travellovers.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "treaslockbox.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "treetopsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tribly.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "troomcafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -40552,7 +40528,6 @@ { "name": "pbcomp.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pdxtowncar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peaceloveandlabor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pedikura-vitu.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pelletizermill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pendriveapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pengumuman.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -43036,7 +43011,6 @@ { "name": "roundaboutweb.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ruquay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "salvaalocombia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "schmelle.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "scpslgame.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "securitysense.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "see.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -43140,7 +43114,6 @@ { "name": "xy7373.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ycherbonnel.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yh35.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "yigujin.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "youareme.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "younl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "your-erotic-stories.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -43803,7 +43776,6 @@ { "name": "wichitafoundationpros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wirkaufendeinau.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wlwlwx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wow-screenshots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ws-meca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wsadek.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "www-9822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44307,7 +44279,6 @@ { "name": "nibo.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nicsezcheckfbi.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "niffler.software", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ninjio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nodecraft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "noelclaremont.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "noleggio-bagni-chimici.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44841,7 +44812,6 @@ { "name": "vapensiero.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vda.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wateroutlook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wayfair.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webministeriet.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webnames.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "werkz.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44972,7 +44942,6 @@ { "name": "inchenaim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "indexyz.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "industriasrenova.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "international-nash-day.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ioliver.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ipadkaitori.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itesign.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -48070,7 +48039,6 @@ { "name": "outdoorlightingwestlakevillage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ovelhaostra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "overamsteluitgevers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "oxygin.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pablofain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pacificpalisadeselectric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pacificpalisadeselectrician.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49519,7 +49487,6 @@ { "name": "woltlab-demo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "woofsbakery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "woomai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "workoptions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "worldmeteo.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "worldofarganoil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wpsitemovers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49549,7 +49516,6 @@ { "name": "zander.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zenchain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zentiweb.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "zhengouwu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zhimajk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zhthings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zlaty-tyden.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49609,7 +49575,6 @@ { "name": "cashbook.co.tz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catchhimandkeephim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catl.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ccavenue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cccwien.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ceoptique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ch47f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -50412,7 +50377,6 @@ { "name": "hti.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hubapi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hubspot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "huffsinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "huskyeye.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hydrosight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hyparia.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -51987,7 +51951,6 @@ { "name": "neteraser.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nethostingtalk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nex.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nl3ehv.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "notarkrauss.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nulap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nxit.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53522,7 +53485,6 @@ { "name": "hysh.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iaminashittymood.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ianvisits.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ibe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iblackfriday.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "icetiger.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "idesoft.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53549,7 +53511,6 @@ { "name": "isavings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iskanderbroere.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "islavolcan.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "itspecialista.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itsundef.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iurisnow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ivy-league-colleges.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55307,7 +55268,6 @@ { "name": "ebenvloedaanleggen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "echobridgepartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "echtes-hutzelbrot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "echtgeld-casinos.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eclanet.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ecliptic.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "edi-gate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -56064,7 +56024,6 @@ { "name": "westernpadermatologist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "westside-pediatrics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "weswitch4u.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wettanbieter-vergleich.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wewin88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wewin88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wheresbuzz.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -57075,7 +57034,6 @@ { "name": "naturalezafengshui.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "natverkstekniker.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "naughtytoy.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "naut.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "navstivime.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ndum.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nederland.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -59837,7 +59795,6 @@ { "name": "olivier-rochet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "omegarazer.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "onehost.blue", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "online-biblio.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "onlinecasinoselite.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "opcionpublicitaria.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "open-ctp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -59949,7 +59906,6 @@ { "name": "reddingsbrigadeveghel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "regensburg-repariert.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "remembermidi.sytes.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "rena.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "resdon.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "respons.je", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "respons.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -60078,7 +60034,6 @@ { "name": "sunbury.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sunhaoxiang.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sunplay.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "supplementswatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sustc.ac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sv-schody.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sweepy.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62409,7 +62364,6 @@ { "name": "q1000.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "qualitywaterproofing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ranobe.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "rapidminer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rawcode.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rawpearls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rdactive.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63161,7 +63115,6 @@ { "name": "l0v0l.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lambertz.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lapatio.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lauraohagan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "laurineprice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lawabidingcactus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "leiyinan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63374,7 +63327,6 @@ { "name": "bestladyshaver.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "betrifft-mich-dsgvo.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bi1gif.radio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "bigadcompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "biosalts.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bongloy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bonus.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63510,7 +63462,6 @@ { "name": "lsh1688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lucasit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "magicbeanschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "marioberluchi.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marjorie-wiki.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "market-vanna.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "markshroyer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63699,7 +63650,6 @@ { "name": "attiremr.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "autorijschooljohanbos.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "available.direct", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "badgr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bakerviewdentalcentre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "banka.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "barcelonabagels.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -65720,7 +65670,6 @@ { "name": "arilto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arkhvoid.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "auburn-housekeeper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "badgr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bagnichimici.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bargainsettelement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "baron14.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -68827,7 +68776,6 @@ { "name": "btt1212.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt2020.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt2121.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "btt256.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt381g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt686.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt8.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -69183,7 +69131,6 @@ { "name": "rr6957.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rssl.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "russelljohn.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "rylandgoldman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "s6729.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "s6729.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "s6957.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -69984,7 +69931,6 @@ { "name": "idealize.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilc666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ime-a-tolerancia-eredmenye.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "imediamyanmar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "imediasingapore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "immivest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "inboxceo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -70664,7 +70610,6 @@ { "name": "ag6211.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ag88110.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ag88220.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ag88799.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "agyacht.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ai-media.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aj-foster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -70753,7 +70698,6 @@ { "name": "ebteam.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ecalculator.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "edcaptain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "eet.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eikentafels.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eisblau.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "elldus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -71711,7 +71655,6 @@ { "name": "boxtreeclinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "brickadia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btopc.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "btt6262a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buysoft.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "byfeldt.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cadastroloteamento.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -71787,7 +71730,6 @@ { "name": "fb.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fgsv-heureka.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "filedesc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fireflyiii.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "firerain.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "firmajulegaver.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fite.family", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -73259,9 +73201,6 @@ { "name": "918bip.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "918bis.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "918bit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "918ddo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "918ddx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "918ffa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "918nn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "918ze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "91d91.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -73625,7 +73564,6 @@ { "name": "btt0505.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt0606.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt11.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "btt216.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt583g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt7878.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt829.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -73633,7 +73571,6 @@ { "name": "btt889g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btt918958.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "btta16.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "btta26.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buddy-acceptance-authentication-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buddy-acceptance-profiles-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "buddy-acceptance-users-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -75039,7 +74976,6 @@ { "name": "t88hh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t88kk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t88ll.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88rr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t88uu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t88ww.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t88yy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -76181,7 +76117,6 @@ { "name": "lierohell.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "life-in-hell.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lightsfromspace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lilai107.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lilai18.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lilai634.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "limstash.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -76203,7 +76138,6 @@ { "name": "livejh.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "livetopknigi.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "livfcshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lldy88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "localtownhouses.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "logicdream.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lojadkstore.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -77951,7 +77885,6 @@ { "name": "eznetworks.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f8036.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f81818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fbe.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ff18.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fh169.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "finotax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78329,7 +78262,6 @@ { "name": "bastide-viens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "berksarl.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bestcomputersecuritybooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "beyondboxgifts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bhthome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "biftin.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "binaries.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78527,7 +78459,6 @@ { "name": "obu4alka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oe2018.gov.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oe2019.gov.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "onlinekocunuz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "only.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ontourmarketing.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ontrio.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -78918,7 +78849,6 @@ { "name": "raveboy.dyndns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "raydius.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "reeves-family.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "renedekoeijer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rheijmans.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ribella.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "richieheijmans.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79325,7 +79255,6 @@ { "name": "sevipro.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shakthifacility.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "siamericas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "sianipestcontrolinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "simplysmartgardening.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sipstix.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "skaginn.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79801,7 +79730,6 @@ { "name": "caycehouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cbnainital.org.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ccli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "centralhealthplan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "centrumpieknairelaksu.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chartsheets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chiavistello.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79840,7 +79768,6 @@ { "name": "drsheri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ea-lateleassistance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eaglemoe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "easypets.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ecotechnologyti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "elprint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "emeraldislerealty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79885,7 +79812,6 @@ { "name": "justin-p.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kb702.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kb7474.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kb88dc28.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kilbi-reussbuehl.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kingdominnergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kingshome.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79903,7 +79829,6 @@ { "name": "kstr.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lacochinacounselor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lacocina.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "landsbankinn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lederkleren.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "leoservicosetc.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "leruevintage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79915,7 +79840,6 @@ { "name": "lorenzocampagna.myqnapcloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ltcwaterwijk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "macaos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "madeinolive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "magniflood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mangabank.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mansora.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -79959,7 +79883,6 @@ { "name": "parkeerbordenhuren.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paroisses-theix-surzur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcdbank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pfonks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "piektraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pitoufi.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "planisys.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -81450,7 +81373,6 @@ { "name": "fam-borsch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fantasticcleanersbristol.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fastighetsekonomi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ferc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fetishbazar.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ff00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fffinfo.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -84909,7 +84831,6 @@ { "name": "daie-inc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dailychristianpodcast.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dailyrenewblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "danndorf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davidgroup.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "davidops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dcave.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -86265,7 +86186,6 @@ { "name": "wijnlandkroatie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wpcc.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wwmm.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xebeche.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xin-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xin-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xing-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -86762,7 +86682,6 @@ { "name": "mijam.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mijnkantoor.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mikedhoore.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "milkkids.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "minibaggerverleih-aulendorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "missmaid.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "missmaid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87506,7 +87425,6 @@ { "name": "mau.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mau.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "maxiglobal.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mczone.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meekhak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meinephbern.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meldpuntemma.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87536,7 +87454,6 @@ { "name": "niederalt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nlc.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nopaincenter.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "npu.best", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nunu.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "o81365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "o82365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88088,7 +88005,6 @@ { "name": "lermer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "levante.net.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "libreho.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lightwitch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lintelliftdks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "loukas-stoltz.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lucklesslovelocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88142,7 +88058,6 @@ { "name": "neverguess.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "newcontext.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nhglobalpartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nixval.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nordlocker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nordpass.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nordsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -89916,22 +89831,15 @@ { "name": "3651203.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3651204.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3651205.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "365123456.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "3653650000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "3653651111.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "3653653333.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "3653654444.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "3655053.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "51cls.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "616578.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "616728.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "616758.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "616798.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "666648.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "6upagent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "76678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "878989.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "96678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "a1demolitionhauling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "a66.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "a6619.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -89974,7 +89882,6 @@ { "name": "arminsure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avgindiantech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avhwelding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b538.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b5901.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b5902.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b5903.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -89984,8 +89891,6 @@ { "name": "b5907.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b5908.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b5910.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b6530.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b6531.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "barkstop.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "basedos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bayer.earth", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90085,7 +89990,6 @@ { "name": "howtorunfasterandlonger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "humitat-stop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "huntyourshitaround.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "i36588.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "i7.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilab.health", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iletisimmakinesi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90328,21 +90232,6 @@ { "name": "x59788.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x59888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x59988.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x7713.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x7719.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x7782.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x7785.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x7795.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77dd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77hh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77jj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77kk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77mm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77nn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77pp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77qq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77tt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "x77ww.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x98d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x98e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x98f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90371,29 +90260,9 @@ { "name": "xpj000555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpj000666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpj678678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj909.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj909.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj909.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpj909.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj909.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj919.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj919.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpj919.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpjbeting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xpjcs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjcu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjdi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjfan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjmd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjtop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjwa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjwb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjwc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "xpjwd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "y365188.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yellsy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yourbusinesscommunity.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yourdomain.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90423,7 +90292,6 @@ { "name": "0117552.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "0127552.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "0137552.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "0319z6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "1004233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "111ttt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "1me.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90461,7 +90329,6 @@ { "name": "7552011.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "7552012.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "7552013.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "aa4888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "abcorporate-aviation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "abcorporate-aviation.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adventurealpinetreks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90499,9 +90366,6 @@ { "name": "b89cc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b89dd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b89ee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b89ff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b89gg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "b89hh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b89ii.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "b89jj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "backtheeffup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90904,27 +90768,6 @@ { "name": "symeonchen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "systemnik.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "szotkowski.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8803.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8805.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8807.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8809.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8815.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8817.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8819.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t8830.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88jj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88mm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88nn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88oo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88ss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip0.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip3.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip5.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "t88vip7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "talkaboutdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tandakutip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tauran.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90954,19 +90797,6 @@ { "name": "transfurrmation.town", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tripsweet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "truyenfull.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt0766.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt0966.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt2866.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt3699.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt3766.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt3999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt7199.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt7299.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt7399.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt8166.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt8266.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt8366.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tt9799.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "turm-umzuege.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ua-blacklist.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ucb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -90991,27 +90821,9 @@ { "name": "vokieciupamokos.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vonpawn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vschafer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w000999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w123123.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w234234.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w456456.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w567567.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w66w66.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w678678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w789789.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w81519.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w888011.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888033.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888044.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w888055.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888066.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888077.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888088.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w888099.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "w99w99.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wallisdiervoeding.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webtrees.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wercat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91046,6 +90858,638 @@ { "name": "zoftbaby.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zusterjansen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zwilla.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "11ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "123viajando.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "12ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "13ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "16ag6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1abcicka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22ag6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "345678365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "365.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "36ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4pillarsit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "567667.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "61ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "66ag9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "72hours2sold.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "87ag9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8ag8.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "93ag8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abetterdeath.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abi95oha.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abrah.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "academie-essentiel.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adventus.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "afharvey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag01.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag011.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag018.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag022.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag06.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag066.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag08.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag09.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag11.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag123.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag130.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag138.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag13842.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag1386.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag155.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag158.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag1601.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag1603.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag1604.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag1607.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag166.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag271.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2786.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag285.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2855.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag288.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2897.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag2978.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3115.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3117.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3119.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag33.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag388.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3916.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3917.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag393.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag3953.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5152.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5159.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5326.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5358.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5392.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5519.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag556.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5623.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5657.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5662.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5758.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5761.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5852.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5856.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5862.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5876.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5917.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5936.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5939.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5951.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5952.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag5967.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.pub", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.vc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag600.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag618.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6272.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6283.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6291.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6298.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag66567.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag666.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag66668.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6675.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6676.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6819.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6825.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag69000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag6995.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag7.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag72.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag7273.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag77.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag77.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag77655.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag7811.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag7822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag806.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81117.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81119.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81125.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81163.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81191.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag812.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag812.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81211.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81213.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81215.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81268.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81275.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81277.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81279.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81325.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81362.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81393.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81399.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81568.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag816.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81611.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81613.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag818.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag818.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81879.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81881.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag819.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81912.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81917.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag81939.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82001.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82006.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82007.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82008.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82011.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82015.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82018.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82022.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag821.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82135.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8218.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82225.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82226.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag82287.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8400.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag860.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8600.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag865.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8778.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag880.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag891.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag898.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag89951.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag8vip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9005.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag905.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag908.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9100.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag918.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag918.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag918.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag92018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9532.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag955.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag96.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag961.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9621.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9623.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag966.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9792.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9793.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag98.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9800.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9815.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag983.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag992.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9931.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag995.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9973.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ag9vip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agg097.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agg66.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agg77.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agg88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agsogou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agsun6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip1000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip1888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip2001.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip2008.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip2013.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agvip986.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aiden.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aiwansky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akay.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "algoritmususpechu.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amberwiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anamelikian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apadmi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ararrl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ararrl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artj.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "astrobriga.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autosalesmachine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avanpost.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avivamiento-radio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aztv.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ballettstudio-ost.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bastardandpoors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bech32.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "benpfitzner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "big-office.lviv.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blindsjoburg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boschveldtuin.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brunolt.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bulutkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bundesverband-krisenintervention.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bundesverbandkrisenintervention.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "callanjg.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "callqa.center", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caodo.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carespan.clinic", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casamentos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ccsae.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ceska-polygraficka.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "checktech.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "childhr.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chizipoms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chriscampdesigns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "christian-oette.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cichlid-world.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cjpsrilanka.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clubon.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "combustibilaspen.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "commercialcleaningbrisbane.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "concetrabajos.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "consulenzanobiliare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cranenburgh.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cranioo.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crestasantos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crowdstack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cubeo.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyclowiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "d64.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dannyrohde.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-gruenwald.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-isny.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-leutkirch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-oberschwaben.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-ravensburg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-wangen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datenschutz-weingarten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dautuvang.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daysgolfclub.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dealsale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "defamiliehagen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "delicon.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deyanadeco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dienmayplus.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dietlein.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diffuzehr.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "disinfestazioni-sardegna.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dmilb.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dogwalkeru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dotcomtest02-single.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drastik.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drivenbyperspective.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "droidee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dubaire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dusty.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dutchassistancedogs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dys-coaching.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-m1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eggendorfer.wine", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elettricista.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elfuerteclamor.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emby.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emsliespharmacy.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "encanttemais.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "encontroespiritadeinverno.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "engione.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enthasso.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "entrup.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eperniagaan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ergaomnes.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "erictgilmour.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estallidodigital.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ethicalescorts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evergarden.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expanda.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faked.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fallout-craft.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "familie-mueller.com.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fan8hd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ffp-survey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fh14.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "filli-it.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flashcrasher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "floating-journey-64892.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flugschule-usa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "free8hd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freewillfilm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ftrac.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fudubank.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "furukogarasusha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fusionapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fusionapps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galleoncloud.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamanlu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "geekobyte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "genbars.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "genometrik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "glutenfreeandtasty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gmcbm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gon45.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "googlepinyin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gozadera.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greatnetsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "halovanic.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hangarbox.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "happynewyear2020countdown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hawaiiforbernie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heinenhopman.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hispania-valencia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "honeyspot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hooghiemstrazelf.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hostedghost.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hostedghost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hostedghost.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "house-scape.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "humansense.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "huuduc.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "i-connect.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iblowdry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ideamiapublicidad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilfumoshop.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "immedicohospitalario.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infra.beer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infraget.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "insuremyworkcomp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isab.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iskconnews.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ivan1874.dynu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jakobs.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jb0.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jfvaccountants.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jimkimmel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jmisern.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jnssnfotografie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jordandirections.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joseluishenriquez.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k811111.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8cf002.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8cf003.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8cf005.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8cf006.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8cf007.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8top.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn001.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn002.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn003.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn005.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn006.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn007.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn008.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn009.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn010.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn011.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k8vn9999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaiva.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kalhufvudet.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kangutingo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kathy.best", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keeley.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keesslop.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kpnthings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kreuzwortraetsellosungen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "krisenintervention-deutschland.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kriseninterventiondeutschland.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ks7.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lagrange.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lakorntoday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "largeandhighquality.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lawyermidrand.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lebalcondesraspes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leon.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "librairiezbookstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lidl-vins.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linguatrip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lipaslovanska.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liulo.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liverobot8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loonbedrijfdenboer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lowratelocksmith.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lsc.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lubersacr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lucorautopartes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "m3e30.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madix.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mailgun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mailmaid.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mandarinpediatrics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manuelraimo.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "markfisher.photo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "markoglou.com.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "massageandwellbeing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maybeonline.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mccordscvs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcvs.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medicaltools.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medictools.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medunovi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "megasupportcr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meilleursjeuxporno.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mempool.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mens-v.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "milkagyengedseg.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "milkandbourbons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "missionpuppy.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mmichaelb.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "montrain.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moove-it.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mountknowledge.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moving-target.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mycloudsaas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mycrowdstack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nedermisp.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nejmaklerka.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nintendohill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "normapro.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nully.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "okayloser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ontopoflove.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opticsboss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "overlord.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pack.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palessit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcf-frankfurt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pipscprd.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "poirierlavoie.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pojdnafp.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pomdoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "poquiloco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "private-diary-taka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prodigyhq.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "projecttools.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "promoglisse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "puredns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "r3t.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rabbit.finance", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ramdigital.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "randstalker.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "realm-of-shade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rellmusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "repairit.support", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "restaurant-eatenjoy.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "retinacv.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riho.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rimo.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "roar.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robbinsgaragedoorwenatchee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ronbyrne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rscturmoil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rubenpeeters.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saint-sym.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sanates.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sapuseven.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scag9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "securesense.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "semesur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seminarraum-isny.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sequachee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shipito.kg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shipmonk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shippinglabel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shishadenbosch.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smlk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "softskills.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soleil.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soma.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soninger.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "standheizung-shop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steno.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stephengeorge.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stevenkendypierre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stjohncamden.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stmsouthcoventry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "striata.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "striata.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sudosaveclimate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superhappyfun.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sydneyexperiences.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "systemofabrown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "szotkowski.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-unit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tactical.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tallgrasslegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taxedesejour-airbnb.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teallhaycock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tecnopiniones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teplo-unit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tferdinand.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tgtw.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "the-azad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thehoff.ddnss.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "themegteam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thirdwaverevenue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tinf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tkmr-gyouseishosi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tld.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tmhanoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tobiase.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tonalaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topicalnet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topophile.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "torremarsalou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trungvien.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tudienchinhta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u9yy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ufacesign.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "up-stage.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "up-stage.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "upakweship.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "urbanemc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "usawireguard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uzay.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vanuithartenziel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vg-store.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vizedia.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vleo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "volcano-ug.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "volcano-x.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "volcano75.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wagnergroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wcscmp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "we8hd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "websitelia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wetravel.company", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wikilinux.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wildfoxlady.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wippie.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wiseradiology.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wmccancercenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wnuq.best", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wofox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wordpressarequipa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wrong.wang", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "www.gov.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xinyitour.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn----7sbbagp2bcfwdeee1afm.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn----dtbhcpoeofgcvoic1s.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--c1aehtaetb.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--pascal-klsch-cjb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xoan.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xotictrends.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xtom.support", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xyj22.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yachtcita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yalacoins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yatai18.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yayou.ag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yn.org.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yokoda.okinawa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt220.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt605.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt606.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt629.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt653.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt656.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt675.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt835.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt839.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt881.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt892.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt962.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yt972.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zenown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zidanpainting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zumtaedanceschool.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zupit.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zz772.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, // END OF 1-YEAR BULK HSTS ENTRIES // Only eTLD+1 domains can be submitted automatically to hstspreload.org,
diff --git a/net/trust_tokens/BUILD.gn b/net/trust_tokens/BUILD.gn index 9aec1d17..bdc97d0 100644 --- a/net/trust_tokens/BUILD.gn +++ b/net/trust_tokens/BUILD.gn
@@ -6,13 +6,12 @@ source_set("trust_tokens") { visibility = [ - "//net", - "//services/network", ":tests", + "//net/*", + "//services/network/", ] - # TODO(davidvc): Public API to be added in a subsequent CL. - public = [] + public = [ "trust_token_store.h" ] friend = [ ":tests" ] @@ -20,26 +19,35 @@ "in_memory_trust_token_persister.cc", "in_memory_trust_token_persister.h", "trust_token_persister.h", + "trust_token_store.cc", + "types.cc", + "types.h", ] deps = [ - ":public_proto", ":storage_proto", "//base", "//url", ] + + public_deps = [ ":public_proto" ] } source_set("tests") { testonly = true - sources = [ "trust_token_persister_unittest.cc" ] + sources = [ + "trust_token_persister_unittest.cc", + "trust_token_store_unittest.cc", + "types_unittest.cc", + ] deps = [ ":public_proto", ":storage_proto", ":trust_tokens", "//base", + "//base/test:test_support", "//testing/gmock", "//testing/gtest", "//url",
diff --git a/net/trust_tokens/OWNERS b/net/trust_tokens/OWNERS new file mode 100644 index 0000000..53f0470 --- /dev/null +++ b/net/trust_tokens/OWNERS
@@ -0,0 +1,3 @@ +csharrison@chromium.org +svaldez@chromium.org +asanka@chromium.org
diff --git a/net/trust_tokens/proto/public.proto b/net/trust_tokens/proto/public.proto index 1d99729..5700635 100644 --- a/net/trust_tokens/proto/public.proto +++ b/net/trust_tokens/proto/public.proto
@@ -8,13 +8,14 @@ option optimize_for = LITE_RUNTIME; -// A TrustTokenCommitmentKey message represents a single commitment key received -// from an issuer’s key commitments endpoint. -message TrustTokenCommitmentKey { - // The body of the keys. Used for comparison (when checking if +// A TrustTokenKeyCommitment message stores a single key received +// from an issuer’s key commitments endpoint, along with associated +// metadata. +message TrustTokenKeyCommitment { + // The key's body. Used for comparison (when checking if // stored tokens’ keys are still current) and, by BoringSSL, for // cryptographic operations. - optional bytes body = 1; // required + optional bytes key = 1; // required // The expiry time of the key. // (Here and elsewhere, string times are serialized base::Times @@ -36,7 +37,7 @@ // The key with which the Token was signed. Tokens // are only provided to servers while their commitment keys // remain active. - optional bytes commitment_key_body = 2; // required + optional bytes signing_key = 2; // required } // A SignedTrustTokenRedemptionRecord message stores state associated with a @@ -46,8 +47,9 @@ // with the SRR. message SignedTrustTokenRedemptionRecord { // The body of an SRR encodes information such as its top-level - // origin and its expiration time, but Chrome doesn’t control - // the encoding and uses a library to extract these values. + // origin and its expiration time. The encoding is opaque to //net; BoringSSL + // provides interfaces to read data from the body that is pertinent to + // protocol execution. optional bytes body = 1; // If one of public_key or signing_key is present, the other must also be // present.
diff --git a/net/trust_tokens/proto/storage.proto b/net/trust_tokens/proto/storage.proto index adeb5286..fbf8360 100644 --- a/net/trust_tokens/proto/storage.proto +++ b/net/trust_tokens/proto/storage.proto
@@ -10,7 +10,7 @@ import "public.proto"; -// An TrustTokenIssuerConfig message represents persistent state scoped +// A TrustTokenIssuerConfig message represents persistent state scoped // to a single Trust Tokens issuer origin. // An issuer’s config contains: // - any signed-but-unspent tokens received from the issuer; and @@ -18,8 +18,8 @@ // per issuance request), if it has configured one via its key // commitment endpoint. message TrustTokenIssuerConfig { - // Keys the issuer has recently committed (we don’t need to store stale keys) - repeated TrustTokenCommitmentKey keys = 1; + // Keys the issuer has recently committed (no need to store stale keys) + repeated TrustTokenKeyCommitment keys = 1; optional int32 batch_size = 2; repeated TrustToken tokens = 3; // The time of the most recent issuance for this pair. Used for
diff --git a/net/trust_tokens/trust_token_store.cc b/net/trust_tokens/trust_token_store.cc new file mode 100644 index 0000000..cba7772 --- /dev/null +++ b/net/trust_tokens/trust_token_store.cc
@@ -0,0 +1,312 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/trust_tokens/trust_token_store.h" + +#include <memory> +#include <utility> + +#include "base/optional.h" +#include "net/trust_tokens/proto/public.pb.h" +#include "net/trust_tokens/proto/storage.pb.h" +#include "net/trust_tokens/types.h" +#include "third_party/protobuf/src/google/protobuf/repeated_field.h" + +namespace net { + +namespace { +// Until the underlying BoringSSL functionality is implemented to extract +// expiry timestamps from Signed Redemption Record bodies, default to +// never expiring stored SRRs. +class NeverExpiringExpiryDelegate + : public TrustTokenStore::RecordExpiryDelegate { + public: + bool IsRecordExpired( + const SignedTrustTokenRedemptionRecord& record) override { + return false; + } +}; +} // namespace + +TrustTokenStore::TrustTokenStore(std::unique_ptr<TrustTokenPersister> persister) + : TrustTokenStore(std::move(persister), + std::make_unique<NeverExpiringExpiryDelegate>()) {} + +TrustTokenStore::TrustTokenStore( + std::unique_ptr<TrustTokenPersister> persister, + std::unique_ptr<RecordExpiryDelegate> expiry_delegate_for_testing) + : persister_(std::move(persister)), + record_expiry_delegate_(std::move(expiry_delegate_for_testing)) { + DCHECK(persister_); +} + +TrustTokenStore::~TrustTokenStore() = default; + +void TrustTokenStore::RecordIssuance(const url::Origin& issuer) { + DCHECK(!issuer.opaque()); + url::Origin issuer_origin = issuer; + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + if (!config) + config = std::make_unique<TrustTokenIssuerConfig>(); + config->set_last_issuance(internal::TimeToString(base::Time::Now())); + persister_->SetIssuerConfig(issuer, std::move(config)); +} + +base::Optional<base::TimeDelta> TrustTokenStore::TimeSinceLastIssuance( + const url::Origin& issuer) { + DCHECK(!issuer.opaque()); + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + if (!config) + return base::nullopt; + if (!config->has_last_issuance()) + return base::nullopt; + base::Optional<base::Time> maybe_last_issuance = + internal::StringToTime(config->last_issuance()); + if (!maybe_last_issuance) + return base::nullopt; + + base::TimeDelta ret = base::Time::Now() - *maybe_last_issuance; + if (ret < base::TimeDelta()) + return base::nullopt; + + return ret; +} + +void TrustTokenStore::RecordRedemption(const url::Origin& issuer, + const url::Origin& top_level) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + std::unique_ptr<TrustTokenIssuerToplevelPairConfig> config = + persister_->GetIssuerToplevelPairConfig(issuer, top_level); + if (!config) + config = std::make_unique<TrustTokenIssuerToplevelPairConfig>(); + config->set_last_redemption(internal::TimeToString(base::Time::Now())); + persister_->SetIssuerToplevelPairConfig(issuer, top_level, std::move(config)); +} + +base::Optional<base::TimeDelta> TrustTokenStore::TimeSinceLastRedemption( + const url::Origin& issuer, + const url::Origin& top_level) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + auto config = persister_->GetIssuerToplevelPairConfig(issuer, top_level); + if (!config) + return base::nullopt; + if (!config->has_last_redemption()) + return base::nullopt; + base::Optional<base::Time> maybe_last_redemption = + internal::StringToTime(config->last_redemption()); + // internal::StringToTime can fail in the case of data corruption (or writer + // error). + if (!maybe_last_redemption) + return base::nullopt; + + base::TimeDelta ret = base::Time::Now() - *maybe_last_redemption; + if (ret < base::TimeDelta()) + return base::nullopt; + return ret; +} + +bool TrustTokenStore::IsAssociated(const url::Origin& issuer, + const url::Origin& top_level) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + std::unique_ptr<TrustTokenToplevelConfig> config = + persister_->GetToplevelConfig(top_level); + if (!config) + return false; + return base::Contains(config->associated_issuers(), issuer.Serialize()); +} + +void TrustTokenStore::SetAssociation(const url::Origin& issuer, + const url::Origin& top_level) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + std::unique_ptr<TrustTokenToplevelConfig> config = + persister_->GetToplevelConfig(top_level); + if (!config) + config = std::make_unique<TrustTokenToplevelConfig>(); + auto string_issuer = issuer.Serialize(); + if (!base::Contains(config->associated_issuers(), string_issuer)) { + config->add_associated_issuers(std::move(string_issuer)); + persister_->SetToplevelConfig(top_level, std::move(config)); + } +} + +std::vector<TrustTokenKeyCommitment> TrustTokenStore::KeyCommitments( + const url::Origin& issuer) { + DCHECK(!issuer.opaque()); + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + + if (!config) + return std::vector<TrustTokenKeyCommitment>(); + + return std::vector<TrustTokenKeyCommitment>(config->keys().begin(), + config->keys().end()); +} + +void TrustTokenStore::SetKeyCommitmentsAndPruneStaleState( + const url::Origin& issuer, + base::span<const TrustTokenKeyCommitment> keys) { + DCHECK(!issuer.opaque()); + DCHECK([&keys]() { + std::set<base::StringPiece> unique_keys; + for (const auto& key : keys) + unique_keys.insert(base::StringPiece(key.key())); + return unique_keys.size() == keys.size(); + }()); + + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + if (!config) + config = std::make_unique<TrustTokenIssuerConfig>(); + + // Because of the characteristics of the protocol, this will be + // quite small (~3 elements). + google::protobuf::RepeatedPtrField<TrustTokenKeyCommitment> keys_to_add( + keys.begin(), keys.end()); + + for (TrustTokenKeyCommitment& new_key : keys_to_add) { + for (const TrustTokenKeyCommitment& existing_key : config->keys()) { + if (existing_key.key() == new_key.key()) { + // It's safe to break here because of the precondition that + // the commitments in |keys_to_add| have distinct keys. + *new_key.mutable_first_seen_at() = existing_key.first_seen_at(); + break; + } + } + } + + config->mutable_keys()->Swap(&keys_to_add); + + google::protobuf::RepeatedPtrField<TrustToken> filtered_tokens; + for (auto& token : *config->mutable_tokens()) { + if (std::any_of(config->keys().begin(), config->keys().end(), + [&token](const TrustTokenKeyCommitment& key) { + return key.key() == token.signing_key(); + })) + *filtered_tokens.Add() = std::move(token); + } + + config->mutable_tokens()->Swap(&filtered_tokens); + + persister_->SetIssuerConfig(issuer, std::move(config)); +} + +void TrustTokenStore::SetBatchSize(const url::Origin& issuer, int batch_size) { + DCHECK(!issuer.opaque()); + DCHECK(batch_size > 0); + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + if (!config) + config = std::make_unique<TrustTokenIssuerConfig>(); + config->set_batch_size(batch_size); + persister_->SetIssuerConfig(issuer, std::move(config)); +} + +base::Optional<int> TrustTokenStore::BatchSize(const url::Origin& issuer) { + DCHECK(!issuer.opaque()); + std::unique_ptr<TrustTokenIssuerConfig> config = + persister_->GetIssuerConfig(issuer); + if (!config) + return base::nullopt; + if (!config->has_batch_size() || config->batch_size() <= 0) + return base::nullopt; + return config->batch_size(); +} + +void TrustTokenStore::AddTokens(const url::Origin& issuer, + base::span<const std::string> token_bodies, + base::StringPiece issuing_key) { + DCHECK(!issuer.opaque()); + auto config = persister_->GetIssuerConfig(issuer); + DCHECK(config && + std::any_of(config->keys().begin(), config->keys().end(), + [issuing_key](const TrustTokenKeyCommitment& commitment) { + return commitment.key() == issuing_key; + })); + + for (const auto& token_body : token_bodies) { + TrustToken* entry = config->add_tokens(); + entry->set_body(token_body); + entry->set_signing_key(std::string(issuing_key)); + } + + persister_->SetIssuerConfig(issuer, std::move(config)); +} + +std::vector<TrustToken> TrustTokenStore::RetrieveMatchingTokens( + const url::Origin& issuer, + base::RepeatingCallback<bool(const std::string&)> key_matcher) { + DCHECK(!issuer.opaque()); + auto config = persister_->GetIssuerConfig(issuer); + std::vector<TrustToken> matching_tokens; + if (!config) + return matching_tokens; + + std::copy_if(config->tokens().begin(), config->tokens().end(), + std::back_inserter(matching_tokens), + [&key_matcher](const TrustToken& token) { + return token.has_signing_key() && + key_matcher.Run(token.signing_key()); + }); + + return matching_tokens; +} + +void TrustTokenStore::DeleteToken(const url::Origin& issuer, + const TrustToken& to_delete) { + DCHECK(!issuer.opaque()); + auto config = persister_->GetIssuerConfig(issuer); + if (!config) + return; + + for (auto it = config->mutable_tokens()->begin(); + it != config->mutable_tokens()->end(); ++it) { + if (it->body() == to_delete.body()) { + config->mutable_tokens()->erase(it); + break; + } + } + + persister_->SetIssuerConfig(issuer, std::move(config)); +} + +void TrustTokenStore::SetRedemptionRecord( + const url::Origin& issuer, + const url::Origin& top_level, + const SignedTrustTokenRedemptionRecord& record) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + auto config = persister_->GetIssuerToplevelPairConfig(issuer, top_level); + if (!config) + config = std::make_unique<TrustTokenIssuerToplevelPairConfig>(); + *config->mutable_signed_redemption_record() = record; + persister_->SetIssuerToplevelPairConfig(issuer, top_level, std::move(config)); +} + +base::Optional<SignedTrustTokenRedemptionRecord> +TrustTokenStore::RetrieveNonstaleRedemptionRecord( + const url::Origin& issuer, + const url::Origin& top_level) { + DCHECK(!issuer.opaque()); + DCHECK(!top_level.opaque()); + auto config = persister_->GetIssuerToplevelPairConfig(issuer, top_level); + if (!config) + return base::nullopt; + + if (!config->has_signed_redemption_record()) + return base::nullopt; + + if (record_expiry_delegate_->IsRecordExpired( + config->signed_redemption_record())) + return base::nullopt; + + return config->signed_redemption_record(); +} + +} // namespace net
diff --git a/net/trust_tokens/trust_token_store.h b/net/trust_tokens/trust_token_store.h new file mode 100644 index 0000000..374db08 --- /dev/null +++ b/net/trust_tokens/trust_token_store.h
@@ -0,0 +1,224 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_ +#define NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/optional.h" +#include "base/time/time.h" +#include "net/trust_tokens/proto/public.pb.h" +#include "net/trust_tokens/trust_token_persister.h" +#include "net/trust_tokens/types.h" +#include "url/origin.h" + +namespace net { + +// A TrustTokenStore provides operations on persistent state necessary for +// the various steps of the Trust TrustTokens protocol. +// +// For more information about the protocol, see the explainer at +// https://github.com/WICG/trust-token-api. +// +// TrustTokenStore translates operations germane to different steps +// of token issuance, token redemption, and request signing into +// operations in the key-value representation used by the persistence +// layer. +// +// For example, it provides operations: +// - checking preconditions for the different protocol steps; +// - storing unblinded, signed tokens; and +// - managing Signed Redemption Records (SRRs) and corresponding key pairs. +// +// TrustTokenStore's methods do minimal precondition checking and, in +// particular, only selectively verify protocol-level invariants and +// input integrity. +class TrustTokenStore { + public: + class RecordExpiryDelegate { + public: + virtual ~RecordExpiryDelegate() = default; + + // Returns whether the given Signed Redemption Record has expired. + // This is implemented with a delegate to abstract away reading + // the values of SRRs (they're opaque to this store). + virtual bool IsRecordExpired( + const SignedTrustTokenRedemptionRecord& record) = 0; + }; + + // Creates a new TrustTokenStore passing read and write operations through + // to the given persister. + // + // Until the underlying BoringSSL functionality is implemented to extract + // expiry timestamps from Signed Redemption Record bodies, defaults to + // never expiring stored SRRs. + // + // |persister| must not be null. + explicit TrustTokenStore(std::unique_ptr<TrustTokenPersister> persister); + + // Creates a TrustTokenStore relying on the given delegate for judging whether + // signed redemption records have expired. + // + // |persister| must not be null. + TrustTokenStore( + std::unique_ptr<TrustTokenPersister> persister, + std::unique_ptr<RecordExpiryDelegate> expiry_delegate_for_testing); + + virtual ~TrustTokenStore(); + + //// Methods related to ratelimits: + + // Updates the given issuer's last issuance time to now. + // + // |issuer| must not be opaque. + virtual void RecordIssuance(const url::Origin& issuer); + + // Returns the time since the last call to RecordIssuance for + // issuer |issuer|, or nullopt in the following two cases: + // 1. there is no currently-recorded prior issuance for the + // issuer, or + // 2. the time since the last issuance is negative (because + // of, for instance, corruption or clock skew). + // + // |issuer| must not be opaque. + WARN_UNUSED_RESULT virtual base::Optional<base::TimeDelta> + TimeSinceLastIssuance(const url::Origin& issuer); + + // Updates the given (issuer, top-level) origin pair's last redemption time + // to now. + // + // |issuer| and |top_level| must not be opaque. + virtual void RecordRedemption(const url::Origin& issuer, + const url::Origin& top_level); + + // Returns the time elapsed since the last redemption recorded by + // RecordRedemption for issuer |issuer| and top level |top_level|, + // or nullopt in the following two cases: + // 1. there was no prior redemption for the (issuer, + // top-level origin) pair. + // 2. the time since the last redepmption is negative (because + // of, for instance, corruption or clock skew). + // + // |issuer| and |top_level| must not be opaque. + WARN_UNUSED_RESULT virtual base::Optional<base::TimeDelta> + TimeSinceLastRedemption(const url::Origin& issuer, + const url::Origin& top_level); + + // Returns whether |issuer| is associated with |top_level|. + // + // |issuer| and |top_level| must not be opaque. + WARN_UNUSED_RESULT virtual bool IsAssociated(const url::Origin& issuer, + const url::Origin& top_level); + + // Associates |issuer| with |top_level|. (It's the caller's responsibility to + // enforce any cap on the number of top levels per issuer.) + // + // |issuer| and |top_level| must not be opaque. + virtual void SetAssociation(const url::Origin& issuer, + const url::Origin& top_level); + + //// Methods related to reading and writing issuer values configured via key + //// commitment queries, such as key commitments and batch sizes: + + // Returns all stored key commitments (including related metadata: + // see the definition of TrustTokenKeyCommitment) for the given issuer. + // + // |issuer| must not be opaque. + WARN_UNUSED_RESULT virtual std::vector<TrustTokenKeyCommitment> + KeyCommitments(const url::Origin& issuer); + + // Sets the key commitments for |issuer| to exactly the keys in |keys|. + // If there is a key in |keys| with the same key() as a key already stored: + // - maintains the "first seen at" time for the key + // - updates the expiry date to the new expiry date, even if it is sooner + // than the previous expiry date + // + // Also prunes all state corresponding to keys *not* in |keys|: + // - removes all stored signed tokens for |issuer| that were signed with + // keys not in |keys| + // - removes all key commitments for |issuer| with keys not in |keys| + // + // It is the client's responsibility to validate the + // reasonableness of the given keys' expiry times. (For instance, one might + // wish to avoid providing keys with expiry times in the past.) + // + // |issuer| must not be opaque, and the commitments in |keys| must have + // distinct keys. + virtual void SetKeyCommitmentsAndPruneStaleState( + const url::Origin& issuer, + base::span<const TrustTokenKeyCommitment> keys); + + // Returns the "batch size" (number of blinded tokens to provide per issuance + // request) for the given issuer, if present and greater than 0. Otherwise, + // returns nullopt. + // + // |issuer| must not be opaque. + WARN_UNUSED_RESULT virtual base::Optional<int> BatchSize( + const url::Origin& issuer); + + // Sets the given issuer's batch size (see above). + // + // |issuer| must not be opaque; |batch_size| must be at least 1. + virtual void SetBatchSize(const url::Origin& issuer, int batch_size); + + //// Methods related to reading and writing signed tokens: + + // Associates to the given issuer additional signed + // trust tokens with: + // - token bodies given by |token_bodies| + // - signing keys given by |issuing_key|. + // + // |issuer| must not be opaque and must have a stored + // key commitment corresponding to |issuing_key|. + virtual void AddTokens(const url::Origin& issuer, + base::span<const std::string> token_bodies, + base::StringPiece issuing_key); + + // Returns all signed tokens from |issuer| signed by keys matching + // the given predicate. + // + // |issuer| must not be opaque. + WARN_UNUSED_RESULT virtual std::vector<TrustToken> RetrieveMatchingTokens( + const url::Origin& issuer, + base::RepeatingCallback<bool(const std::string&)> key_matcher); + + // If |to_delete| is a token issued by |issuer|, deletes the token. + // + // |issuer| must not be opaque. + void DeleteToken(const url::Origin& issuer, const TrustToken& to_delete); + + //// Methods concerning Signed Redemption Records (SRRs) + + // Sets the cached SRR corresponding to the pair (issuer, top_level) + // to |record|. Overwrites any existing record. + // + // |issuer| and |top_level| must not be opaque. + virtual void SetRedemptionRecord( + const url::Origin& issuer, + const url::Origin& top_level, + const SignedTrustTokenRedemptionRecord& record); + + // Attempts to retrieve the stored SRR for the given pair of (issuer, + // top-level) origins. + // - If the pair has a current (i.e., non-expired) SRR, returns that SRR. + // - Otherwise, returns nullopt. + // + // |issuer| and |top_level| must not be opaque. + WARN_UNUSED_RESULT virtual base::Optional<SignedTrustTokenRedemptionRecord> + RetrieveNonstaleRedemptionRecord(const url::Origin& issuer, + const url::Origin& top_level); + + private: + std::unique_ptr<TrustTokenPersister> persister_; + std::unique_ptr<RecordExpiryDelegate> record_expiry_delegate_; +}; + +} // namespace net + +#endif // NET_TRUST_TOKENS_TRUST_TOKEN_STORE_H_
diff --git a/net/trust_tokens/trust_token_store_unittest.cc b/net/trust_tokens/trust_token_store_unittest.cc new file mode 100644 index 0000000..4f24782 --- /dev/null +++ b/net/trust_tokens/trust_token_store_unittest.cc
@@ -0,0 +1,540 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/trust_tokens/trust_token_store.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "net/trust_tokens/in_memory_trust_token_persister.h" +#include "net/trust_tokens/proto/public.pb.h" +#include "net/trust_tokens/proto/storage.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +using ::testing::ElementsAre; +using ::testing::Optional; + +namespace net { +namespace trust_tokens { + +namespace { +MATCHER_P(EqualsProto, + message, + "Match a proto Message equal to the matcher's argument.") { + std::string expected_serialized, actual_serialized; + message.SerializeToString(&expected_serialized); + arg.SerializeToString(&actual_serialized); + return expected_serialized == actual_serialized; +} +} // namespace + +TEST(TrustTokenStoreTest, RecordsIssuances) { + // A newly initialized store should not think it's + // recorded any issuances. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + EXPECT_EQ(my_store.TimeSinceLastIssuance(issuer), base::nullopt); + + // Recording an issuance should result in the time + // since last issuance being correctly returned. + + my_store.RecordIssuance(issuer); + auto delta = base::TimeDelta::FromSeconds(1); + env.AdvanceClock(delta); + + EXPECT_THAT(my_store.TimeSinceLastIssuance(issuer), Optional(delta)); +} + +TEST(TrustTokenStoreTest, DoesntReportMissingOrMalformedIssuanceTimestamps) { + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + + TrustTokenStore my_store(std::move(my_persister)); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + auto issuer_config_with_no_time = std::make_unique<TrustTokenIssuerConfig>(); + raw_persister->SetIssuerConfig(issuer, std::move(issuer_config_with_no_time)); + + EXPECT_EQ(my_store.TimeSinceLastIssuance(issuer), base::nullopt); + + auto issuer_config_with_malformed_time = + std::make_unique<TrustTokenIssuerConfig>(); + issuer_config_with_malformed_time->set_last_issuance( + "not a valid serialization of a base::Time"); + raw_persister->SetIssuerConfig(issuer, + std::move(issuer_config_with_malformed_time)); + + EXPECT_EQ(my_store.TimeSinceLastIssuance(issuer), base::nullopt); +} + +TEST(TrustTokenStoreTest, DoesntReportNegativeTimeSinceLastIssuance) { + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + TrustTokenStore my_store(std::move(my_persister)); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + base::Time later_than_now = + base::Time::Now() + base::TimeDelta::FromSeconds(1); + + auto issuer_config_with_future_time = + std::make_unique<TrustTokenIssuerConfig>(); + issuer_config_with_future_time->set_last_issuance( + internal::TimeToString(later_than_now)); + raw_persister->SetIssuerConfig(issuer, + std::move(issuer_config_with_future_time)); + + // TimeSinceLastIssuance shouldn't return negative values. + + EXPECT_EQ(my_store.TimeSinceLastIssuance(issuer), base::nullopt); +} + +TEST(TrustTokenStore, RecordsRedemptions) { + // A newly initialized store should not think it's + // recorded any redemptions. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + EXPECT_EQ(my_store.TimeSinceLastRedemption(issuer, toplevel), base::nullopt); + + // Recording a redemption should result in the time + // since last redemption being correctly returned. + + my_store.RecordRedemption(issuer, toplevel); + auto delta = base::TimeDelta::FromSeconds(1); + env.AdvanceClock(delta); + + EXPECT_THAT(my_store.TimeSinceLastRedemption(issuer, toplevel), + Optional(delta)); +} + +TEST(TrustTokenStoreTest, DoesntReportMissingOrMalformedRedemptionTimestamps) { + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + + TrustTokenStore my_store(std::move(my_persister)); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + + auto config_with_no_time = + std::make_unique<TrustTokenIssuerToplevelPairConfig>(); + raw_persister->SetIssuerToplevelPairConfig(issuer, toplevel, + std::move(config_with_no_time)); + + EXPECT_EQ(my_store.TimeSinceLastRedemption(issuer, toplevel), base::nullopt); + + auto config_with_malformed_time = + std::make_unique<TrustTokenIssuerToplevelPairConfig>(); + config_with_malformed_time->set_last_redemption( + "not a valid serialization of a base::Time"); + raw_persister->SetIssuerToplevelPairConfig( + issuer, toplevel, std::move(config_with_malformed_time)); + + EXPECT_EQ(my_store.TimeSinceLastRedemption(issuer, toplevel), base::nullopt); +} + +TEST(TrustTokenStoreTest, DoesntReportNegativeTimeSinceLastRedemption) { + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + TrustTokenStore my_store(std::move(my_persister)); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + + base::Time later_than_now = + base::Time::Now() + base::TimeDelta::FromSeconds(1); + + auto config_with_future_time = + std::make_unique<TrustTokenIssuerToplevelPairConfig>(); + config_with_future_time->set_last_redemption( + internal::TimeToString(later_than_now)); + + raw_persister->SetIssuerToplevelPairConfig( + issuer, toplevel, std::move(config_with_future_time)); + + // TimeSinceLastRedemption shouldn't return negative values. + + EXPECT_EQ(my_store.TimeSinceLastRedemption(issuer, toplevel), base::nullopt); +} + +TEST(TrustTokenStore, AssociatesToplevelsWithIssuers) { + // A newly initialized store should not think + // any toplevels are associated with any issuers. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + EXPECT_FALSE(my_store.IsAssociated(issuer, toplevel)); + + // After associating an issuer with a toplevel, + // the store should think that that issuer is associated + // with that toplevel. + + my_store.SetAssociation(issuer, toplevel); + EXPECT_TRUE(my_store.IsAssociated(issuer, toplevel)); +} + +TEST(TrustTokenStore, StoresKeyCommitments) { + // A newly initialized store should not think + // any issuers have committed keys. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + EXPECT_TRUE(my_store.KeyCommitments(issuer).empty()); + + // A stored committed key should be returned + // by a subsequent query. + + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key("quite a secure key, this"); + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{my_commitment}); + + EXPECT_THAT(my_store.KeyCommitments(issuer), + ElementsAre(EqualsProto(my_commitment))); +} + +TEST(TrustTokenStore, OverwritesExistingKeyCommitments) { + // Overwriting an existing committed key should lead + // to the key's metadata being fused: + // - the key should still be present + // - the "first seen at" should not change + // - the expiry date should be updated + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + const std::string kMyKey = "quite a secure key, this"; + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key(kMyKey); + + const std::string kMySerializedTime = "four o'clock"; + const std::string kReplacementSerializedTime = "five o'clock"; + my_commitment.set_expiry(kMySerializedTime); + my_commitment.set_first_seen_at(kMySerializedTime); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{my_commitment}); + + TrustTokenKeyCommitment replacement_commitment; + replacement_commitment.set_key(kMyKey); + replacement_commitment.set_expiry(kReplacementSerializedTime); + replacement_commitment.set_first_seen_at(kReplacementSerializedTime); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{replacement_commitment}); + + ASSERT_EQ(my_store.KeyCommitments(issuer).size(), 1u); + auto got = my_store.KeyCommitments(issuer).front(); + + EXPECT_TRUE(got.key() == kMyKey); + EXPECT_TRUE(got.first_seen_at() == kMySerializedTime); + EXPECT_TRUE(got.expiry() == kReplacementSerializedTime); +} + +TEST(TrustTokenStore, KeyUpdateRemovesNonupdatedKeys) { + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key("quite a secure key, this"); + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{my_commitment}); + + // When committed keys are changed, the store should + // remove all keys not present in the provided set. + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>()); + + EXPECT_TRUE(my_store.KeyCommitments(issuer).empty()); +} + +TEST(TrustTokenStore, PrunesDataAssociatedWithRemovedKeyCommitments) { + // Removing a committed key should result in trust tokens + // associated with the removed key being pruned from the store. + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key("quite a secure key, this"); + + TrustTokenKeyCommitment another_commitment; + another_commitment.set_key("distinct from the first key"); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, + std::vector<TrustTokenKeyCommitment>{my_commitment, another_commitment}); + + my_store.AddTokens(issuer, std::vector<std::string>{"some token body"}, + my_commitment.key()); + + my_store.AddTokens(issuer, std::vector<std::string>{"some other token body"}, + another_commitment.key()); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{another_commitment}); + + TrustToken expected_token; + expected_token.set_body("some other token body"); + expected_token.set_signing_key(another_commitment.key()); + + // Removing |my_commitment| should have + // - led to the removal of the token associated with the removed key and + // - *not* led to the removal of the token associated with the remaining key. + EXPECT_THAT(my_store.RetrieveMatchingTokens( + issuer, base::BindRepeating( + [](const std::string& t) { return true; })), + ElementsAre(EqualsProto(expected_token))); +} + +TEST(TrustTokenStore, SetsBatchSize) { + // A newly initialized store should not think + // any issuers have associated batch sizes. + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + TrustTokenStore my_store(std::move(my_persister)); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + EXPECT_EQ(my_store.BatchSize(issuer), base::nullopt); + + // Setting an issuer's batch size should mean that + // subsequent queries return that batch size. + + my_store.SetBatchSize(issuer, 1); + EXPECT_THAT(my_store.BatchSize(issuer), Optional(1)); + + // If the issuer config is storing a bad batch size for some reason, + // the store's client should see nullopt. + auto bad_config = std::make_unique<TrustTokenIssuerConfig>(); + bad_config->set_batch_size(-1); + raw_persister->SetIssuerConfig(issuer, std::move(bad_config)); + EXPECT_EQ(my_store.BatchSize(issuer), base::nullopt); +} + +TEST(TrustTokenStore, AddsTrustTokens) { + // A newly initialized store should not think + // any issuers have associated trust tokens. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + auto match_all_keys = + base::BindRepeating([](const std::string& t) { return true; }); + + EXPECT_TRUE(my_store.RetrieveMatchingTokens(issuer, match_all_keys).empty()); + + // Adding a token should result in that token being + // returned by subsequent queries with predicates accepting + // that token. + + const std::string kMyKey = "abcdef"; + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key(kMyKey); + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{my_commitment}); + + TrustToken expected_token; + expected_token.set_body("some token"); + expected_token.set_signing_key(kMyKey); + my_store.AddTokens(issuer, std::vector<std::string>{expected_token.body()}, + kMyKey); + + EXPECT_THAT(my_store.RetrieveMatchingTokens(issuer, match_all_keys), + ElementsAre(EqualsProto(expected_token))); +} + +TEST(TrustTokenStore, RetrievesTrustTokensRespectingNontrivialPredicate) { + // RetrieveMatchingTokens should not return tokens rejected by + // the provided predicate. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + const std::string kMatchingKey = "bbbbbb"; + const std::string kNonmatchingKey = "aaaaaa"; + TrustTokenKeyCommitment matching_commitment; + matching_commitment.set_key(kMatchingKey); + + TrustTokenKeyCommitment nonmatching_commitment; + nonmatching_commitment.set_key(kNonmatchingKey); + + TrustToken expected_token; + expected_token.set_body("this one should get returned"); + expected_token.set_signing_key(kMatchingKey); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{matching_commitment, + nonmatching_commitment}); + + my_store.AddTokens(issuer, std::vector<std::string>{expected_token.body()}, + kMatchingKey); + my_store.AddTokens( + issuer, + std::vector<std::string>{"this one should get rejected by the predicate"}, + kNonmatchingKey); + + EXPECT_THAT(my_store.RetrieveMatchingTokens( + issuer, base::BindRepeating( + [](const std::string& pattern, + const std::string& possible_match) { + return possible_match == pattern; + }, + kMatchingKey)), + ElementsAre(EqualsProto(expected_token))); +} + +TEST(TrustTokenStore, DeletesSingleToken) { + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + auto match_all_keys = + base::BindRepeating([](const std::string& t) { return true; }); + + // Deleting a single token should result in that token + // not being returned by subsequent RetrieveMatchingTokens calls. + // On the other hand, tokens *not* deleted should still be + // returned. + + TrustTokenKeyCommitment my_commitment; + my_commitment.set_key("key"); + + TrustToken first_token; + first_token.set_body("delete me!"); + first_token.set_signing_key(my_commitment.key()); + + TrustToken second_token; + second_token.set_body("don't delete me!"); + second_token.set_signing_key(my_commitment.key()); + + my_store.SetKeyCommitmentsAndPruneStaleState( + issuer, std::vector<TrustTokenKeyCommitment>{my_commitment}); + my_store.AddTokens( + issuer, std::vector<std::string>{first_token.body(), second_token.body()}, + my_commitment.key()); + + my_store.DeleteToken(issuer, first_token); + + EXPECT_THAT(my_store.RetrieveMatchingTokens(issuer, match_all_keys), + ElementsAre(EqualsProto(second_token))); +} + +TEST(TrustTokenStore, DeleteTokenForMissingIssuer) { + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + + // Deletes for issuers not present in the store should gracefully no-op. + + my_store.DeleteToken(issuer, TrustToken()); +} + +TEST(TrustTokenStore, SetsAndRetrievesRedemptionRecord) { + // A newly initialized store should not think + // it has any signed redemption records. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + EXPECT_EQ(my_store.RetrieveNonstaleRedemptionRecord(issuer, toplevel), + base::nullopt); + + // Providing a redemption record should mean that subsequent + // queries (modulo the record's staleness) should return that + // record. + + SignedTrustTokenRedemptionRecord my_record; + my_record.set_body("Look at me! I'm a signed redemption record!"); + my_store.SetRedemptionRecord(issuer, toplevel, my_record); + + EXPECT_THAT(my_store.RetrieveNonstaleRedemptionRecord(issuer, toplevel), + Optional(EqualsProto(my_record))); +} + +TEST(TrustTokenStore, RetrieveRedemptionRecordHandlesConfigWithNoRecord) { + // A RetrieveRedemptionRecord call for an (issuer, toplevel) pair with + // no redemption record stored should gracefully return the default value. + + auto my_persister = std::make_unique<InMemoryTrustTokenPersister>(); + auto* raw_persister = my_persister.get(); + TrustTokenStore my_store(std::move(my_persister)); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + + raw_persister->SetIssuerToplevelPairConfig( + issuer, toplevel, std::make_unique<TrustTokenIssuerToplevelPairConfig>()); + + EXPECT_EQ(my_store.RetrieveNonstaleRedemptionRecord(issuer, toplevel), + base::nullopt); +} + +TEST(TrustTokenStore, SetRedemptionRecordOverwritesExisting) { + // Subsequent redemption records should overwrite ones set earlier. + + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + base::test::TaskEnvironment env( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + SignedTrustTokenRedemptionRecord my_record; + my_record.set_body("Look at me! I'm a signed redemption record!"); + my_store.SetRedemptionRecord(issuer, toplevel, my_record); + + SignedTrustTokenRedemptionRecord another_record; + another_record.set_body( + "If all goes well, this one should overwrite |my_record|."); + my_store.SetRedemptionRecord(issuer, toplevel, another_record); + + EXPECT_THAT(my_store.RetrieveNonstaleRedemptionRecord(issuer, toplevel), + Optional(EqualsProto(another_record))); +} + +namespace { +// Characterizes an SRR as expired if its body begins with an "a". +class LetterAExpiringExpiryDelegate + : public TrustTokenStore::RecordExpiryDelegate { + public: + bool IsRecordExpired( + const SignedTrustTokenRedemptionRecord& record) override { + return record.body().size() > 1 && record.body().front() == 'a'; + } +}; +} // namespace + +TEST(TrustTokenStore, DoesNotReturnStaleRedemptionRecord) { + // Once a redemption record expires, it should no longer + // be returned by retrieval queries. + TrustTokenStore my_store(std::make_unique<InMemoryTrustTokenPersister>(), + std::make_unique<LetterAExpiringExpiryDelegate>()); + url::Origin issuer = url::Origin::Create(GURL("https://issuer.com")); + url::Origin toplevel = url::Origin::Create(GURL("https://toplevel.com")); + + SignedTrustTokenRedemptionRecord my_record; + my_record.set_body("aLook at me! I'm an expired signed redemption record!"); + my_store.SetRedemptionRecord(issuer, toplevel, my_record); + + EXPECT_EQ(my_store.RetrieveNonstaleRedemptionRecord(issuer, toplevel), + base::nullopt); +} + +} // namespace trust_tokens +} // namespace net
diff --git a/net/trust_tokens/types.cc b/net/trust_tokens/types.cc new file mode 100644 index 0000000..829d027c --- /dev/null +++ b/net/trust_tokens/types.cc
@@ -0,0 +1,26 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/trust_tokens/types.h" +#include "base/time/time.h" +#include "base/value_conversions.h" +#include "base/values.h" +#include "url/origin.h" + +namespace net { +namespace internal { + +base::Optional<base::Time> StringToTime(base::StringPiece my_string) { + base::Time ret; + if (!base::GetValueAsTime(base::Value(my_string), &ret)) + return base::nullopt; + return ret; +} + +std::string TimeToString(base::Time my_time) { + return base::CreateTimeValue(my_time).GetString(); +} + +} // namespace internal +} // namespace net
diff --git a/net/trust_tokens/types.h b/net/trust_tokens/types.h new file mode 100644 index 0000000..47338017 --- /dev/null +++ b/net/trust_tokens/types.h
@@ -0,0 +1,30 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TRUST_TOKENS_TYPES_H_ +#define NET_TRUST_TOKENS_TYPES_H_ + +#include <string> + +#include "base/strings/string_piece_forward.h" +#include "base/time/time.h" +#include "url/origin.h" + +namespace net { +namespace internal { + +// types.h provides utility functions for Trust TrustTokens type conversion. + +// Deserializes a base::Time. Returns nullopt on failure (for instance, +// deserialization can fail if |my_string| is malformed due to data +// corruption) and the deserialized Time on success. +base::Optional<base::Time> StringToTime(base::StringPiece my_string); + +// Serializes a base::Time. +std::string TimeToString(base::Time my_time); + +} // namespace internal +} // namespace net + +#endif // NET_TRUST_TOKENS_TYPES_H_
diff --git a/net/trust_tokens/types_unittest.cc b/net/trust_tokens/types_unittest.cc new file mode 100644 index 0000000..7830f87 --- /dev/null +++ b/net/trust_tokens/types_unittest.cc
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/trust_tokens/types.h" +#include "base/time/time.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::Optional; + +namespace net { +namespace internal { + +// trust_tokens/types.h's TimeToString/StringToTime implementations are +// thin wrappers around well-tested //base conversion methods, so these +// tests are just sanity checks to make sure that values are actually +// getting passed to the pertinent //base libraries. + +TEST(TrustTokenTypes, TimeToStringRoundtrip) { + auto my_time = base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds( + 373849174829374); // arbitrary + EXPECT_THAT(StringToTime(TimeToString(my_time)), Optional(my_time)); +} + +TEST(TrustTokenTypes, TimeFromBadStringFails) { + EXPECT_EQ(StringToTime("I bet this isn't a valid representation of a time."), + base::nullopt); +} + +} // namespace internal +} // namespace net
diff --git a/net/url_request/http_with_dns_over_https_unittest.cc b/net/url_request/http_with_dns_over_https_unittest.cc index 12fe95c0..d4f1d9e 100644 --- a/net/url_request/http_with_dns_over_https_unittest.cc +++ b/net/url_request/http_with_dns_over_https_unittest.cc
@@ -313,7 +313,7 @@ EXPECT_EQ(test_https_requests_served_, 0u); EXPECT_TRUE(d.response_completed()); - EXPECT_EQ(d.request_status(), net::ERR_DNS_MALFORMED_RESPONSE); + EXPECT_EQ(d.request_status(), net::ERR_NAME_NOT_RESOLVED); const auto& resolve_error_info = req->response_info().resolve_error_info; EXPECT_TRUE(resolve_error_info.is_secure_network_error);
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 8645851..8e91675 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -288,8 +288,10 @@ rtc_config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + webrtc::PeerConnectionDependencies dependencies(this); + dependencies.allocator = std::move(port_allocator); peer_connection_ = peer_connection_factory_->CreatePeerConnection( - rtc_config, std::move(port_allocator), nullptr, this); + rtc_config, std::move(dependencies)); } ~PeerConnectionWrapper() override {
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 3d8b23d8..a23f8eb 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -91,6 +91,7 @@ uint32_t options, DeleteCallback delete_callback, const ResourceRequest& resource_request, + bool ignore_isolated_world_origin, mojo::PendingRemote<mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojom::URLLoaderFactory* network_loader_factory, @@ -109,6 +110,9 @@ origin_access_list_(origin_access_list), factory_bound_origin_access_list_(factory_bound_origin_access_list), preflight_controller_(preflight_controller) { + if (ignore_isolated_world_origin) + request_.isolated_world_origin = base::nullopt; + receiver_.set_disconnect_handler( base::BindOnce(&CorsURLLoader::OnMojoDisconnect, base::Unretained(this))); DCHECK(network_loader_factory_);
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h index 159d304..a3e3b72 100644 --- a/services/network/cors/cors_url_loader.h +++ b/services/network/cors/cors_url_loader.h
@@ -44,6 +44,7 @@ uint32_t options, DeleteCallback delete_callback, const ResourceRequest& resource_request, + bool ignore_isolated_world_origin, mojo::PendingRemote<mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojom::URLLoaderFactory* network_loader_factory,
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index e91b2db..af1c74c 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -125,6 +125,7 @@ disable_web_security_(params->disable_web_security), process_id_(params->process_id), request_initiator_site_lock_(params->request_initiator_site_lock), + ignore_isolated_world_origin_(params->ignore_isolated_world_origin), origin_access_list_(origin_access_list) { DCHECK(context_); DCHECK(origin_access_list_); @@ -200,8 +201,8 @@ std::move(receiver), routing_id, request_id, options, base::BindOnce(&CorsURLLoaderFactory::DestroyURLLoader, base::Unretained(this)), - resource_request, std::move(client), traffic_annotation, - inner_url_loader_factory, origin_access_list_, + resource_request, ignore_isolated_world_origin_, std::move(client), + traffic_annotation, inner_url_loader_factory, origin_access_list_, factory_bound_origin_access_list_.get(), context_->cors_preflight_controller()); auto* raw_loader = loader.get();
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h index ebf9480..9c81a2c 100644 --- a/services/network/cors/cors_url_loader_factory.h +++ b/services/network/cors/cors_url_loader_factory.h
@@ -93,6 +93,7 @@ const bool disable_web_security_; const int32_t process_id_ = mojom::kInvalidProcessId; const base::Optional<url::Origin> request_initiator_site_lock_; + const bool ignore_isolated_world_origin_; // Relative order of |network_loader_factory_| and |loaders_| matters - // URLLoaderFactory needs to live longer than URLLoaders created using the
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index af70995f..1f05fd8d 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -327,7 +327,8 @@ void ResetFactory(base::Optional<url::Origin> initiator, uint32_t process_id, - bool is_trusted = false) { + bool is_trusted, + bool ignore_isolated_world_origin) { test_url_loader_factory_ = std::make_unique<TestURLLoaderFactory>(); test_url_loader_factory_receiver_ = std::make_unique<mojo::Receiver<mojom::URLLoaderFactory>>( @@ -347,6 +348,7 @@ factory_params->is_trusted = is_trusted; factory_params->process_id = process_id; factory_params->is_corb_enabled = (process_id != mojom::kBrowserProcessId); + factory_params->ignore_isolated_world_origin = ignore_isolated_world_origin; factory_params->factory_override = mojom::URLLoaderFactoryOverride::New(); factory_params->factory_override->overriding_factory = test_url_loader_factory_receiver_->BindNewPipeAndPassRemote(); @@ -362,6 +364,13 @@ &origin_access_list_); } + void ResetFactory(base::Optional<url::Origin> initiator, + uint32_t process_id) { + auto params = network::mojom::URLLoaderFactoryParams::New(); + ResetFactory(initiator, process_id, params->is_trusted, + params->ignore_isolated_world_origin); + } + NetworkContext* network_context() { return network_context_.get(); } private: @@ -1264,12 +1273,16 @@ // Tests if CorsURLLoader takes into account // ResourceRequest::isolated_world_origin when consulting OriginAccessList. TEST_F(CorsURLLoaderTest, OriginAccessList_IsolatedWorldOrigin) { - const GURL main_world_origin("http://main-world.com"); - const GURL isolated_world_origin("http://isolated-world.com"); + const url::Origin main_world_origin = + url::Origin::Create(GURL("http://main-world.com")); + const url::Origin isolated_world_origin = + url::Origin::Create(GURL("http://isolated-world.com")); const GURL url("http://other.com/foo.png"); - AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin), - url.scheme(), url.host(), + ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, + false /* ignore_isolated_world_origin */); + + AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); ResourceRequest request; @@ -1277,8 +1290,8 @@ request.credentials_mode = mojom::CredentialsMode::kOmit; request.method = net::HttpRequestHeaders::kGetMethod; request.url = url; - request.request_initiator = url::Origin::Create(main_world_origin); - request.isolated_world_origin = url::Origin::Create(isolated_world_origin); + request.request_initiator = main_world_origin; + request.isolated_world_origin = isolated_world_origin; CreateLoaderAndStart(request); RunUntilCreateLoaderAndStartCalled(); @@ -1289,7 +1302,7 @@ EXPECT_TRUE(IsNetworkLoaderStarted()); EXPECT_FALSE(client().has_received_redirect()); - EXPECT_TRUE(client().has_received_response()); + ASSERT_TRUE(client().has_received_response()); EXPECT_EQ(network::mojom::FetchResponseType::kBasic, client().response_head()->response_type); EXPECT_TRUE(client().has_received_completion()); @@ -1300,18 +1313,22 @@ // ResourceRequest::isolated_world_origin when consulting OriginAccessList // after redirects. TEST_F(CorsURLLoaderTest, OriginAccessList_IsolatedWorldOrigin_Redirect) { - const GURL main_world_origin("http://main-world.com"); - const GURL isolated_world_origin("http://isolated-world.com"); + const url::Origin main_world_origin = + url::Origin::Create(GURL("http://main-world.com")); + const url::Origin isolated_world_origin = + url::Origin::Create(GURL("http://isolated-world.com")); const GURL url("http://other.com/foo.png"); // |new_url| is same-origin as |url| to avoid tainting the response // in CorsURLLoader::OnReceiveRedirect. const GURL new_url("http://other.com/bar.png"); - AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin), - url.scheme(), url.host(), + ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, + false /* ignore_isolated_world_origin */); + + AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); - AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin), - new_url.scheme(), new_url.host(), + AddAllowListEntryForOrigin(isolated_world_origin, new_url.scheme(), + new_url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); ResourceRequest request; @@ -1321,8 +1338,8 @@ request.credentials_mode = mojom::CredentialsMode::kOmit; request.method = net::HttpRequestHeaders::kGetMethod; request.url = url; - request.request_initiator = url::Origin::Create(main_world_origin); - request.isolated_world_origin = url::Origin::Create(isolated_world_origin); + request.request_initiator = main_world_origin; + request.isolated_world_origin = isolated_world_origin; CreateLoaderAndStart(request); RunUntilCreateLoaderAndStartCalled(); @@ -1342,13 +1359,50 @@ EXPECT_TRUE(IsNetworkLoaderStarted()); EXPECT_TRUE(client().has_received_redirect()); - EXPECT_TRUE(client().has_received_response()); + ASSERT_TRUE(client().has_received_response()); EXPECT_EQ(network::mojom::FetchResponseType::kBasic, client().response_head()->response_type); EXPECT_TRUE(client().has_received_completion()); EXPECT_EQ(net::OK, client().completion_status().error_code); } +// Tests if CorsURLLoader takes ignores ResourceRequest::isolated_world_origin +// when URLLoaderFactoryParams::ignore_isolated_world_origin is set to true. +TEST_F(CorsURLLoaderTest, OriginAccessList_IsolatedWorldOriginIgnored) { + const url::Origin main_world_origin = + url::Origin::Create(GURL("http://main-world.com")); + const url::Origin isolated_world_origin = + url::Origin::Create(GURL("http://isolated-world.com")); + const GURL url("http://other.com/foo.png"); + + ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, + true /* ignore_isolated_world_origin */); + + AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), + mojom::CorsDomainMatchMode::kDisallowSubdomains); + + ResourceRequest request; + request.mode = mojom::RequestMode::kCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; + request.method = net::HttpRequestHeaders::kGetMethod; + request.url = url; + request.request_initiator = main_world_origin; + request.isolated_world_origin = isolated_world_origin; + CreateLoaderAndStart(request); + RunUntilCreateLoaderAndStartCalled(); + + NotifyLoaderClientOnReceiveResponse(); + NotifyLoaderClientOnComplete(net::OK); + + RunUntilComplete(); + + EXPECT_TRUE(IsNetworkLoaderStarted()); + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_FALSE(client().has_received_response()); + EXPECT_TRUE(client().has_received_completion()); + EXPECT_EQ(net::ERR_FAILED, client().completion_status().error_code); +} + // Check if higher-priority block list wins. TEST_F(CorsURLLoaderTest, OriginAccessList_Blocked) { const GURL origin("http://example.com"); @@ -1956,7 +2010,9 @@ // Run the test with a trusted URLLoaderFactory as well, to make sure a CORS // request is in fact made when using a trusted factory. for (bool is_trusted : {false, true}) { - ResetFactory(base::nullopt, kRendererProcessId, is_trusted); + bool ignore_isolated_world_origin = true; // This is the default. + ResetFactory(base::nullopt, kRendererProcessId, is_trusted, + ignore_isolated_world_origin); BadMessageTestHelper bad_message_helper; @@ -2002,7 +2058,8 @@ // Test that when a request has LOAD_RESTRICTED_PREFETCH and a // NetworkIsolationKey, CorsURLLoaderFactory does not reject the request. TEST_F(CorsURLLoaderTest, RestrictedPrefetchSucceedsWithNIK) { - ResetFactory(base::nullopt, kRendererProcessId, true); + ResetFactory(base::nullopt, kRendererProcessId, true /* is_trusted */, + true /* ignore_isolated_world_origin */); BadMessageTestHelper bad_message_helper; @@ -2041,7 +2098,8 @@ // because the LOAD_RESTRICTED_PREFETCH flag must only appear on requests that // make use of their TrustedParams' |network_isolation_key|. TEST_F(CorsURLLoaderTest, RestrictedPrefetchFailsWithoutNIK) { - ResetFactory(base::nullopt, kRendererProcessId, true); + ResetFactory(base::nullopt, kRendererProcessId, true /* is_trusted */, + true /* ignore_isolated_world_origin */); BadMessageTestHelper bad_message_helper;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 32a60d94..c37e71fb 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -565,6 +565,11 @@ // Cross-origin read blocking (CORB) configuration. bool is_corb_enabled = true; + // Whether |isolated_world_origin| from network::ResourceRequest should be + // ignored. Set |ignore_isolated_world_origin| to |false| to allow isolated + // worlds to bypass CORS security checks via OriginAccessList. + bool ignore_isolated_world_origin = true; + // Indicate whether a request is not from web page ( probably from chrome // extension background page ). bool unsafe_non_webby_initiator = false;
diff --git a/third_party/android_build_tools/aapt2/README.chromium b/third_party/android_build_tools/aapt2/README.chromium index 9dd0caad..98cbf2a 100644 --- a/third_party/android_build_tools/aapt2/README.chromium +++ b/third_party/android_build_tools/aapt2/README.chromium
@@ -12,4 +12,4 @@ distributed here as a CIPD package instead. See cipd.yaml for details. Local Modifications: -Fetched prebuilt from go/aapt2-6089589 (version not yet published to maven). +Fetched prebuilt from go/aapt2-6143298 (version not yet published to maven).
diff --git a/third_party/blink/public/OWNERS b/third_party/blink/public/OWNERS index f87e5af..c488ebc 100644 --- a/third_party/blink/public/OWNERS +++ b/third_party/blink/public/OWNERS
@@ -1,6 +1,7 @@ chrishtr@chromium.org dcheng@chromium.org dgozman@chromium.org +dtapuska@chromium.org falken@chromium.org foolip@chromium.org haraken@chromium.org
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 8655fb8..45c10d4 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -174,6 +174,10 @@ // Provides accessibility information about the termination of a find // in page operation. HandleAccessibilityFindInPageTermination(); + + // Sent after the onload handler has been invoked for the document + // in this frame. Sent for top-level frames. + DocumentOnLoadCompleted(); }; // Implemented in Blink, this interface defines frame-specific methods that will
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 200dee4..b123ff61 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2501,6 +2501,7 @@ kCSPROWithReasonableRestrictions = 3136, kCSPWithBetterThanReasonableRestrictions = 3137, kCSPROWithBetterThanReasonableRestrictions = 3138, + kMeasureMemory = 3139, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc index ca2eca9..8c8cd1e 100644 --- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc +++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -239,9 +239,16 @@ if (HTMLImageElement* image_element = ImageElementFromImageDocument(document)) { - WriteImageNodeToClipboard(*frame.GetSystemClipboard(), *image_element, - document->title()); - return true; + // In an image document, normally there isn't anything to select, and we + // only want to copy the image itself. + if (frame.Selection().ComputeVisibleSelectionInDOMTree().IsNone()) { + WriteImageNodeToClipboard(*frame.GetSystemClipboard(), *image_element, + document->title()); + return true; + } + + // Scripts may insert other contents into an image document. Falls through + // when they are selected. } // Since copy is a read-only operation it succeeds anytime a selection
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 1139a78..012abf06 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -387,6 +387,8 @@ } void LocalFrameClientImpl::DispatchDidHandleOnloadEvents() { + if (!web_frame_->Parent()) + web_frame_->GetFrame()->GetLocalFrameHostRemote().DocumentOnLoadCompleted(); if (web_frame_->Client()) web_frame_->Client()->DidHandleOnloadEvents(); }
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer.cc b/third_party/blink/renderer/core/exported/web_frame_serializer.cc index c5f5b6aa..fa35bdf 100644 --- a/third_party/blink/renderer/core/exported/web_frame_serializer.cc +++ b/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -40,356 +40,23 @@ #include "third_party/blink/public/web/web_frame_serializer_client.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h" -#include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/core/frame/frame_serializer.h" -#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/core/frame/web_frame_serializer_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" -#include "third_party/blink/renderer/core/html/forms/html_input_element.h" -#include "third_party/blink/renderer/core/html/html_all_collection.h" -#include "third_party/blink/renderer/core/html/html_frame_element_base.h" -#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" -#include "third_party/blink/renderer/core/html/html_head_element.h" -#include "third_party/blink/renderer/core/html/html_image_element.h" -#include "third_party/blink/renderer/core/html/html_link_element.h" -#include "third_party/blink/renderer/core/html/html_table_element.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/input_type_names.h" -#include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/loader/frame_loader.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" -#include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h" #include "third_party/blink/renderer/platform/mhtml/serialized_resource.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/deque.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/string_concatenate.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { -namespace { - -const int kPopupOverlayZIndexThreshold = 50; -const char kShadowModeAttributeName[] = "shadowmode"; -const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus"; - -// Returns a Content-ID to be used for the given frame. -// See rfc2557 - section 8.3 - "Use of the Content-ID header and CID URLs". -// Format note - the returned string should be of the form "<foo@bar.com>" -// (i.e. the strings should include the angle brackets). -String GetContentID(Frame* frame) { - String frame_id = String(ToTraceValue(frame).data()); - return "<frame-" + frame_id + "@mhtml.blink>"; -} - -class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate { - STACK_ALLOCATED(); - - public: - MHTMLFrameSerializerDelegate( - WebFrameSerializer::MHTMLPartsGenerationDelegate&, - HeapHashSet<WeakMember<const Element>>&); - ~MHTMLFrameSerializerDelegate() override = default; - bool ShouldIgnoreElement(const Element&) override; - bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; - bool RewriteLink(const Element&, String& rewritten_link) override; - bool ShouldSkipResourceWithURL(const KURL&) override; - Vector<Attribute> GetCustomAttributes(const Element&) override; - std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override; - bool ShouldCollectProblemMetric() override; - - private: - bool ShouldIgnoreHiddenElement(const Element&); - bool ShouldIgnoreMetaElement(const Element&); - bool ShouldIgnorePopupOverlayElement(const Element&); - void GetCustomAttributesForImageElement(const HTMLImageElement&, - Vector<Attribute>*); - - WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_; - HeapHashSet<WeakMember<const Element>>& shadow_template_elements_; - bool popup_overlays_skipped_; - - DISALLOW_COPY_AND_ASSIGN(MHTMLFrameSerializerDelegate); -}; - -MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate( - WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate, - HeapHashSet<WeakMember<const Element>>& shadow_template_elements) - : web_delegate_(web_delegate), - shadow_template_elements_(shadow_template_elements), - popup_overlays_skipped_(false) {} - -bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) { - if (ShouldIgnoreHiddenElement(element)) - return true; - if (ShouldIgnoreMetaElement(element)) - return true; - if (web_delegate_.RemovePopupOverlay() && - ShouldIgnorePopupOverlayElement(element)) { - return true; - } - // Remove <link> for stylesheets that do not load. - auto* html_link_element = DynamicTo<HTMLLinkElement>(element); - if (html_link_element && html_link_element->RelAttribute().IsStyleSheet() && - !html_link_element->sheet()) { - return true; - } - return false; -} - -bool MHTMLFrameSerializerDelegate::ShouldIgnoreHiddenElement( - const Element& element) { - // If an iframe is in the head, it will be moved to the body when the page is - // being loaded. But if an iframe is injected into the head later, it will - // stay there and not been displayed. To prevent it from being brought to the - // saved page and cause it being displayed, we should not include it. - if (IsA<HTMLIFrameElement>(element) && - Traversal<HTMLHeadElement>::FirstAncestor(element)) { - return true; - } - - // Do not include the element that is marked with hidden attribute. - if (element.FastHasAttribute(html_names::kHiddenAttr)) - return true; - - // Do not include the hidden form element. - auto* html_element_element = DynamicTo<HTMLInputElement>(&element); - return html_element_element && - html_element_element->type() == input_type_names::kHidden; -} - -bool MHTMLFrameSerializerDelegate::ShouldIgnoreMetaElement( - const Element& element) { - // Do not include meta elements that declare Content-Security-Policy - // directives. They should have already been enforced when the original - // document is loaded. Since only the rendered resources are encapsulated in - // the saved MHTML page, there is no need to carry the directives. If they - // are still kept in the MHTML, child frames that are referred to using cid: - // scheme could be prevented from loading. - if (!IsA<HTMLMetaElement>(element)) - return false; - if (!element.FastHasAttribute(html_names::kContentAttr)) - return false; - const AtomicString& http_equiv = - element.FastGetAttribute(html_names::kHttpEquivAttr); - return http_equiv == "Content-Security-Policy"; -} - -bool MHTMLFrameSerializerDelegate::ShouldIgnorePopupOverlayElement( - const Element& element) { - // The element should be visible. - LayoutBox* box = element.GetLayoutBox(); - if (!box) - return false; - - // The bounding box of the element should contain center point of the - // viewport. - LocalDOMWindow* window = element.GetDocument().domWindow(); - DCHECK(window); - int center_x = window->innerWidth() / 2; - int center_y = window->innerHeight() / 2; - if (Page* page = element.GetDocument().GetPage()) { - center_x = page->GetChromeClient().WindowToViewportScalar( - window->GetFrame(), center_x); - center_y = page->GetChromeClient().WindowToViewportScalar( - window->GetFrame(), center_y); - } - LayoutPoint center_point(center_x, center_y); - if (!box->FrameRect().Contains(center_point)) - return false; - - // The z-index should be greater than the threshold. - if (box->Style()->ZIndex() < kPopupOverlayZIndexThreshold) - return false; - - popup_overlays_skipped_ = true; - - return true; -} - -bool MHTMLFrameSerializerDelegate::ShouldIgnoreAttribute( - const Element& element, - const Attribute& attribute) { - // TODO(fgorski): Presence of srcset attribute causes MHTML to not display - // images, as only the value of src is pulled into the archive. Discarding - // srcset prevents the problem. Long term we should make sure to MHTML plays - // nicely with srcset. - if (IsA<HTMLImageElement>(element) && - (attribute.LocalName() == html_names::kSrcsetAttr || - attribute.LocalName() == html_names::kSizesAttr)) { - return true; - } - - // Do not save ping attribute since anyway the ping will be blocked from - // MHTML. - if (IsA<HTMLAnchorElement>(element) && - attribute.LocalName() == html_names::kPingAttr) { - return true; - } - - // The special attribute in a template element to denote the shadow DOM - // should only be generated from MHTML serialization. If it is found in the - // original page, it should be ignored. - if (IsA<HTMLTemplateElement>(element) && - (attribute.LocalName() == kShadowModeAttributeName || - attribute.LocalName() == kShadowDelegatesFocusAttributeName) && - !shadow_template_elements_.Contains(&element)) { - return true; - } - - // If srcdoc attribute for frame elements will be rewritten as src attribute - // containing link instead of html contents, don't ignore the attribute. - // Bail out now to avoid the check in Element::isScriptingAttribute. - bool is_src_doc_attribute = IsA<HTMLFrameElementBase>(element) && - attribute.GetName() == html_names::kSrcdocAttr; - String new_link_for_the_element; - if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element)) - return false; - - // Drop integrity attribute for those links with subresource loaded. - auto* html_link_element = DynamicTo<HTMLLinkElement>(element); - if (attribute.LocalName() == html_names::kIntegrityAttr && - html_link_element && html_link_element->sheet()) { - return true; - } - - // Do not include attributes that contain javascript. This is because the - // script will not be executed when a MHTML page is being loaded. - return element.IsScriptingAttribute(attribute); -} - -bool MHTMLFrameSerializerDelegate::RewriteLink(const Element& element, - String& rewritten_link) { - auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(element); - if (!frame_owner) - return false; - - Frame* frame = frame_owner->ContentFrame(); - if (!frame) - return false; - - WebString content_id = GetContentID(frame); - KURL cid_uri = MHTMLParser::ConvertContentIDToURI(content_id); - DCHECK(cid_uri.IsValid()); - rewritten_link = cid_uri.GetString(); - return true; -} - -bool MHTMLFrameSerializerDelegate::ShouldSkipResourceWithURL(const KURL& url) { - return web_delegate_.ShouldSkipResource(url); -} - -Vector<Attribute> MHTMLFrameSerializerDelegate::GetCustomAttributes( - const Element& element) { - Vector<Attribute> attributes; - - if (auto* image = DynamicTo<HTMLImageElement>(element)) { - GetCustomAttributesForImageElement(*image, &attributes); - } - - return attributes; -} - -bool MHTMLFrameSerializerDelegate::ShouldCollectProblemMetric() { - return web_delegate_.UsePageProblemDetectors(); -} - -void MHTMLFrameSerializerDelegate::GetCustomAttributesForImageElement( - const HTMLImageElement& element, - Vector<Attribute>* attributes) { - // Currently only the value of src is pulled into the archive and the srcset - // attribute is ignored (see shouldIgnoreAttribute() above). If the device - // has a higher DPR, a different image from srcset could be loaded instead. - // When this occurs, we should provide the rendering width and height for - // <img> element if not set. - - // The image should be loaded and participate the layout. - ImageResourceContent* image = element.CachedImage(); - if (!image || !image->HasImage() || image->ErrorOccurred() || - !element.GetLayoutObject()) { - return; - } - - // The width and height attributes should not be set. - if (element.FastHasAttribute(html_names::kWidthAttr) || - element.FastHasAttribute(html_names::kHeightAttr)) { - return; - } - - // Check if different image is loaded. naturalWidth/naturalHeight will return - // the image size adjusted with current DPR. - if (((int)element.naturalWidth()) == image->GetImage()->width() && - ((int)element.naturalHeight()) == image->GetImage()->height()) { - return; - } - - Attribute width_attribute(html_names::kWidthAttr, - AtomicString::Number(element.LayoutBoxWidth())); - attributes->push_back(width_attribute); - Attribute height_attribute(html_names::kHeightAttr, - AtomicString::Number(element.LayoutBoxHeight())); - attributes->push_back(height_attribute); -} - -std::pair<Node*, Element*> MHTMLFrameSerializerDelegate::GetAuxiliaryDOMTree( - const Element& element) const { - ShadowRoot* shadow_root = element.GetShadowRoot(); - if (!shadow_root) - return std::pair<Node*, Element*>(); - - String shadow_mode; - switch (shadow_root->GetType()) { - case ShadowRootType::kUserAgent: - // No need to serialize. - return std::pair<Node*, Element*>(); - case ShadowRootType::V0: - shadow_mode = "v0"; - break; - case ShadowRootType::kOpen: - shadow_mode = "open"; - break; - case ShadowRootType::kClosed: - shadow_mode = "closed"; - break; - } - - // Put the shadow DOM content inside a template element. A special attribute - // is set to tell the mode of the shadow DOM. - auto* template_element = MakeGarbageCollected<Element>( - html_names::kTemplateTag, &(element.GetDocument())); - template_element->setAttribute( - QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom), - AtomicString(shadow_mode)); - if (shadow_root->GetType() != ShadowRootType::V0 && - shadow_root->delegatesFocus()) { - template_element->setAttribute( - QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName, - g_null_atom), - g_empty_atom); - } - shadow_template_elements_.insert(template_element); - - return std::pair<Node*, Element*>(shadow_root, template_element); -} - -} // namespace - WebThreadSafeData WebFrameSerializer::GenerateMHTMLHeader( const WebString& boundary, WebLocalFrame* frame, @@ -432,8 +99,8 @@ SCOPED_BLINK_UMA_HISTOGRAM_TIMER( "PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame"); HeapHashSet<WeakMember<const Element>> shadow_template_elements; - MHTMLFrameSerializerDelegate core_delegate(*web_delegate, - shadow_template_elements); + FrameSerializerDelegateImpl core_delegate(*web_delegate, + shadow_template_elements); FrameSerializer serializer(resources, core_delegate); serializer.SerializeFrame(*frame); } @@ -453,9 +120,9 @@ "PageSerialization.MhtmlGeneration.EncodingTime.SingleFrame"); // Frame is the 1st resource (see FrameSerializer::serializeFrame doc // comment). Frames get a Content-ID header. - MHTMLArchive::GenerateMHTMLPart(boundary, GetContentID(frame), - encoding_policy, resources.TakeFirst(), - *output->MutableData()); + MHTMLArchive::GenerateMHTMLPart( + boundary, FrameSerializerDelegateImpl::GetContentID(frame), + encoding_policy, resources.TakeFirst(), *output->MutableData()); while (!resources.IsEmpty()) { TRACE_EVENT0("page-serialization", "WebFrameSerializer::generateMHTMLParts encoding");
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index cbeb817..bb2c86c 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -103,6 +103,7 @@ #include "third_party/blink/renderer/core/editing/finder/text_finder.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h" +#include "third_party/blink/renderer/core/editing/selection_template.h" #include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h" #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/events/mouse_event.h" @@ -10566,6 +10567,51 @@ system_clipboard->CommitWrite(); } +TEST_F(WebFrameTest, CopyTextInImageDocument) { + // If Javascript inserts other contents into an image document, we should be + // able to copy those contents, not just the image itself. + + RegisterMockedHttpURLLoadWithMimeType("white-1x1.png", "image/png"); + frame_test_helpers::WebViewHelper web_view_helper; + web_view_helper.InitializeAndLoad(base_url_ + "white-1x1.png"); + WebViewImpl* web_view = web_view_helper.GetWebView(); + WebLocalFrameImpl* web_frame = web_view->MainFrameImpl(); + Document* document = web_frame->GetFrame()->GetDocument(); + + ASSERT_TRUE(document); + EXPECT_TRUE(IsA<ImageDocument>(document)); + + Node* text = document->createTextNode("copy me"); + document->body()->appendChild(text); + document->GetFrame()->Selection().SetSelection( + SelectionInDOMTree::Builder().SelectAllChildren(*text).Build(), + SetSelectionOptions()); + + // Setup a mock clipboard host. + PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider( + web_frame->GetFrame()->GetBrowserInterfaceBroker()); + + SystemClipboard* system_clipboard = + document->GetFrame()->GetSystemClipboard(); + ASSERT_TRUE(system_clipboard); + + EXPECT_TRUE(system_clipboard->ReadAvailableTypes().IsEmpty()); + + bool result = web_frame->ExecuteCommand("Copy"); + test::RunPendingTasks(); + + EXPECT_TRUE(result); + + Vector<String> types = system_clipboard->ReadAvailableTypes(); + EXPECT_EQ(2u, types.size()); + EXPECT_EQ("text/plain", types[0]); + EXPECT_EQ("text/html", types[1]); + + // Clear clipboard data + system_clipboard->WritePlainText(""); + system_clipboard->CommitWrite(); +} + class CallbackOrderingWebFrameClient : public frame_test_helpers::TestWebFrameClient { public:
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 3729bf3b..eed9d1d 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -4387,7 +4387,6 @@ WebViewImpl* web_view_; frame_test_helpers::WebViewHelper& web_view_helper_; frame_test_helpers::TestWebFrameClient web_frame_client_; - std::unique_ptr<service_manager::InterfaceProvider::TestApi> test_api_; }; // Mock implementation of the UnhandledTapNotifier Mojo receiver, for testing
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn index 6ec08d1..cbbfa3c 100644 --- a/third_party/blink/renderer/core/frame/BUILD.gn +++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -75,6 +75,8 @@ "frame_owner.h", "frame_serializer.cc", "frame_serializer.h", + "frame_serializer_delegate_impl.cc", + "frame_serializer_delegate_impl.h", "frame_types.h", "frame_view.cc", "frame_view.h",
diff --git a/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc new file mode 100644 index 0000000..ac111ef --- /dev/null +++ b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
@@ -0,0 +1,320 @@ +// Copyright 2020 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 "third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h" + +#include "third_party/blink/public/web/web_frame_serializer.h" +#include "third_party/blink/renderer/core/dom/attribute.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/element_traversal.h" +#include "third_party/blink/renderer/core/dom/shadow_root.h" +#include "third_party/blink/renderer/core/frame/frame.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" +#include "third_party/blink/renderer/core/html/html_anchor_element.h" +#include "third_party/blink/renderer/core/html/html_frame_element_base.h" +#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/html/html_head_element.h" +#include "third_party/blink/renderer/core/html/html_iframe_element.h" +#include "third_party/blink/renderer/core/html/html_image_element.h" +#include "third_party/blink/renderer/core/html/html_link_element.h" +#include "third_party/blink/renderer/core/html/html_meta_element.h" +#include "third_party/blink/renderer/core/html/html_template_element.h" +#include "third_party/blink/renderer/core/html/link_rel_attribute.h" +#include "third_party/blink/renderer/core/html_names.h" +#include "third_party/blink/renderer/core/input_type_names.h" +#include "third_party/blink/renderer/core/layout/layout_box.h" +#include "third_party/blink/renderer/core/layout/layout_object.h" +#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/platform/geometry/layout_point.h" +#include "third_party/blink/renderer/platform/geometry/layout_rect.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/assertions.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +namespace { + +const int kPopupOverlayZIndexThreshold = 50; +const char kShadowModeAttributeName[] = "shadowmode"; +const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus"; + +} // namespace + +// static +String FrameSerializerDelegateImpl::GetContentID(Frame* frame) { + DCHECK(frame); + String frame_id = String(frame->ToTraceValue().data()); + return "<frame-" + frame_id + "@mhtml.blink>"; +} + +FrameSerializerDelegateImpl::FrameSerializerDelegateImpl( + WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate, + HeapHashSet<WeakMember<const Element>>& shadow_template_elements) + : web_delegate_(web_delegate), + shadow_template_elements_(shadow_template_elements), + popup_overlays_skipped_(false) {} + +bool FrameSerializerDelegateImpl::ShouldIgnoreElement(const Element& element) { + if (ShouldIgnoreHiddenElement(element)) + return true; + if (ShouldIgnoreMetaElement(element)) + return true; + if (web_delegate_.RemovePopupOverlay() && + ShouldIgnorePopupOverlayElement(element)) { + return true; + } + // Remove <link> for stylesheets that do not load. + auto* html_link_element = DynamicTo<HTMLLinkElement>(element); + if (html_link_element && html_link_element->RelAttribute().IsStyleSheet() && + !html_link_element->sheet()) { + return true; + } + return false; +} + +bool FrameSerializerDelegateImpl::ShouldIgnoreHiddenElement( + const Element& element) { + // If an iframe is in the head, it will be moved to the body when the page is + // being loaded. But if an iframe is injected into the head later, it will + // stay there and not been displayed. To prevent it from being brought to the + // saved page and cause it being displayed, we should not include it. + if (IsA<HTMLIFrameElement>(element) && + Traversal<HTMLHeadElement>::FirstAncestor(element)) { + return true; + } + + // Do not include the element that is marked with hidden attribute. + if (element.FastHasAttribute(html_names::kHiddenAttr)) + return true; + + // Do not include the hidden form element. + auto* html_element_element = DynamicTo<HTMLInputElement>(&element); + return html_element_element && + html_element_element->type() == input_type_names::kHidden; +} + +bool FrameSerializerDelegateImpl::ShouldIgnoreMetaElement( + const Element& element) { + // Do not include meta elements that declare Content-Security-Policy + // directives. They should have already been enforced when the original + // document is loaded. Since only the rendered resources are encapsulated in + // the saved MHTML page, there is no need to carry the directives. If they + // are still kept in the MHTML, child frames that are referred to using cid: + // scheme could be prevented from loading. + if (!IsA<HTMLMetaElement>(element)) + return false; + if (!element.FastHasAttribute(html_names::kContentAttr)) + return false; + const AtomicString& http_equiv = + element.FastGetAttribute(html_names::kHttpEquivAttr); + return http_equiv == "Content-Security-Policy"; +} + +bool FrameSerializerDelegateImpl::ShouldIgnorePopupOverlayElement( + const Element& element) { + // The element should be visible. + LayoutBox* box = element.GetLayoutBox(); + if (!box) + return false; + + // The bounding box of the element should contain center point of the + // viewport. + LocalDOMWindow* window = element.GetDocument().domWindow(); + DCHECK(window); + int center_x = window->innerWidth() / 2; + int center_y = window->innerHeight() / 2; + if (Page* page = element.GetDocument().GetPage()) { + center_x = page->GetChromeClient().WindowToViewportScalar( + window->GetFrame(), center_x); + center_y = page->GetChromeClient().WindowToViewportScalar( + window->GetFrame(), center_y); + } + LayoutPoint center_point(center_x, center_y); + if (!box->FrameRect().Contains(center_point)) + return false; + + // The z-index should be greater than the threshold. + if (box->Style()->ZIndex() < kPopupOverlayZIndexThreshold) + return false; + + popup_overlays_skipped_ = true; + + return true; +} + +bool FrameSerializerDelegateImpl::ShouldIgnoreAttribute( + const Element& element, + const Attribute& attribute) { + // TODO(fgorski): Presence of srcset attribute causes MHTML to not display + // images, as only the value of src is pulled into the archive. Discarding + // srcset prevents the problem. Long term we should make sure to MHTML plays + // nicely with srcset. + if (IsA<HTMLImageElement>(element) && + (attribute.LocalName() == html_names::kSrcsetAttr || + attribute.LocalName() == html_names::kSizesAttr)) { + return true; + } + + // Do not save ping attribute since anyway the ping will be blocked from + // MHTML. + if (IsA<HTMLAnchorElement>(element) && + attribute.LocalName() == html_names::kPingAttr) { + return true; + } + + // The special attribute in a template element to denote the shadow DOM + // should only be generated from MHTML serialization. If it is found in the + // original page, it should be ignored. + if (IsA<HTMLTemplateElement>(element) && + (attribute.LocalName() == kShadowModeAttributeName || + attribute.LocalName() == kShadowDelegatesFocusAttributeName) && + !shadow_template_elements_.Contains(&element)) { + return true; + } + + // If srcdoc attribute for frame elements will be rewritten as src attribute + // containing link instead of html contents, don't ignore the attribute. + // Bail out now to avoid the check in Element::isScriptingAttribute. + bool is_src_doc_attribute = IsA<HTMLFrameElementBase>(element) && + attribute.GetName() == html_names::kSrcdocAttr; + String new_link_for_the_element; + if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element)) + return false; + + // Drop integrity attribute for those links with subresource loaded. + auto* html_link_element = DynamicTo<HTMLLinkElement>(element); + if (attribute.LocalName() == html_names::kIntegrityAttr && + html_link_element && html_link_element->sheet()) { + return true; + } + + // Do not include attributes that contain javascript. This is because the + // script will not be executed when a MHTML page is being loaded. + return element.IsScriptingAttribute(attribute); +} + +bool FrameSerializerDelegateImpl::RewriteLink(const Element& element, + String& rewritten_link) { + auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(element); + if (!frame_owner) + return false; + + Frame* frame = frame_owner->ContentFrame(); + if (!frame) + return false; + + WebString content_id = GetContentID(frame); + KURL cid_uri = MHTMLParser::ConvertContentIDToURI(content_id); + DCHECK(cid_uri.IsValid()); + rewritten_link = cid_uri.GetString(); + return true; +} + +bool FrameSerializerDelegateImpl::ShouldSkipResourceWithURL(const KURL& url) { + return web_delegate_.ShouldSkipResource(url); +} + +Vector<Attribute> FrameSerializerDelegateImpl::GetCustomAttributes( + const Element& element) { + Vector<Attribute> attributes; + + if (auto* image = DynamicTo<HTMLImageElement>(element)) { + GetCustomAttributesForImageElement(*image, &attributes); + } + + return attributes; +} + +bool FrameSerializerDelegateImpl::ShouldCollectProblemMetric() { + return web_delegate_.UsePageProblemDetectors(); +} + +void FrameSerializerDelegateImpl::GetCustomAttributesForImageElement( + const HTMLImageElement& element, + Vector<Attribute>* attributes) { + // Currently only the value of src is pulled into the archive and the srcset + // attribute is ignored (see shouldIgnoreAttribute() above). If the device + // has a higher DPR, a different image from srcset could be loaded instead. + // When this occurs, we should provide the rendering width and height for + // <img> element if not set. + + // The image should be loaded and participate the layout. + ImageResourceContent* image = element.CachedImage(); + if (!image || !image->HasImage() || image->ErrorOccurred() || + !element.GetLayoutObject()) { + return; + } + + // The width and height attributes should not be set. + if (element.FastHasAttribute(html_names::kWidthAttr) || + element.FastHasAttribute(html_names::kHeightAttr)) { + return; + } + + // Check if different image is loaded. naturalWidth/naturalHeight will return + // the image size adjusted with current DPR. + if ((static_cast<int>(element.naturalWidth())) == + image->GetImage()->width() && + (static_cast<int>(element.naturalHeight())) == + image->GetImage()->height()) { + return; + } + + Attribute width_attribute(html_names::kWidthAttr, + AtomicString::Number(element.LayoutBoxWidth())); + attributes->push_back(width_attribute); + Attribute height_attribute(html_names::kHeightAttr, + AtomicString::Number(element.LayoutBoxHeight())); + attributes->push_back(height_attribute); +} + +std::pair<Node*, Element*> FrameSerializerDelegateImpl::GetAuxiliaryDOMTree( + const Element& element) const { + ShadowRoot* shadow_root = element.GetShadowRoot(); + if (!shadow_root) + return std::pair<Node*, Element*>(); + + String shadow_mode; + switch (shadow_root->GetType()) { + case ShadowRootType::kUserAgent: + // No need to serialize. + return std::pair<Node*, Element*>(); + case ShadowRootType::V0: + shadow_mode = "v0"; + break; + case ShadowRootType::kOpen: + shadow_mode = "open"; + break; + case ShadowRootType::kClosed: + shadow_mode = "closed"; + break; + } + + // Put the shadow DOM content inside a template element. A special attribute + // is set to tell the mode of the shadow DOM. + auto* template_element = MakeGarbageCollected<Element>( + html_names::kTemplateTag, &(element.GetDocument())); + template_element->setAttribute( + QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom), + AtomicString(shadow_mode)); + if (shadow_root->GetType() != ShadowRootType::V0 && + shadow_root->delegatesFocus()) { + template_element->setAttribute( + QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName, + g_null_atom), + g_empty_atom); + } + shadow_template_elements_.insert(template_element); + + return std::pair<Node*, Element*>(shadow_root, template_element); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h new file mode 100644 index 0000000..d9c82cf --- /dev/null +++ b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h
@@ -0,0 +1,62 @@ +// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_SERIALIZER_DELEGATE_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_SERIALIZER_DELEGATE_IMPL_H_ + +#include "third_party/blink/renderer/core/frame/frame_serializer.h" + +#include "third_party/blink/public/web/web_frame_serializer.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/heap/member.h" + +namespace blink { + +class Frame; +class KURL; +class HTMLImageElement; + +// An implementation of FrameSerializer's delegate which is used to serialize a +// frame to a MHTML file. +class FrameSerializerDelegateImpl final : public FrameSerializer::Delegate { + STACK_ALLOCATED(); + + public: + // Returns a Content-ID to be used for the given frame. + // See rfc2557 - section 8.3 - "Use of the Content-ID header and CID URLs". + // Format note - the returned string should be of the form "<foo@bar.com>" + // (i.e. the strings should include the angle brackets). + static String GetContentID(Frame* frame); + + FrameSerializerDelegateImpl(WebFrameSerializer::MHTMLPartsGenerationDelegate&, + HeapHashSet<WeakMember<const Element>>&); + ~FrameSerializerDelegateImpl() override = default; + + // FrameSerializer::Delegate implementation. + bool ShouldIgnoreElement(const Element&) override; + bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; + bool RewriteLink(const Element&, String& rewritten_link) override; + bool ShouldSkipResourceWithURL(const KURL&) override; + Vector<Attribute> GetCustomAttributes(const Element&) override; + std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override; + bool ShouldCollectProblemMetric() override; + + private: + bool ShouldIgnoreHiddenElement(const Element&); + bool ShouldIgnoreMetaElement(const Element&); + bool ShouldIgnorePopupOverlayElement(const Element&); + void GetCustomAttributesForImageElement(const HTMLImageElement&, + Vector<Attribute>*); + + WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_; + HeapHashSet<WeakMember<const Element>>& shadow_template_elements_; + bool popup_overlays_skipped_; + + DISALLOW_COPY_AND_ASSIGN(FrameSerializerDelegateImpl); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_SERIALIZER_DELEGATE_IMPL_H_
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index f4d7c97..a6b662c 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -505,8 +505,7 @@ int TestWebFrameClient::loads_in_progress_ = 0; TestWebFrameClient::TestWebFrameClient() - : interface_provider_(new service_manager::InterfaceProvider()), - associated_interface_provider_(new AssociatedInterfaceProvider(nullptr)), + : associated_interface_provider_(new AssociatedInterfaceProvider(nullptr)), effective_connection_type_(WebEffectiveConnectionType::kTypeUnknown) {} TestWebFrameClient::~TestWebFrameClient() = default;
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index 2e79f20f..40f058e3 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -42,7 +42,6 @@ #include "cc/trees/layer_tree_host.h" #include "content/renderer/compositor/layer_tree_view.h" #include "content/test/stub_layer_tree_view_delegate.h" -#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" @@ -440,9 +439,6 @@ FrameOwnerElementType) override; void DidStartLoading() override; void DidStopLoading() override; - service_manager::InterfaceProvider* GetInterfaceProvider() override { - return interface_provider_.get(); - } std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override { // TODO(kinuko,toyoshim): Stop using Platform's URLLoaderFactory, but create @@ -469,10 +465,6 @@ // If set to a non-null value, self-deletes on frame detach. std::unique_ptr<TestWebFrameClient> self_owned_; - // Use service_manager::InterfaceProvider::TestApi to provide test interfaces - // through this client. - std::unique_ptr<service_manager::InterfaceProvider> interface_provider_; - std::unique_ptr<AssociatedInterfaceProvider> associated_interface_provider_; // This is null from when the client is created until it is initialized with
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc index a14c555..37c8f491 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -544,6 +544,7 @@ kViewportHeight + GetLoadingDistanceThreshold() - 100)); css_resource.Complete("img { width: 50px; height: 50px; }"); + test::RunPendingTasks(); Vector<char> full_image = ReadTestImage(); ASSERT_LT(2048U, full_image.size()); @@ -677,6 +678,7 @@ kViewportHeight + GetLoadingDistanceThreshold() + 100)); css_resource.Complete("img { width: 50px; height: 50px; }"); + test::RunPendingTasks(); Compositor().BeginFrame(); test::RunPendingTasks();
diff --git a/third_party/blink/renderer/core/mojo/mojo.idl b/third_party/blink/renderer/core/mojo/mojo.idl index 9bfcfc6..6a9e639 100644 --- a/third_party/blink/renderer/core/mojo/mojo.idl +++ b/third_party/blink/renderer/core/mojo/mojo.idl
@@ -7,14 +7,14 @@ typedef unsigned long MojoResult; enum MojoScope { - // Refers to the InterfaceProvider associated with the current execution + // Refers to the BrowserInterfaceBroker associated with the current execution // context. Either a Document or WorkerGlobalScope. "context", - // Refers to the InterfaceProvider of the current process. + // Refers to the BrowserInterfaceBroker of the current process. // // Note: A "process" is not a web concept. In some cases the browser process // concept of a "site instance" may be useful however there is currently no - // InterfaceProvider per site instance. + // BrowserInterfaceBroker per site instance. "process", };
diff --git a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc index 473044db..a32a6d7 100644 --- a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc +++ b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h" -#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" @@ -84,32 +83,7 @@ "Interface " + interface_name_ + " is already intercepted by another MojoInterfaceInterceptor."); } - return; } - - // TODO(crbug.com/994843): remove when no longer used. - service_manager::InterfaceProvider* interface_provider = - GetInterfaceProvider(); - if (!interface_provider) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "The interface provider is unavailable."); - return; - } - - service_manager::InterfaceProvider::TestApi test_api(interface_provider); - if (test_api.HasBinderForName(interface_name)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidModificationError, - "Interface " + interface_name_ + - " is already intercepted by another MojoInterfaceInterceptor."); - return; - } - - started_ = true; - test_api.SetBinderForName( - interface_name, - WTF::BindRepeating(&MojoInterfaceInterceptor::OnInterfaceRequest, - WrapWeakPersistent(this))); } void MojoInterfaceInterceptor::stop() { @@ -130,15 +104,7 @@ DCHECK(context); context->GetBrowserInterfaceBroker().SetBinderForTesting(interface_name, {}); - return; } - - // TODO(crbug.com/994843): remove when no longer used. - // GetInterfaceProvider() is guaranteed not to return nullptr because this - // method is called when the context is destroyed. - service_manager::InterfaceProvider::TestApi test_api(GetInterfaceProvider()); - DCHECK(test_api.HasBinderForName(interface_name)); - test_api.ClearBinderForName(interface_name); } void MojoInterfaceInterceptor::Trace(blink::Visitor* visitor) { @@ -172,19 +138,10 @@ process_scope_(process_scope), use_browser_interface_broker_(use_browser_interface_broker) {} -service_manager::InterfaceProvider* -MojoInterfaceInterceptor::GetInterfaceProvider() const { - ExecutionContext* context = GetExecutionContext(); - if (!context) - return nullptr; - - return context->GetInterfaceProvider(); -} - void MojoInterfaceInterceptor::OnInterfaceRequest( mojo::ScopedMessagePipeHandle handle) { // Execution of JavaScript may be forbidden in this context as this method is - // called synchronously by the InterfaceProvider. Dispatching of the + // called synchronously by the BrowserInterfaceBroker. Dispatching of the // 'interfacerequest' event is therefore scheduled to take place in the next // microtask. This also more closely mirrors the behavior when an interface // request is being satisfied by another process.
diff --git a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h index 010d146..ab2f0ac 100644 --- a/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h +++ b/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h
@@ -14,10 +14,6 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -namespace service_manager { -class InterfaceProvider; -} - namespace blink { class ExceptionState; @@ -70,7 +66,6 @@ void ContextDestroyed(ExecutionContext*) final; private: - service_manager::InterfaceProvider* GetInterfaceProvider() const; void OnInterfaceRequest(mojo::ScopedMessagePipeHandle); void DispatchInterfaceRequestEvent(mojo::ScopedMessagePipeHandle);
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index c77f16d..7caac9d 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -188,14 +188,10 @@ CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer) : owning_layer_(layer), pending_update_scope_(kGraphicsLayerUpdateNone), - is_main_frame_layout_view_layer_(false), scrolling_contents_are_empty_(false), background_paints_onto_scrolling_contents_layer_(false), background_paints_onto_graphics_layer_(false), draws_background_onto_content_layer_(false) { - if (layer.IsRootLayer() && GetLayoutObject().GetFrame()->IsMainFrame()) - is_main_frame_layout_view_layer_ = true; - CreatePrimaryGraphicsLayer(); }
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h index 83253fe..5514175 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -482,7 +482,6 @@ PhysicalRect composited_bounds_; unsigned pending_update_scope_ : 2; - unsigned is_main_frame_layout_view_layer_ : 1; unsigned scrolling_contents_are_empty_ : 1;
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc index 5fe8f78..611df97 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -92,4 +92,6 @@ void FakeLocalFrameHost::HandleAccessibilityFindInPageTermination() {} +void FakeLocalFrameHost::DocumentOnLoadCompleted() {} + } // namespace blink
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/third_party/blink/renderer/core/testing/fake_local_frame_host.h index ae96d5c..3e789d9 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -59,6 +59,7 @@ void HandleAccessibilityFindInPageResult( mojom::blink::FindInPageResultAXParamsPtr params) override; void HandleAccessibilityFindInPageTermination() override; + void DocumentOnLoadCompleted() override; private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/third_party/blink/renderer/core/testing/page_test_base.h b/third_party/blink/renderer/core/testing/page_test_base.h index 8b0f0036..76aaa7c 100644 --- a/third_party/blink/renderer/core/testing/page_test_base.h +++ b/third_party/blink/renderer/core/testing/page_test_base.h
@@ -45,7 +45,6 @@ void BindClipboardHost(mojo::ScopedMessagePipeHandle handle); MockClipboardHost host_; - std::unique_ptr<service_manager::InterfaceProvider::TestApi> clipboard_api_; }; PageTestBase();
diff --git a/third_party/blink/renderer/core/timing/performance.idl b/third_party/blink/renderer/core/timing/performance.idl index 95bec9b..e618c4a 100644 --- a/third_party/blink/renderer/core/timing/performance.idl +++ b/third_party/blink/renderer/core/timing/performance.idl
@@ -71,7 +71,7 @@ // https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ [Exposed=Window, Measure] readonly attribute MemoryInfo memory; - [Exposed=(Window,Worker), CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MeasureMemory> measureMemory(optional MeasureMemoryOptions options = {}); + [MeasureAs=MeasureMemory, Exposed=(Window,Worker), CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MeasureMemory> measureMemory(optional MeasureMemoryOptions options = {}); // JS Self-Profiling API // https://github.com/WICG/js-self-profiling/
diff --git a/third_party/blink/renderer/platform/audio/fft_frame.h b/third_party/blink/renderer/platform/audio/fft_frame.h index ea19c80fd0..bfd2abd 100644 --- a/third_party/blink/renderer/platform/audio/fft_frame.h +++ b/third_party/blink/renderer/platform/audio/fft_frame.h
@@ -38,13 +38,13 @@ #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/threading.h" -#if defined(OS_MACOSX) -#include <Accelerate/Accelerate.h> -#elif defined(WTF_USE_WEBAUDIO_FFMPEG) +#if defined(WTF_USE_WEBAUDIO_FFMPEG) struct RDFTContext; #elif defined(WTF_USE_WEBAUDIO_PFFFT) #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/pffft/src/pffft.h" +#elif defined(OS_MACOSX) +#include <Accelerate/Accelerate.h> #endif namespace blink { @@ -144,7 +144,7 @@ AudioFloatArray real_data_; AudioFloatArray imag_data_; -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT) // Thin wrapper around FFTSetup so we can call the appropriate routines to // construct or release the FFTSetup objects. class FFTSetupDatum {
diff --git a/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc b/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc index f189a78..3315687 100644 --- a/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc +++ b/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc
@@ -30,7 +30,7 @@ #include "build/build_config.h" -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT) #include "third_party/blink/renderer/platform/audio/fft_frame.h" #include "third_party/blink/renderer/platform/audio/hrtf_panner.h" @@ -201,4 +201,4 @@ } // namespace blink -#endif // #if defined(OS_MACOSX) +#endif // #if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT)
diff --git a/third_party/blink/web_tests/FlagExpectations/composite-after-paint b/third_party/blink/web_tests/FlagExpectations/composite-after-paint index 15b18a8..c2d1863f 100644 --- a/third_party/blink/web_tests/FlagExpectations/composite-after-paint +++ b/third_party/blink/web_tests/FlagExpectations/composite-after-paint
@@ -148,7 +148,9 @@ # Text failures due to layerization differences css3/blending/mix-blend-mode-isolation-remove.html [ Failure ] -virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Timeout ] +# Passes on bot, timeouts locally. +virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Pass Timeout ] + virtual/threaded/compositing/visibility/layer-visible-content.html [ Failure ] crbug.com/931486 compositing/overflow/overlap-testing-ancestor-scroller-high-dpi.html [ Failure ] @@ -217,37 +219,3 @@ crbug.com/1041322 virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen-zoom-out-slow.html [ Crash ] crbug.com/1041322 virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen.html [ Crash ] -# TODO(iopopesc) these need to be rebaselined for FormControlsRefresh focus ring. -crbug.com/1035582 fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Failure ] -crbug.com/1035582 fast/forms/select-popup/popup-menu-appearance-long.html [ Failure ] -crbug.com/1035582 fast/forms/select-popup/popup-menu-appearance-many.html [ Failure ] -crbug.com/1035582 fast/forms/select-popup/popup-menu-appearance-rtl-default.html [ Failure ] -crbug.com/1035582 fast/forms/select-popup/popup-menu-appearance-rtl.html [ Failure ] -crbug.com/1035582 fast/forms/select/listbox-appearance-basic.html [ Failure ] -crbug.com/1035582 paint/invalidation/4776765.html [ Failure ] -crbug.com/1035582 paint/invalidation/clip/caret-ancestor-clip-change.html [ Failure ] -crbug.com/1035582 paint/invalidation/forms/button-reset-focus-by-mouse-then-keydown.html [ Failure ] -crbug.com/1035582 paint/invalidation/forms/checkbox-focus-by-mouse-then-keydown.html [ Failure ] -crbug.com/1035582 paint/invalidation/forms/radio-focus-by-mouse-then-keydown.html [ Failure ] -crbug.com/1035582 paint/invalidation/forms/submit-focus-by-mouse-then-keydown.html [ Failure ] -crbug.com/1035582 paint/invalidation/forms/textarea-caret.html [ Failure ] -crbug.com/1035582 paint/invalidation/invalidate-caret-before-text-node-update.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/focus-continuations.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/focus-enable-continuations.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/focus-ring-on-continuation-move.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/focus-ring-on-inline-continuation-move.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/outline-become-affected-by-descendant.html [ Failure ] -crbug.com/1035582 paint/invalidation/outline/outline-become-not-affected-by-descendant.html [ Failure ] -crbug.com/1035582 paint/invalidation/scroll/invalidate-caret-in-composited-scrolling-container.html [ Failure ] -crbug.com/1035582 paint/invalidation/scroll/invalidate-caret-in-non-composited-scrolling-container.html [ Failure ] -crbug.com/1035582 paint/invalidation/selection/selection-in-composited-scrolling-container.html [ Failure ] -crbug.com/1035582 paint/invalidation/selection/selection-in-non-composited-scrolling-container.html [ Failure ] -crbug.com/1035582 paint/invalidation/svg/focus-element.html [ Failure ] -crbug.com/1035582 paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ] -crbug.com/1035582 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ] -crbug.com/1035582 paint/invalidation/table/caret-contenteditable-content-after.html [ Failure ] -crbug.com/1035582 virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] -crbug.com/1035582 virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ] -crbug.com/1035582 virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ] - -external/wpt/css/compositing/root-element-blend-mode.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ec41473..70a3b6a8 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -53,7 +53,6 @@ crbug.com/1014421 external/wpt/css/cssom-view/MediaQueryList-addListener-handleEvent.html [ Timeout ] # Tested by paint/background/root-element-background-transparency.html for now. -external/wpt/css/compositing/root-element-background-transparency.html [ Failure ] # ====== Site Isolation failures from here ====== # See also third_party/blink/web_tests/virtual/not-site-per-process/README.md @@ -374,6 +373,8 @@ crbug.com/1042453 [ Win ] external/wpt/css/filter-effects/idlharness.any.html [ Timeout Pass ] crbug.com/1042453 [ Mac ] external/wpt/css/filter-effects/idlharness.any.html [ Timeout Pass ] +crbug.com/1042453 [ Win ] external/wpt/css/filter-effects/idlharness.any.worker.html [ Timeout Pass ] +crbug.com/1042453 [ Mac ] external/wpt/css/filter-effects/idlharness.any.worker.html [ Timeout Pass ] crbug.com/1042783 external/wpt/css/css-backgrounds/background-size/background-size-near-zero-png.html [ Failure ] crbug.com/1042783 external/wpt/css/css-backgrounds/background-size/background-size-near-zero-svg.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json index 4d914979..b1ced03 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json
@@ -37,6 +37,12 @@ {} ] ], + "css/css-flexbox/zero-content-size-with-scrollbar-crash.html": [ + [ + "css/css-flexbox/zero-content-size-with-scrollbar-crash.html", + {} + ] + ], "css/css-grid/subgrid/contain-strict-nested-subgrid-crash.html": [ [ "css/css-grid/subgrid/contain-strict-nested-subgrid-crash.html", @@ -158896,6 +158902,9 @@ "fetch/api/policies/referrer-no-referrer.js.headers": [ [] ], + "fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https-expected.txt": [ + [] + ], "fetch/api/policies/referrer-origin-when-cross-origin.html.headers": [ [] ], @@ -347606,7 +347615,7 @@ "support" ], "README.md": [ - "3b580da869015b968668bec6a26f3137f4a020a0", + "482da428db4ab90a006754ccc40209e9f2f13b7d", "support" ], "WebCryptoAPI/META.yml": [ @@ -383389,6 +383398,10 @@ "bec931a4e331192704701d261807e9b0ce7d3c6b", "reftest" ], + "css/css-flexbox/zero-content-size-with-scrollbar-crash.html": [ + "c38659a9d8cff6d0003793896dc83cc78e7a22c4", + "crashtest" + ], "css/css-font-loading/META.yml": [ "3ac9b655b0606783334ff91f9fba852df8efdbc1", "support" @@ -452145,6 +452158,10 @@ "4018b837816e669e2819e7731e46a2bdcf141732", "testharness" ], + "fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https-expected.txt": [ + "5826fb328be576189a361a092663a7cfc681c921", + "support" + ], "fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https.html": [ "d87192e227119a5a139beedf65bffb5c91a64f79", "testharness" @@ -452154,7 +452171,7 @@ "testharness" ], "fetch/api/policies/referrer-origin-when-cross-origin.html": [ - "18de7364634d18a79861309172ec75ee83676208", + "5cd79e4b53615995cb79ad8ad06d9b405151be71", "testharness" ], "fetch/api/policies/referrer-origin-when-cross-origin.html.headers": [ @@ -452162,7 +452179,7 @@ "support" ], "fetch/api/policies/referrer-origin-when-cross-origin.js": [ - "7cd4113f506f26c91275eb65361fc4887e9d1398", + "0adadbc55081f0dbb9250be1cec89c7134603bb3", "support" ], "fetch/api/policies/referrer-origin-when-cross-origin.js.headers": [ @@ -458266,7 +458283,7 @@ "support" ], "html/cross-origin-opener-policy/blob-popup.https.html": [ - "4aef1b848917c1f2901eb696a39d5d7f1369a063", + "a4e53e7806267049b9190019e2061fd77ac3073a", "testharness" ], "html/cross-origin-opener-policy/blob-popup.https.html.headers": [ @@ -458286,7 +458303,7 @@ "support" ], "html/cross-origin-opener-policy/coep-navigate-popup.https.html": [ - "391929e75cf93c7d9dee24141398c6d6f80135be", + "714a4b6c4270900282328af1aacadc8592a0b44e", "testharness" ], "html/cross-origin-opener-policy/coep-navigate-popup.https.html.headers": [ @@ -458302,15 +458319,15 @@ "support" ], "html/cross-origin-opener-policy/coep-navigate-popup.https_4-last-expected.txt": [ - "1e74c90db47ce01fbbe413e8b758d15a021cd3f9", + "c323a77a1e49594ddbf3445592f3d16b190fa1d1", "support" ], "html/cross-origin-opener-policy/coep-redirect.https-expected.txt": [ - "fd033fd632fe81a9f8adf6c93468f21bc8e1ea9b", + "7fd7dc9b2cdbcbf65ae28a1fdaf5aa6cfcbaaf98", "support" ], "html/cross-origin-opener-policy/coep-redirect.https.html": [ - "2c41a92e12f9c77bb4268bbf39c38ff5d7c87fd7", + "83f8f8a33d4b2c9c7f23c02011bcc568836e62ea", "testharness" ], "html/cross-origin-opener-policy/coep-redirect.https.html.headers": [ @@ -458318,11 +458335,11 @@ "support" ], "html/cross-origin-opener-policy/coep.https-expected.txt": [ - "4409826428c16d7a8ffb4f670fe3177f51432310", + "2b4a10cb374a5cef3975f0be501c0e8b677ff520", "support" ], "html/cross-origin-opener-policy/coep.https.html": [ - "e909f6275faac90e279a32f68bad34afca27af21", + "f6d975564f4fd0a5d272ea6977b7aa93c64e4794", "testharness" ], "html/cross-origin-opener-policy/coep.https.html.headers": [ @@ -458338,11 +458355,11 @@ "testharness" ], "html/cross-origin-opener-policy/coop-navigated-popup.https-expected.txt": [ - "66b2fb564b7063988271105b3d50aa73b8e5e0ff", + "5540bd3e8165ca13fd265edc215e864444c24d9d", "support" ], "html/cross-origin-opener-policy/coop-navigated-popup.https.html": [ - "3c6019ace0b308562cca08d6d6bfd6484882e1db", + "e1741932919a426429083544ce44e2f4438cab3d", "testharness" ], "html/cross-origin-opener-policy/coop-navigated-popup.https.html.headers": [ @@ -458506,11 +458523,11 @@ "support" ], "html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https-expected.txt": [ - "a0c0e0c6d0803474302667292771736e95f106c2", + "09d81b126a031dd332726d6466c5383483c0a04f", "support" ], "html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html": [ - "4c70b1102fd5329c64835203d70a2b5611c54111", + "635f7ab3b872c49c436a5cfcb387e63100322ea3", "testharness" ], "html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html.headers": [ @@ -458570,7 +458587,7 @@ "support" ], "html/cross-origin-opener-policy/popup-redirect-cache.https.html": [ - "f05eb492c03234fd5b7620d042bbff0b5b4afda4", + "d68c80664bc549ca0e9786653bc0b3759ca31953", "testharness" ], "html/cross-origin-opener-policy/popup-redirect-cache.https.html.headers": [ @@ -458730,11 +458747,11 @@ "support" ], "html/cross-origin-opener-policy/resources/common.js": [ - "59ba33d65b04e26c1db810783b7fdcc96dee8954", + "760db60365fbe79a70d37c770a48a162c5058002", "support" ], "html/cross-origin-opener-policy/resources/coop-coep.py": [ - "e6f655ab728107e4bac31cd7748711f719b01bd3", + "0271d7834af98a1d25fd2869c11c6f56b08bfcd3", "support" ], "html/cross-origin-opener-policy/resources/iframe-popup.sub.html": [ @@ -458742,7 +458759,7 @@ "support" ], "html/cross-origin-opener-policy/resources/postback.html": [ - "cf3c93bbe1d3589e9a649db34995e02e2ac9c1e4", + "5955e2d7593a51fa112fe82bb97b79add54f3ba0", "support" ], "html/cross-origin-opener-policy/resources/postback.html.headers": [ @@ -467942,7 +467959,7 @@ "testharness" ], "html/semantics/embedded-content/the-canvas-element/security.pattern.fillStyle.sub.html": [ - "6695138c57b6556d29fc6070efa5f1542f9fa3c1", + "70c5f194ff63bedea313fe924f8c2f80849d9bb5", "testharness" ], "html/semantics/embedded-content/the-canvas-element/security.pattern.image.fillStyle.cross.html": [ @@ -522002,7 +522019,7 @@ "support" ], "tools/wptrunner/wptrunner/executors/executorselenium.py": [ - "ceca81211e1140577cc3a5f163ffe17c73dd56a3", + "39d723a788662dd55c2707eb8d670dba6237cd3c", "support" ], "tools/wptrunner/wptrunner/executors/executorservo.py": [ @@ -522014,7 +522031,7 @@ "support" ], "tools/wptrunner/wptrunner/executors/executorwebdriver.py": [ - "0b329210fc546f9ee50a8a4d0ae02133e3446106", + "d09eb1e145170243dc9e74aa68f53d05154283fa", "support" ], "tools/wptrunner/wptrunner/executors/executorwebkit.py": [ @@ -522186,7 +522203,7 @@ "support" ], "tools/wptrunner/wptrunner/wptcommandline.py": [ - "91f1161b01b99f31ef1d3dde05333627bf4365b2", + "5b7278b99ff4bfe03981f87671a240141bd0a037", "support" ], "tools/wptrunner/wptrunner/wptlogging.py": [
diff --git a/third_party/blink/web_tests/external/wpt/README.md b/third_party/blink/web_tests/external/wpt/README.md index 3b580da..482da42 100644 --- a/third_party/blink/web_tests/external/wpt/README.md +++ b/third_party/blink/web_tests/external/wpt/README.md
@@ -3,16 +3,15 @@ [](https://community-tc.services.mozilla.com/api/github/v1/repository/web-platform-tests/wpt/master/latest) -The web-platform-tests Project is a W3C-coordinated attempt to build a -cross-browser test suite for the Web-platform stack. Writing tests in a way -that allows them to be run in all browsers gives browser projects -confidence that they are shipping software that is compatible with other -implementations, and that later implementations will be compatible with -their implementations. This in turn gives Web authors/developers -confidence that they can actually rely on the Web platform to deliver on -the promise of working across browsers and devices without needing extra -layers of abstraction to paper over the gaps left by specification -editors and implementors. +The web-platform-tests Project is a cross-browser test suite for the +Web-platform stack. Writing tests in a way that allows them to be run in all +browsers gives browser projects confidence that they are shipping software that +is compatible with other implementations, and that later implementations will +be compatible with their implementations. This in turn gives Web +authors/developers confidence that they can actually rely on the Web platform +to deliver on the promise of working across browsers and devices without +needing extra layers of abstraction to paper over the gaps left by +specification editors and implementors. The most important sources of information and activity are:
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency-ref.html deleted file mode 100644 index 4671d44..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency-ref.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!doctype HTML> -<title>Backround color transparency on the root element blends with a white backdrop</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<html style="background: rgb(150, 150, 150)"> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency.html deleted file mode 100644 index 910eb08..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-background-transparency.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!doctype HTML> -<title>Backround color transparency on the root element blends with a white backdrop</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<link rel="match" href="root-element-background-transparency-ref.html"> -<html style="background: rgba(45, 45, 45, 0.5)"> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode-ref.html deleted file mode 100644 index 14c99f7..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode-ref.html +++ /dev/null
@@ -1,6 +0,0 @@ -<!doctype HTML> -<title>Blend-mode on the root stacking context blends with the root element's background.</title> -<html style="background: #000"> - <div style="width: 50px; height: 50px; background: #000"></div> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode.html deleted file mode 100644 index 2c97d8b..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-blend-mode.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!doctype HTML> -<title>Blend-mode on the root stacking context blends with the root element's background.</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<link rel="match" href="root-element-blend-mode-ref.html"> -<html style="background: #000;"> - <div style="width: 50px; height: 50px; background: #E33; mix-blend-mode: multiply"></div> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter-ref.html deleted file mode 100644 index 27cfb11b..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter-ref.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!doctype HTML> -<title>A filter on the root element applies to its background</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<html style="background: #FFF"> - <div style="width: 50px; height: 50px; background: #1CC"></div> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter.html deleted file mode 100644 index 62bde9df..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-filter.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!doctype HTML> -<title>A filter on the root element applies to its background</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<link rel="match" href="root-element-filter-ref.html"> -<html style="filter: invert(1); background: #000"> - <div style="width: 50px; height: 50px; background: #E33"></div> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity-ref.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity-ref.html deleted file mode 100644 index be2348a..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity-ref.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!doctype HTML> -<title>Opacity on the root element blends with a white backdrop</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<html style="background: #DDD"> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity.html b/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity.html deleted file mode 100644 index 4885d805..0000000 --- a/third_party/blink/web_tests/external/wpt/css/compositing/root-element-opacity.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!doctype HTML> -<title>Opacity on the root element blends with a white background</title> -<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> -<link rel="help" href="https://drafts.fxtf.org/compositing/#pagebackdrop"> -<link rel="match" href="root-element-opacity-ref.html"> -<html style="background: #BBB; opacity: 0.5"> - <div id=spacer style="width: 100px; height: 3000px"></div> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https-expected.txt new file mode 100644 index 0000000..5826fb3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Fetch in service worker: referrer with origin-when-cross-origin policy +FAIL Request's referrer is origin promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.html b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.html index 18de736..5cd79e4b 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.html +++ b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.html
@@ -7,6 +7,7 @@ <meta name="help" href="https://fetch.spec.whatwg.org/#http-network-or-cache-fetch"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> + <script src="/common/get-host-info.sub.js"></script> </head> <body> <script src="../resources/utils.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.js b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.js index 7cd4113f..0adadbc5 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.js +++ b/third_party/blink/web_tests/external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.js
@@ -1,6 +1,7 @@ if (this.document === undefined) { importScripts("/resources/testharness.js"); importScripts("../resources/utils.js"); + importScripts("/common/get-host-info.sub.js"); // A nested importScripts() with a referrer-policy should have no effect // on overall worker policy. @@ -8,7 +9,7 @@ } var referrerOrigin = location.origin + '/'; -var fetchedUrl = "https://{{domains[www]}}:{{ports[https][0]}}" + dirname(location.pathname) + RESOURCES_DIR + "inspect-headers.py?cors&headers=referer"; +var fetchedUrl = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + "inspect-headers.py?cors&headers=referer"; promise_test(function(test) { return fetch(fetchedUrl).then(function(resp) {
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html index 4aef1b8..a4e53e7 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/blob-popup.https.html
@@ -20,15 +20,17 @@ const blobContents = `<script> const w = window.open("${get_host_info().HTTPS_REMOTE_ORIGIN}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=x&coep=x&channel=${bc.name}", "${bc.name}"); window.opener.furtherPopup = w; - -// w will be closed by its postback iframe. When out of process, -// window.close() does not work. -window.opener.test.add_cleanup(() => w.close()); <\/script>`; const blob = new Blob([blobContents], { type: "text/html" }); const blobURL = URL.createObjectURL(blob); const popup = window.open(blobURL); - t.add_cleanup(() => popup.close()); + t.add_cleanup(() => { + // Close the popups once the test is complete. + // The browsing context of the second popup is closed hence use the + // broadcast channel to trigger the closure. + bc.postMessage("close"); + popup.close(); + }); popup.onload = t.step_func(() => { assert_equals(popup.opener, window); assert_equals(popup.location.href, blobURL);
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https.html index 391929e7..714a4b6 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https.html
@@ -39,7 +39,7 @@ "title": "coop unsafe-none/coep", "coop": "unsafe-none", "coep": "require-corp", - "opener": true + "opener": false }, { "title": "coop unsafe-none/no coep",
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https_4-last-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https_4-last-expected.txt index 1e74c90..c323a77a 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https_4-last-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-navigate-popup.https_4-last-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -PASS Popup navigating to same-origin with coop unsafe-none/coep +FAIL Popup navigating to same-origin with coop unsafe-none/coep assert_equals: name expected "" but got "Popup-navigating-to-same-origin-with-coop-unsafe-none/coep" FAIL Popup navigating to same-site with coop unsafe-none/coep assert_equals: name expected "" but got "Popup-navigating-to-same-site-with-coop-unsafe-none/coep" FAIL Popup navigating to same-origin with coop unsafe-none/no coep assert_equals: name expected "" but got "Popup-navigating-to-same-origin-with-coop-unsafe-none/no-coep" FAIL Popup navigating to same-site with coop unsafe-none/no coep assert_equals: name expected "" but got "Popup-navigating-to-same-site-with-coop-unsafe-none/no-coep"
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https-expected.txt index fd033fd..7fd7dc9 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https-expected.txt
@@ -3,7 +3,7 @@ FAIL Redirect from coop/coep to no coop/coep assert_equals: name expected "" but got "Redirect-from-coop/coep-to-no-coop/coep" FAIL Redirect from no coop/no coep to coop/coep assert_equals: name expected "" but got "Redirect-from-no-coop/no-coep-to-coop/coep" FAIL Redirect from coop/no coep to coop/coep assert_equals: name expected "" but got "Redirect-from-coop/no-coep-to-coop/coep" -PASS Redirect from coop unsafe-none/coep to coop/coep -PASS Redirect from coop unsafe-none/coep to coop unsafe-inherit/coep +FAIL Redirect from coop unsafe-none/coep to coop/coep assert_equals: name expected "" but got "Redirect-from-coop-unsafe-none/coep-to-coop/coep" +FAIL Redirect from coop unsafe-none/coep to coop unsafe-inherit/coep assert_equals: name expected "" but got "Redirect-from-coop-unsafe-none/coep-to-coop-unsafe-inherit/coep" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https.html index 2c41a92..83f8f8a 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep-redirect.https.html
@@ -47,7 +47,7 @@ "redirectCOEP": "require-corp", "coop": "same-origin", "coep": "require-corp", - "opener": true + "opener": false }, { "title": "coop unsafe-none/coep to coop unsafe-inherit/coep", @@ -55,7 +55,7 @@ "redirectCOEP": "require-corp", "coop": "unsafe-none", "coep": "require-corp", - "opener": true + "opener": false } ].forEach(variant => { const title = `Redirect from ${variant.title}`;
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt index 4409826..2b4a10c 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. PASS Same-origin popup with coop/coep FAIL historical: "same-site" popup with coop/coep assert_equals: name expected "" but got "same-site-popup-with-coop/coep" -PASS Same-origin popup with coop unsafe-none/coep +FAIL Same-origin popup with coop unsafe-none/coep assert_equals: name expected "" but got "popup-with-coop-unsafe-none/coep" FAIL historical: "same-site" popup with coop unsafe-none/coep assert_equals: name expected "" but got "same-site-popup-with-coop-unsafe-none/coep" FAIL Same-origin popup with coop unsafe-none without coep assert_equals: name expected "" but got "popup-with-coop-unsafe-none-without-coep" FAIL historical: "same-site" popup with coop unsafe-none without coep assert_equals: name expected "" but got "same-site-popup-with-coop-unsafe-none-without-coep"
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html index e909f62..f6d9755 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html
@@ -17,7 +17,7 @@ "title": "popup with coop unsafe-none/coep", "coop": "unsafe-none", "coep": "require-corp", - "opener": true + "opener": false }, { "title": "popup with coop unsafe-none without coep",
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https-expected.txt index 66b2fb5..5540bd3 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https-expected.txt
@@ -1,4 +1,5 @@ This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = Test named 'Open a popup to a document without COOP, then navigate it to a document with' specified 1 'cleanup' function, and 1 failed. FAIL Open a popup to a document without COOP, then navigate it to a document with assert_equals: expected 0 but got 36 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https.html index 3c6019a..e174193 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coop-navigated-popup.https.html
@@ -12,7 +12,12 @@ const noCOOP = "/common/blank.html"; const popupName = token(); const popup = window.open(noCOOP, popupName); - t.add_cleanup(() => popup.close()); + // Close the popup once the test is complete. + // The browsing context is closed after the navigation hence use the broadcast channel + // to trigger the closure. + t.add_cleanup(() => { + bc.postMessage("close"); + }); popup.onload = t.step_func(() => { assert_equals(popup.name, popupName); assert_equals(new URL(popup.document.URL).pathname, noCOOP); @@ -23,6 +28,7 @@ // string comparison to "" to keep the random token out of error messages. assert_equals(payload.name.length, 0); assert_false(payload.opener); + assert_true(popup.closed); }); const coop = `resources/coop-coep.py?coop=same-origin&coep=&channel=${channel.name}`; popup.location = coop;
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https-expected.txt index a0c0e0c..09d81b1 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https-expected.txt
@@ -1,12 +1,12 @@ This is a testharness.js-based test. PASS same-origin with SAME_ORIGIN iframe opening popup a SAME_ORIGIN with COOP: same-origin -PASS same-origin with SAME_SITE iframe opening popup a SAME_ORIGIN with COOP: same-origin -PASS same-origin with CROSS_ORIGIN iframe opening popup a SAME_ORIGIN with COOP: same-origin +FAIL same-origin with SAME_SITE iframe opening popup a SAME_ORIGIN with COOP: same-origin assert_equals: name expected "" but got "SAME_SITE_iframe_opening_SAME_ORIGIN_popup_with_coop_same-origin" +FAIL same-origin with CROSS_ORIGIN iframe opening popup a SAME_ORIGIN with COOP: same-origin assert_equals: name expected "" but got "CROSS_ORIGIN_iframe_opening_SAME_ORIGIN_popup_with_coop_same-origin" FAIL same-origin with SAME_ORIGIN iframe opening popup a SAME_SITE with COOP: same-origin assert_equals: opener expected false but got true -PASS same-origin with SAME_SITE iframe opening popup a SAME_SITE with COOP: same-origin -PASS same-origin with CROSS_ORIGIN iframe opening popup a SAME_SITE with COOP: same-origin +FAIL same-origin with SAME_SITE iframe opening popup a SAME_SITE with COOP: same-origin assert_equals: name expected "" but got "SAME_SITE_iframe_opening_SAME_SITE_popup_with_coop_same-origin" +FAIL same-origin with CROSS_ORIGIN iframe opening popup a SAME_SITE with COOP: same-origin assert_equals: name expected "" but got "CROSS_ORIGIN_iframe_opening_SAME_SITE_popup_with_coop_same-origin" FAIL same-origin with SAME_ORIGIN iframe opening popup a CROSS_ORIGIN with COOP: same-origin assert_equals: opener expected false but got true -PASS same-origin with SAME_SITE iframe opening popup a CROSS_ORIGIN with COOP: same-origin -PASS same-origin with CROSS_ORIGIN iframe opening popup a CROSS_ORIGIN with COOP: same-origin +FAIL same-origin with SAME_SITE iframe opening popup a CROSS_ORIGIN with COOP: same-origin assert_equals: name expected "" but got "SAME_SITE_iframe_opening_CROSS_ORIGIN_popup_with_coop_same-origin" +FAIL same-origin with CROSS_ORIGIN iframe opening popup a CROSS_ORIGIN with COOP: same-origin assert_equals: name expected "" but got "CROSS_ORIGIN_iframe_opening_CROSS_ORIGIN_popup_with_coop_same-origin" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html index 4c70b110..635f7ab 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-same-origin.https.html
@@ -10,14 +10,14 @@ <script> [ [SAME_ORIGIN, SAME_ORIGIN, "same-origin", true, true], -[SAME_SITE, SAME_ORIGIN, "same-origin", false, true], -[CROSS_ORIGIN, SAME_ORIGIN, "same-origin", false, true], +[SAME_SITE, SAME_ORIGIN, "same-origin", false, false], +[CROSS_ORIGIN, SAME_ORIGIN, "same-origin", false, false], [SAME_ORIGIN, SAME_SITE, "same-origin", false, false], -[SAME_SITE, SAME_SITE, "same-origin", false, true], -[CROSS_ORIGIN, SAME_SITE, "same-origin", false, true], +[SAME_SITE, SAME_SITE, "same-origin", false, false], +[CROSS_ORIGIN, SAME_SITE, "same-origin", false, false], [SAME_ORIGIN, CROSS_ORIGIN, "same-origin", false, false], -[SAME_SITE, CROSS_ORIGIN, "same-origin", false, true], -[CROSS_ORIGIN, CROSS_ORIGIN, "same-origin", false, true], +[SAME_SITE, CROSS_ORIGIN, "same-origin", false, false], +[CROSS_ORIGIN, CROSS_ORIGIN, "same-origin", false, false], ].forEach( value => { run_coop_test_iframe("same-origin", value[0], value[1], value[2], value[3], value[4]); });
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html index f05eb49..d68c806 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-cache.https.html
@@ -15,6 +15,7 @@ const payload = event.data; assert_equals(payload.name, hasOpener ? channelName : ""); assert_equals(payload.opener, hasOpener); + assert_equals(w.closed, !hasOpener); bc.close() // test the same url for cache @@ -23,9 +24,7 @@ const w = window.open(url, channelName); - // w will be closed by its postback iframe. When out of process, - // window.close() does not work. - t.add_cleanup(() => w.close()); + // The popup is closed by url_test. } // Redirect from hostA to hostB with same coop and coep.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js index 59ba33d6..760db60 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/common.js
@@ -12,13 +12,17 @@ if (openerDOMAccess !== undefined) { assert_equals(payload.openerDOMAccess, openerDOMAccess, 'openerDOMAccess'); } + assert_equals(w.closed, !hasOpener, 'Openee browsing context closed'); }); const w = window.open(url, channelName); - // w will be closed by its postback iframe. When out of process, - // window.close() does not work. - t.add_cleanup(() => w.close()); + // Close the popup once the test is complete. + // The browsing context might be closed hence use the broadcast channel + // to trigger the closure. + t.add_cleanup(() => { + bc.postMessage("close"); + }); } function coop_coep_test(t, host, coop, coep, channelName, hasOpener, openerDOMAccess) { @@ -43,7 +47,14 @@ const name = iframe_origin.name + "_iframe_opening_" + popup_origin.name + "_popup_with_coop_" + popup_coop; async_test(t => { const frame = document.createElement("iframe"); - t.add_cleanup(() => { frame.remove(); }); + + // Close the popup and remove the frame once the test is + // complete. The browsing context might be closed hence use the + // broadcast channel to trigger the closure. + t.add_cleanup(() => { + frame.remove(); + bc.postMessage("close"); + }); const origin = CROSS_ORIGIN.origin; const path = new URL("resources/iframe-popup.sub.html", window.location).pathname;
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py index e6f655ab..0271d78 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/coop-coep.py
@@ -50,6 +50,13 @@ openerDOMAccessAllowed = !!self.opener.document.URL; } catch(ex) { } + // Handle the response from the frame, closing the popup once the + // test completes. + addEventListener("message", event => { + if (event.data == "close") { + close(); + } + }); const iframe = document.querySelector("iframe"); iframe.onload = () => { const payload = { name: self.name, opener: !!self.opener, openerDOMAccess: openerDOMAccessAllowed };
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/postback.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/postback.html index cf3c93b..5955e2d 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/postback.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/postback.html
@@ -3,8 +3,17 @@ <script> const channelName = new URL(location).searchParams.get("channel"); const bc = new BroadcastChannel(channelName); + +// Handle the close message from the test-cleanup, forwarding it to the +// top level document, as this iframe and the opening document might not +// be able to close the popup. +bc.onmessage = event => { + if (event.data == "close") { + top.postMessage("close", "*"); + } +}; + window.addEventListener("message", event => { bc.postMessage(event.data); - window.parent.close(); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/security.pattern.fillStyle.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/security.pattern.fillStyle.sub.html index 6695138c..70c5f19 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/security.pattern.fillStyle.sub.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/security.pattern.fillStyle.sub.html
@@ -3,6 +3,7 @@ <title>Canvas test: security.pattern.canvas.fillStyle.cross</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> <script src="/common/media.js"></script> <script src="/2dcontext/resources/canvas-tests.js"></script> @@ -11,8 +12,8 @@ <script> -forEachCanvasSource("http://{{domains[www1]}}:{{ports[http][0]}}", - "http://{{domains[]}}:{{ports[http][0]}}", +forEachCanvasSource(get_host_info().HTTP_REMOTE_ORIGIN, + get_host_info().HTTP_ORIGIN, (name, factory) => { promise_test(_ => { return factory().then(source => {
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py index ceca8121..39d723a 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
@@ -1,11 +1,12 @@ +from __future__ import absolute_import import json import os import socket import threading import time import traceback -import urlparse import uuid +from six.moves.urllib.parse import urljoin from .base import (CallbackHandler, RefTestExecutor, @@ -87,8 +88,8 @@ def load_runner(self, url_protocol): if self.runner_handle: self.webdriver.switch_to_window(self.runner_handle) - url = urlparse.urljoin(self.parent.executor.server_url(url_protocol), - "/testharness_runner.html") + url = urljoin(self.parent.executor.server_url(url_protocol), + "/testharness_runner.html") self.logger.debug("Loading %s" % url) self.webdriver.get(url) self.runner_handle = self.webdriver.current_window_handle
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py index 0b32921..d09eb1e1 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
@@ -1,11 +1,12 @@ +from __future__ import absolute_import import json import os import socket import threading import time import traceback -import urlparse import uuid +from six.moves.urllib.parse import urljoin from .base import (CallbackHandler, CrashtestExecutor, @@ -86,8 +87,8 @@ def load_runner(self, url_protocol): if self.runner_handle: self.webdriver.window_handle = self.runner_handle - url = urlparse.urljoin(self.parent.executor.server_url(url_protocol), - "/testharness_runner.html") + url = urljoin(self.parent.executor.server_url(url_protocol), + "/testharness_runner.html") self.logger.debug("Loading %s" % url) self.webdriver.url = url
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py index 91f1161b..5b7278b 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
@@ -1,4 +1,4 @@ -from __future__ import print_function +from __future__ import absolute_import, print_function import argparse import os import sys @@ -16,9 +16,9 @@ def url_or_path(path): - import urlparse + from six.moves.urllib.parse import urlparse - parsed = urlparse.urlparse(path) + parsed = urlparse(path) if len(parsed.scheme) > 2: return path else:
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/lots-of-img-layers-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/lots-of-img-layers-expected.png deleted file mode 100644 index 6f9fc57..0000000 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/lots-of-img-layers-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png deleted file mode 100644 index 0468f555..0000000 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/checkbox-focus-by-mouse-then-keydown-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/checkbox-focus-by-mouse-then-keydown-expected.txt index 2c6302f..8be630f 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/checkbox-focus-by-mouse-then-keydown-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/checkbox-focus-by-mouse-then-keydown-expected.txt
@@ -7,8 +7,8 @@ "backgroundColor": "#FFFFFF", "paintInvalidations": [ { - "object": "LayoutBlockFlow INPUT", - "rect": [10, 9, 17, 17], + "object": "LayoutNGBlockFlow INPUT", + "rect": [8, 7, 21, 21], "reason": "subtree" } ]
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.txt index 7d8a007..5022cf1f 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.txt
@@ -8,7 +8,7 @@ "paintInvalidations": [ { "object": "LayoutSlider INPUT", - "rect": [9, 9, 131, 18], + "rect": [8, 8, 133, 20], "reason": "subtree" }, {
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt index e4dbf1a..84335d70 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt
@@ -18,7 +18,7 @@ }, { "object": "NGPhysicalBoxFragment LayoutInline A", - "rect": [382, 970, 44, 23], + "rect": [380, 968, 48, 27], "reason": "appeared" }, {
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png deleted file mode 100644 index 4570a36c..0000000 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png deleted file mode 100644 index f6ef9da..0000000 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance-expected.png deleted file mode 100644 index 88c1c1ca..0000000 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..5b79a7f --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/BUILD.gn index 149d87b..fb3178f 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn index facca4f5..0d01e51 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/BUILD.gn index 293bea7..79ed522 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-a11y-keys-extracted") { - deps = [ - "../iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", - ] + deps = [ "../iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-behaviors/BUILD.gn index e3dd06a9..3306dd1 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-collapse/BUILD.gn index 301a4e3..6cf68037 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-collapse/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-collapse-extracted") { - deps = [ - "../iron-resizable-behavior:iron-resizable-behavior-extracted", - ] + deps = [ "../iron-resizable-behavior:iron-resizable-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-dropdown/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-dropdown/BUILD.gn index 1fe9c23..074a228 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-dropdown/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-dropdown/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -16,7 +16,5 @@ } js_library("iron-dropdown-scroll-manager-extracted") { - deps = [ - "../iron-overlay-behavior:iron-scroll-manager-extracted", - ] + deps = [ "../iron-overlay-behavior:iron-scroll-manager-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/BUILD.gn index 7410bdc..22f0e261 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-icon/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-icon/BUILD.gn index 504bc78..a8c5db3 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-icon/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-icon/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-icon-extracted") { - deps = [ - "../iron-meta:iron-meta-extracted", - ] + deps = [ "../iron-meta:iron-meta-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/BUILD.gn index 4010b38..7102e40 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-iconset-svg-extracted") { - deps = [ - "../iron-meta:iron-meta-extracted", - ] + deps = [ "../iron-meta:iron-meta-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-input/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-input/BUILD.gn index c21a07f..8ee4910f 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-input/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-input/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-list/BUILD.gn index 43f8943..7dc5cd7e 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-list/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-list/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-location/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-location/BUILD.gn index e502ced..b6d216f2 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-location/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-location/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-media-query/BUILD.gn index 05879f1..2e96db5 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-media-query/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-meta/BUILD.gn index 3b207b2..5458d02 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-meta/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-meta/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/BUILD.gn index 9305be9..f9ed61f 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-pages/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-pages/BUILD.gn index 430f3615..9e3979d 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-pages/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-pages/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/BUILD.gn index c906aeb2..6ef24aa7 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/BUILD.gn index b04c9fb..81c96523 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-scroll-target-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-scroll-target-behavior/BUILD.gn index 3b41716..3593f9b 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-scroll-target-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-scroll-target-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/BUILD.gn index 9b65c19..66b9197 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,6 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-scroll-threshold-extracted") { - deps = [ - "../iron-scroll-target-behavior:iron-scroll-target-behavior-extracted", - ] + deps = + [ "../iron-scroll-target-behavior:iron-scroll-target-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-selector/BUILD.gn index 3ae53a1d7..99546aec 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-selector/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-selector/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,22 +7,16 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-multi-selectable-extracted") { - deps = [ - ":iron-selectable-extracted", - ] + deps = [ ":iron-selectable-extracted" ] } js_library("iron-selectable-extracted") { - deps = [ - ":iron-selection-extracted", - ] + deps = [ ":iron-selection-extracted" ] } js_library("iron-selection-extracted") { } js_library("iron-selector-extracted") { - deps = [ - ":iron-multi-selectable-extracted", - ] + deps = [ ":iron-multi-selectable-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/BUILD.gn b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/BUILD.gn index cd8d61e..8ca3573 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-validatable-behavior-extracted") { - deps = [ - "../iron-meta:iron-meta-extracted", - ] + deps = [ "../iron-meta:iron-meta-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/BUILD.gn b/third_party/polymer/v1_0/components-chromium/neon-animation/BUILD.gn index d27d489..96b8ea5 100644 --- a/third_party/polymer/v1_0/components-chromium/neon-animation/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/neon-animation/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -28,7 +28,5 @@ } js_library("neon-animation-runner-behavior-extracted") { - deps = [ - ":neon-animatable-behavior-extracted", - ] + deps = [ ":neon-animatable-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/animations/BUILD.gn b/third_party/polymer/v1_0/components-chromium/neon-animation/animations/BUILD.gn index 68a8d82..6dfbe86 100644 --- a/third_party/polymer/v1_0/components-chromium/neon-animation/animations/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/neon-animation/animations/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,13 +7,9 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("fade-in-animation-extracted") { - deps = [ - "..:neon-animation-behavior-extracted", - ] + deps = [ "..:neon-animation-behavior-extracted" ] } js_library("fade-out-animation-extracted") { - deps = [ - "..:neon-animation-behavior-extracted", - ] + deps = [ "..:neon-animation-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-behaviors/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-behaviors/BUILD.gn index ee3258f..e52d3bc 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-behaviors/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-behaviors/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-input/BUILD.gn index 4e8f276f..3f679707 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-input/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-input/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -13,7 +13,5 @@ } js_library("paper-input-error-extracted") { - deps = [ - ":paper-input-addon-behavior-extracted", - ] + deps = [ ":paper-input-addon-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-progress/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-progress/BUILD.gn index d3f60da..f84054a 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-progress/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-progress/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("paper-progress-extracted") { - deps = [ - "../iron-range-behavior:iron-range-behavior-extracted", - ] + deps = [ "../iron-range-behavior:iron-range-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-ripple/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-ripple/BUILD.gn index aab1bad..01b5adf9 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-ripple/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-ripple/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("paper-ripple-extracted") { - deps = [ - "../iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", - ] + deps = [ "../iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-spinner/BUILD.gn index 2677d9ac..21e3387 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-spinner/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -10,7 +10,5 @@ } js_library("paper-spinner-lite-extracted") { - deps = [ - ":paper-spinner-behavior-extracted", - ] + deps = [ ":paper-spinner-behavior-extracted" ] }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tooltip/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-tooltip/BUILD.gn index 50e30af1..b2f9403f 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-tooltip/BUILD.gn +++ b/third_party/polymer/v1_0/components-chromium/paper-tooltip/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/font-roboto/BUILD.gn b/third_party/polymer/v3_0/components-chromium/font-roboto/BUILD.gn index e5345d2..f232c75 100644 --- a/third_party/polymer/v3_0/components-chromium/font-roboto/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/font-roboto/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-a11y-announcer/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-a11y-announcer/BUILD.gn index 91fc0d46f..c9d5e96f 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-a11y-announcer/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-a11y-announcer/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-a11y-announcer") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn index 953a4cfb..1c269bb 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-a11y-keys-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-a11y-keys-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-a11y-keys/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-a11y-keys/BUILD.gn index a95f20a8..a28030e 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-a11y-keys/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-a11y-keys/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-behaviors/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-behaviors/BUILD.gn index 9622f7e..71c988e 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-behaviors/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-behaviors/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -15,7 +15,5 @@ } js_library("iron-control-state") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-collapse/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-collapse/BUILD.gn index 51a622a..7761a4a 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-collapse/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-collapse/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-dropdown/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-dropdown/BUILD.gn index 4d12238..aa6826d 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-dropdown/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-dropdown/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -17,7 +17,5 @@ } js_library("iron-dropdown-scroll-manager") { - deps = [ - "../iron-overlay-behavior:iron-scroll-manager", - ] + deps = [ "../iron-overlay-behavior:iron-scroll-manager" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-fit-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-fit-behavior/BUILD.gn index 49cc0041..29ff79e4 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-fit-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-fit-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-fit-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-flex-layout/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-flex-layout/BUILD.gn index 3a0fc2cf..084fad9f 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-flex-layout/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-flex-layout/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,13 +7,9 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-flex-layout") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("iron-flex-layout-classes") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-icon/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-icon/BUILD.gn index 9974bafe..064b4627 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-icon/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-icon/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-iconset-svg/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-iconset-svg/BUILD.gn index e7ac6ba08..006b423a 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-iconset-svg/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-iconset-svg/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-input/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-input/BUILD.gn index f6a553c..6d1e99e 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-input/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-input/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-list/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-list/BUILD.gn index b5f9129..4240557 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-list/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-list/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-location/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-location/BUILD.gn index 043c444e..e5ebeff 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-location/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-location/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,13 +7,9 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-location") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("iron-query-params") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-media-query/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-media-query/BUILD.gn index d0a473f..3c23d08 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-media-query/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-media-query/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-media-query") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-meta/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-meta/BUILD.gn index dae2816e..a08a6a18 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-meta/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-meta/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-meta") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-overlay-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-overlay-behavior/BUILD.gn index 1d276827..5e0cc87 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-overlay-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-overlay-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,15 +7,11 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-focusables-helper") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("iron-overlay-backdrop") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("iron-overlay-behavior") { @@ -38,7 +34,5 @@ } js_library("iron-scroll-manager") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-pages/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-pages/BUILD.gn index d29f7e9..e801d83 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-pages/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-pages/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-range-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-range-behavior/BUILD.gn index f4822f8..569152cc 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-range-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-range-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-range-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-resizable-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-resizable-behavior/BUILD.gn index 0f96c9d..59cf354 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-resizable-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-resizable-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-resizable-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-scroll-target-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-scroll-target-behavior/BUILD.gn index 26d261a9..664a7ab 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-scroll-target-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-scroll-target-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("iron-scroll-target-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-scroll-threshold/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-scroll-threshold/BUILD.gn index d75b199..19acd92 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-scroll-threshold/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-scroll-threshold/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/iron-selector/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-selector/BUILD.gn index 9736a67b..656367c 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-selector/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-selector/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -21,9 +21,7 @@ } js_library("iron-selection") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("iron-selector") {
diff --git a/third_party/polymer/v3_0/components-chromium/iron-test-helpers/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-test-helpers/BUILD.gn index 7c9dd2c..090b65d 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-test-helpers/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-test-helpers/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("mock-interactions") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/third_party/polymer/v3_0/components-chromium/iron-validatable-behavior/BUILD.gn b/third_party/polymer/v3_0/components-chromium/iron-validatable-behavior/BUILD.gn index fd0d308a..790b7ad 100644 --- a/third_party/polymer/v3_0/components-chromium/iron-validatable-behavior/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/iron-validatable-behavior/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/neon-animation/BUILD.gn b/third_party/polymer/v3_0/components-chromium/neon-animation/BUILD.gn index 7a01eaba..b3f1e15 100644 --- a/third_party/polymer/v3_0/components-chromium/neon-animation/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/neon-animation/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -15,9 +15,7 @@ } js_library("neon-animatable-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("neon-animated-pages") { @@ -30,9 +28,7 @@ } js_library("neon-animation-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("neon-animation-runner-behavior") {
diff --git a/third_party/polymer/v3_0/components-chromium/neon-animation/animations/BUILD.gn b/third_party/polymer/v3_0/components-chromium/neon-animation/animations/BUILD.gn index 0c6a170..73be497 100644 --- a/third_party/polymer/v3_0/components-chromium/neon-animation/animations/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/neon-animation/animations/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/paper-behaviors/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-behaviors/BUILD.gn index 2665a266..baf0ee53 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-behaviors/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-behaviors/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/paper-input/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-input/BUILD.gn index 575500af..33b65ee 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-input/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-input/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,9 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("paper-input-addon-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("paper-input-container") {
diff --git a/third_party/polymer/v3_0/components-chromium/paper-progress/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-progress/BUILD.gn index 1da4c66..c162d3ca 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-progress/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-progress/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/paper-ripple/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-ripple/BUILD.gn index 79ddb10..101fb2a 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-ripple/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-ripple/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/paper-spinner/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-spinner/BUILD.gn index 4d998d0..2a79df47 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-spinner/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-spinner/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,9 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("paper-spinner-behavior") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("paper-spinner-lite") {
diff --git a/third_party/polymer/v3_0/components-chromium/paper-styles/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-styles/BUILD.gn index 2c4b5bf1..7d81b54 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-styles/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-styles/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,9 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("color") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("default-theme") { @@ -30,9 +28,7 @@ } js_library("shadow") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] } js_library("typography") {
diff --git a/third_party/polymer/v3_0/components-chromium/paper-styles/classes/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-styles/classes/BUILD.gn index ced3624..121a3132 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-styles/classes/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-styles/classes/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -14,9 +14,7 @@ } js_library("shadow") { - deps = [ - "../../polymer:polymer_bundled", - ] + deps = [ "../../polymer:polymer_bundled" ] } js_library("typography") {
diff --git a/third_party/polymer/v3_0/components-chromium/paper-styles/element-styles/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-styles/element-styles/BUILD.gn index 00797a2d..b9b59d5 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-styles/element-styles/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-styles/element-styles/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. #
diff --git a/third_party/polymer/v3_0/components-chromium/paper-tooltip/BUILD.gn b/third_party/polymer/v3_0/components-chromium/paper-tooltip/BUILD.gn index 7af0c00..f4b04ee 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-tooltip/BUILD.gn +++ b/third_party/polymer/v3_0/components-chromium/paper-tooltip/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 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. # @@ -7,7 +7,5 @@ import("//third_party/closure_compiler/compile_js.gni") js_library("paper-tooltip") { - deps = [ - "../polymer:polymer_bundled", - ] + deps = [ "../polymer:polymer_bundled" ] }
diff --git a/tools/android/avd/avd.py b/tools/android/avd/avd.py index 3236b0bc..eddb28a 100755 --- a/tools/android/avd/avd.py +++ b/tools/android/avd/avd.py
@@ -81,11 +81,17 @@ start_parser = subparsers.add_parser( 'start', help='Start an AVD instance with the given config.') + start_parser.add_argument( + '--no-read-only', + action='store_false', + dest='read_only', + default=True, + help='Run a modifiable emulator. Will save snapshots on exit.') add_common_arguments(start_parser) def start_cmd(args): inst = avd.AvdConfig(args.avd_config).CreateInstance() - inst.Start(read_only=False, snapshot_save=True) + inst.Start(read_only=args.read_only, snapshot_save=not args.read_only) print('%s started (pid: %d)' % (str(inst), inst._emulator_proc.pid)) return 0
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 84fce257..f2b82d8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -26025,6 +26025,7 @@ <int value="3136" label="CSPROWithReasonableRestrictions"/> <int value="3137" label="CSPWithBetterThanReasonableRestrictions"/> <int value="3138" label="CSPROWithBetterThanReasonableRestrictions"/> + <int value="3139" label="MeasureMemory"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -36947,6 +36948,8 @@ <int value="-1416754663" label="enable-mac-views-native-app-windows"/> <int value="-1416184931" label="TranslateRankerEnforcement:enabled"/> <int value="-1411733990" label="OmniboxDedupeGoogleDriveURLs:disabled"/> + <int value="-1411219910" + label="enable-experimental-accessibility-chromevox-annotations"/> <int value="-1411003295" label="disable-encrypted-media"/> <int value="-1410394131" label="EvDetailsInPageInfo:enabled"/> <int value="-1410001116" @@ -56234,6 +56237,7 @@ <int value="31" label="SENSITIVE_CONTENT_WARNING"/> <int value="32" label="SENSITIVE_CONTENT_BLOCK"/> <int value="33" label="DEEP_SCANNED_SAFE"/> + <int value="34" label="ADVANCED_PROTECTION_PROMPT"/> </enum> <enum name="SBClientDownloadCheckResult"> @@ -56250,6 +56254,7 @@ <int value="10" label="SENSITIVE_CONTENT_WARNING"/> <int value="11" label="SENSITIVE_CONTENT_BLOCK"/> <int value="12" label="DEEP_SCANNED_SAFE"/> + <int value="13" label="PROMPT_FOR_SCANNING"/> </enum> <enum name="SBClientDownloadExtensions">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index eece7c6..a7bf5da1 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -48527,6 +48527,10 @@ <histogram name="Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension" units="ms" expires_after="2020-12-30"> + <obsolete> + Deprecated Jan 2020 to increase resolution to microseconds. Replaced with + Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension2. + </obsolete> <owner>karandeepb@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -48537,6 +48541,19 @@ </histogram> <histogram + name="Extensions.DeclarativeNetRequest.EvaluateBeforeRequestTime.SingleExtension2" + units="microseconds" expires_after="2021-01-31"> + <owner>karandeepb@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + Time taken to evaluate the before-request action for a network request for a + single extension ruleset. Emitted for each network request that is visible + to the extension. This is only emitted for users with high resolution + clocks. + </summary> +</histogram> + +<histogram name="Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions" units="ms" expires_after="M80"> <obsolete> @@ -48555,6 +48572,10 @@ <histogram name="Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2" units="ms" expires_after="2020-12-30"> + <obsolete> + Deprecated Jan 2020 to increase resolution to microseconds. Replaced with + Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3. + </obsolete> <owner>karandeepb@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -48566,6 +48587,20 @@ </summary> </histogram> +<histogram + name="Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions3" + units="microseconds" expires_after="2021-01-31"> + <owner>karandeepb@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + Time taken to evaluate the action to take for the network request as per the + Declarative Net Request API. This includes the time taken to evaluate all + the extension rulesets. Emitted for non-sensitive network requests seen by + the Extension System when there is at least one active extension ruleset. + This is only emitted for users with high resolution clocks. + </summary> +</histogram> + <histogram name="Extensions.DeclarativeNetRequest.IndexAndPersistRulesTime" units="ms" expires_after="2020-12-30"> <owner>karandeepb@chromium.org</owner> @@ -63205,7 +63240,7 @@ </histogram> <histogram name="IOS.CommittedNavigationHasContext" enum="Boolean" - expires_after="2019-05-01"> + expires_after="2020-08-01"> <owner>danyao@chromium.org</owner> <summary> When a navigation is committed, it should have a non-null NavigationContext. @@ -85731,10 +85766,10 @@ </histogram> <histogram name="Net.NetworkErrorLogging.SignedExchangeRequestOutcome" - enum="NetNetworkErrorLoggingRequestOutcome" expires_after="2020-02-28"> + enum="NetNetworkErrorLoggingRequestOutcome" expires_after="2020-10-01"> <owner>horo@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> - <owner>kouhei@chromium.org</owner> + <owner>kinuko@chromium.org</owner> <summary> When Network Error Logging observes a completed request of signed exchange that might generate a report, what happens to it. NEL observes all requests, @@ -102061,7 +102096,7 @@ </histogram> <histogram name="Omnibox.MatchStability.AsyncMatchChange2" units="position" - expires_after="2020-03-01"> + expires_after="2021-03-01"> <owner>tommycli@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -102463,7 +102498,7 @@ </histogram> <histogram name="Omnibox.Start.WantAsyncMatches" enum="Boolean" - expires_after="2020-03-01"> + expires_after="2021-03-01"> <owner>tommycli@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -156342,7 +156377,7 @@ </histogram> <histogram name="TabHoverCards.TabHoverCardsSeenBeforeTabSelection" - units="units" expires_after="2020-02-01"> + units="units" expires_after="2020-05-01"> <owner>corising@chromium.org</owner> <owner>chrome-desktop-ui-sea@google.com</owner> <summary> @@ -156352,7 +156387,7 @@ </histogram> <histogram name="TabHoverCards.TimeSinceLastVisible" units="ms" - expires_after="2020-02-01"> + expires_after="2020-05-01"> <owner>corising@chromium.org</owner> <owner>chrome-desktop-ui-sea@google.com</owner> <summary> @@ -157697,7 +157732,7 @@ </histogram> <histogram name="Tabs.ScrubbedInInterval.KeyPress" units="tabs" - expires_after="2020-02-01"> + expires_after="2020-05-01"> <owner>corising@chromium.org</owner> <owner>chrome-desktop-ui-sea@google.com</owner> <summary> @@ -157709,7 +157744,7 @@ </histogram> <histogram name="Tabs.ScrubbedInInterval.MousePress" units="tabs" - expires_after="2020-02-01"> + expires_after="2020-05-01"> <owner>corising@chromium.org</owner> <owner>chrome-desktop-ui-sea@google.com</owner> <summary> @@ -167940,7 +167975,7 @@ </histogram> <histogram name="WebCore.Document.execCommand" enum="MappedEditingCommands" - expires_after="M81"> + expires_after="2020-12-31"> <owner>yoichio@chromium.org</owner> <summary> Counts the number of times each document.execCommand is executed. This @@ -167949,7 +167984,7 @@ </histogram> <histogram name="WebCore.Editing.Commands" enum="MappedEditingCommands" - expires_after="2020-07-01"> + expires_after="2020-12-31"> <owner>yoichio@chromium.org</owner> <summary> Counts the number of times each Editor::Command::execute is called. This
diff --git a/tools/metrics/structured/structured.xml b/tools/metrics/structured/structured.xml index 05deb90..89f8198 100644 --- a/tools/metrics/structured/structured.xml +++ b/tools/metrics/structured/structured.xml
@@ -2,22 +2,29 @@ <!-- Structured metrics is under development and isn't available for use yet. --> -<event name="TestEvent"> +<event name="TestEventOne"> <owner>tby@chromium.org</owner> <summary> Event for unit testing, do not use. </summary> - <metric name="ValueOne" kind="hashed-string"> + <metric name="TestMetricOne" kind="hashed-string"> <summary> A per-user keyed hashed value. </summary> </metric> - <metric name="ValueThree" kind="int"> + <metric name="TestMetricTwo" kind="int"> <summary> An unhashed value, recorded as-is. </summary> </metric> - <metric name="ValueTwo" kind="hashed-string"> +</event> + +<event name="TestEventTwo"> + <owner>tby@chromium.org</owner> + <summary> + Event for unit testing, do not use. + </summary> + <metric name="TestMetricOne" kind="hashed-string"> <summary> A per-user keyed hashed value. </summary>
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc index 3d2e14a..41d5507 100644 --- a/ui/accessibility/accessibility_switches.cc +++ b/ui/accessibility/accessibility_switches.cc
@@ -41,6 +41,10 @@ const char kEnableExperimentalAccessibilitySwitchAccessText[] = "enable-experimental-accessibility-switch-access-text"; +// Enables annotations feature that hasn't launched yet. +const char kEnableExperimentalAccessibilityChromeVoxAnnotations[] = + "enable-experimental-accessibility-chromevox-annotations"; + // Enables language switching feature that hasn't launched yet. const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[] = "enable-experimental-accessibility-chromevox-language-switching";
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h index ffb6ac9..d0391a64 100644 --- a/ui/accessibility/accessibility_switches.h +++ b/ui/accessibility/accessibility_switches.h
@@ -20,6 +20,8 @@ AX_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccess[]; AX_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccessText[]; AX_EXPORT extern const char + kEnableExperimentalAccessibilityChromeVoxAnnotations[]; +AX_EXPORT extern const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[]; AX_EXPORT extern const char kEnableExperimentalAccessibilityChromeVoxSearchMenus[];
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index 88e321d07..ed02804 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -609,6 +609,12 @@ if (string_pending_insertion_.empty()) { if (!text_input_client_->HasCompositionText()) { if (has_composition_range_) { + // Remove replacing text first before starting composition. + if (new_text_inserted_ && !replace_text_range_.is_empty() && + !replace_text_size_) { + text_input_client_->SetEditableSelectionRange(replace_text_range_); + text_input_client_->ExtendSelectionAndDelete(0, 0); + } string_pending_insertion_ = string_buffer_document_.substr( composition_range_.GetMin(), composition_range_.length()); StartCompositionOnExistingText(); @@ -791,7 +797,7 @@ return ret; TS_TEXTCHANGE change; - if (text_buffer_size > 0) { + if (text_buffer_size >= 0) { new_text_inserted_ = true; replace_text_range_.set_start(acp_start); replace_text_range_.set_end(acp_end);
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc index 7cb99f74..aefd640 100644 --- a/ui/base/ime/win/tsf_text_store_unittest.cc +++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -3295,5 +3295,105 @@ EXPECT_EQ(S_OK, result); } +// regression tests for crbug.com/1013154. +// We should remove selected text before start composition on existing text. +class RegressionTest7Callback : public TSFTextStoreTestCallback { + public: + explicit RegressionTest7Callback(TSFTextStore* text_store) + : TSFTextStoreTestCallback(text_store) {} + + HRESULT LockGranted1(DWORD flags) { + SetTextTest(0, 0, L"aaaa", S_OK); + SetSelectionTest(0, 4, S_OK); + return S_OK; + } + + HRESULT LockGranted2(DWORD flags) { + GetTextTest(0, -1, L"aaaa", 4); + SetTextTest(1, 4, L"", S_OK); + SetSelectionTest(1, 1, S_OK); + + text_spans()->clear(); + ImeTextSpan text_span_1; + text_span_1.start_offset = 0; + text_span_1.end_offset = 1; + text_span_1.underline_color = SK_ColorBLACK; + text_span_1.thickness = ImeTextSpan::Thickness::kThin; + text_span_1.background_color = SK_ColorTRANSPARENT; + text_spans()->push_back(text_span_1); + + *edit_flag() = true; + *composition_start() = 0; + composition_range()->set_start(0); + composition_range()->set_end(1); + *has_composition_range() = true; + + text_store_->OnKeyTraceDown(65u, 1966081u); + return S_OK; + } + + bool SetCompositionFromExistingText2( + const gfx::Range& range, + const std::vector<ui::ImeTextSpan>& text_spans) { + EXPECT_EQ(0u, range.start()); + EXPECT_EQ(1u, range.end()); + EXPECT_EQ(1u, text_spans.size()); + SetHasCompositionText(true); + return true; + } + + HRESULT LockGranted3(DWORD flags) { + GetTextTest(0, -1, L"a", 1); + + text_spans()->clear(); + *edit_flag() = true; + *composition_start() = 1; + composition_range()->set_start(0); + composition_range()->set_end(0); + + *has_composition_range() = false; + text_store_->OnKeyTraceUp(65u, 1966081u); + return S_OK; + } + + void InsertText3(const base::string16& text) { + EXPECT_EQ(L"a", text); + SetHasCompositionText(false); + } + + private: + DISALLOW_COPY_AND_ASSIGN(RegressionTest7Callback); +}; + +TEST_F(TSFTextStoreTest, RegressionTest7) { + RegressionTest7Callback callback(text_store_.get()); + EXPECT_CALL(text_input_client_, SetCompositionFromExistingText(_, _)) + .WillOnce( + Invoke(&callback, + &RegressionTest7Callback::SetCompositionFromExistingText2)); + + EXPECT_CALL(text_input_client_, InsertText(_)) + .WillOnce(Invoke(&callback, &RegressionTest7Callback::InsertText3)); + + EXPECT_CALL(*sink_, OnLockGranted(_)) + .WillOnce(Invoke(&callback, &RegressionTest7Callback::LockGranted1)) + .WillOnce(Invoke(&callback, &RegressionTest7Callback::LockGranted2)) + .WillOnce(Invoke(&callback, &RegressionTest7Callback::LockGranted3)); + + ON_CALL(text_input_client_, HasCompositionText()) + .WillByDefault( + Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText)); + + HRESULT result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); + result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); + result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); +} + } // namespace } // namespace ui
diff --git a/ui/base/x/x11_shm_image_pool_base.cc b/ui/base/x/x11_shm_image_pool_base.cc index 9baf516..39ec3b9 100644 --- a/ui/base/x/x11_shm_image_pool_base.cc +++ b/ui/base/x/x11_shm_image_pool_base.cc
@@ -194,16 +194,16 @@ if (state.shminfo_.shmid < 0) return false; state.shminfo_.shmaddr = - reinterpret_cast<char*>(shmat(state.shminfo_.shmid, 0, 0)); + reinterpret_cast<char*>(shmat(state.shminfo_.shmid, nullptr, 0)); if (state.shminfo_.shmaddr == reinterpret_cast<char*>(-1)) { - shmctl(state.shminfo_.shmid, IPC_RMID, 0); + shmctl(state.shminfo_.shmid, IPC_RMID, nullptr); return false; } #if defined(OS_LINUX) // On Linux, a shmid can still be attached after IPC_RMID if otherwise // kept alive. Detach before XShmAttach to prevent a memory leak in case // the process dies. - shmctl(state.shminfo_.shmid, IPC_RMID, 0); + shmctl(state.shminfo_.shmid, IPC_RMID, nullptr); #endif DCHECK(!state.shmem_attached_to_server_); if (!XShmAttach(display_, &state.shminfo_)) @@ -214,7 +214,7 @@ // forced to do IPC_RMID after the server has attached to the segment. // XShmAttach is asynchronous, so we must also sync. XSync(display_, x11::False); - shmctl(shminfo_.shmid, IPC_RMID, 0); + shmctl(shminfo_.shmid, IPC_RMID, nullptr); #endif // If this class ever needs to use XShmGetImage(), this needs to be // changed to read-write. @@ -222,8 +222,7 @@ } } - for (std::size_t i = 0; i < frame_states_.size(); ++i) { - FrameState& state = frame_states_[i]; + for (FrameState& state : frame_states_) { state.image->data = state.shminfo_.shmaddr; SkImageInfo image_info = SkImageInfo::Make(state.image->width, state.image->height,
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 656410d..4f7a14c 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -181,7 +181,7 @@ "cr_toolbar:cr_toolbar_search_field_module", "cr_toolbar:cr_toolbar_selection_overlay_module", "cr_view_manager:cr_view_manager_module", - "policy:cr_tooltip_icon_module", + "policy:polymer3_elements", ] if (is_chromeos) {
diff --git a/ui/webui/resources/cr_elements/cr_slider/BUILD.gn b/ui/webui/resources/cr_elements/cr_slider/BUILD.gn index 379930f3..1229cf7 100644 --- a/ui/webui/resources/cr_elements/cr_slider/BUILD.gn +++ b/ui/webui/resources/cr_elements/cr_slider/BUILD.gn
@@ -22,6 +22,7 @@ html_file = "cr_slider.html" html_type = "dom-module" auto_imports = [ "ui/webui/resources/html/event_tracker.html|EventTracker" ] + namespace_rewrites = [ "cr_slider.SliderTick|SliderTick" ] } js_type_check("closure_compile_module") { @@ -36,7 +37,6 @@ deps = [ "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:event_tracker.m", ] extra_deps = [ ":cr_slider_module" ]
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js index 5e1f94d8..4d77f318 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -19,7 +19,7 @@ * ariaValue: (number|undefined), * }} */ - let SliderTick; + /* #export */ let SliderTick; /** * @param {number} min @@ -32,9 +32,7 @@ } /** - * Object is actually a SliderTick, but the closure compiler won't - * recognise it with the way this code is structured. - * @param {!(Object|number)} tick + * @param {!(cr_slider.SliderTick|number)} tick * @return {number} */ function getAriaValue(tick) { @@ -124,9 +122,7 @@ /** * The data associated with each tick on the slider. Each element in the * array contains a value and the label corresponding to that value. - * Object is actually a SliderTick, but the closure compiler won't - * recognise it with the way this code is structured. - * @type {!Array<Object>|!Array<number>} + * @type {!Array<cr_slider.SliderTick>|!Array<number>} */ ticks: { type: Array,
diff --git a/ui/webui/resources/cr_elements/policy/BUILD.gn b/ui/webui/resources/cr_elements/policy/BUILD.gn index c1c2741..d74cac4 100644 --- a/ui/webui/resources/cr_elements/policy/BUILD.gn +++ b/ui/webui/resources/cr_elements/policy/BUILD.gn
@@ -4,6 +4,7 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/polymer.gni") +import("../../tools/js_modulizer.gni") js_type_check("closure_compile") { deps = [ @@ -65,15 +66,30 @@ js_library("cr_tooltip_icon") { } -polymer_modulizer("cr_tooltip_icon") { - js_file = "cr_tooltip_icon.js" - html_file = "cr_tooltip_icon.html" - html_type = "dom-module" -} +# Polymer 3 autogenerated version js_type_check("closure_compile_module") { is_polymer3 = true - deps = [ ":cr_tooltip_icon.m" ] + deps = [ + ":cr_policy_indicator.m", + ":cr_policy_indicator_behavior.m", + ":cr_tooltip_icon.m", + ] +} + +js_library("cr_policy_indicator.m") { + sources = [ "$root_gen_dir/ui/webui/resources/cr_elements/policy/cr_policy_indicator.m.js" ] + deps = [ + ":cr_policy_indicator_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] + extra_deps = [ ":cr_policy_indicator_module" ] +} + +js_library("cr_policy_indicator_behavior.m") { + sources = [ "$root_gen_dir/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.m.js" ] + deps = [ "//ui/webui/resources/js:assert.m" ] + extra_deps = [ ":modulize" ] } js_library("cr_tooltip_icon.m") { @@ -85,3 +101,28 @@ ] extra_deps = [ ":cr_tooltip_icon_module" ] } + +group("polymer3_elements") { + deps = [ + ":cr_policy_indicator_module", + ":cr_tooltip_icon_module", + ":modulize", + ] +} + +polymer_modulizer("cr_policy_indicator") { + js_file = "cr_policy_indicator.js" + html_file = "cr_policy_indicator.html" + html_type = "dom-module" + auto_imports = [ "ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.html|CrPolicyIndicatorBehavior,CrPolicyIndicatorType" ] +} + +polymer_modulizer("cr_tooltip_icon") { + js_file = "cr_tooltip_icon.js" + html_file = "cr_tooltip_icon.html" + html_type = "dom-module" +} + +js_modulizer("modulize") { + input_files = [ "cr_policy_indicator_behavior.js" ] +}
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js index 6f99752f..1655bad 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js +++ b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
@@ -8,6 +8,8 @@ * rework the "policy" naming scheme throughout this directory. */ +// #import {assertNotReached} from 'chrome://resources/js/assert.m.js'; + /** * Strings required for policy indicators. These must be set at runtime. * Chrome OS only strings may be undefined. @@ -28,7 +30,7 @@ var CrPolicyStrings; /** @enum {string} */ -const CrPolicyIndicatorType = { +/* #export */ const CrPolicyIndicatorType = { DEVICE_POLICY: 'devicePolicy', EXTENSION: 'extension', NONE: 'none', @@ -41,7 +43,7 @@ }; /** @polymerBehavior */ -const CrPolicyIndicatorBehavior = { +/* #export */ const CrPolicyIndicatorBehavior = { // Properties exposed to all policy indicators. properties: { /** @@ -121,9 +123,11 @@ * @return {string} The tooltip text for |type|. */ getIndicatorTooltip(type, name, opt_matches) { - if (!CrPolicyStrings) { + if (!window['CrPolicyStrings']) { return ''; } // Tooltips may not be defined, e.g. in OOBE. + + CrPolicyStrings = window['CrPolicyStrings']; switch (type) { case CrPolicyIndicatorType.EXTENSION: return name.length > 0 ?
diff --git a/ui/webui/resources/cr_elements_resources_v3.grdp b/ui/webui/resources/cr_elements_resources_v3.grdp index 88348e8..0e78e0b 100644 --- a/ui/webui/resources/cr_elements_resources_v3.grdp +++ b/ui/webui/resources/cr_elements_resources_v3.grdp
@@ -116,6 +116,11 @@ use_base_dir="false" type="BINDATA" compress="gzip" /> + <include name="IDR_CR_ELEMENTS_CR_SLIDER_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_slider/cr_slider.m.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> <include name="IDR_CR_ELEMENTS_CR_SPLITTER_JS" file="cr_elements/cr_splitter/cr_splitter.js" type="BINDATA" @@ -155,11 +160,21 @@ use_base_dir="false" type="BINDATA" compress="gzip" /> - <include name="IDR_CR_ELEMENTS_CR_TOOLTIP_ICON_M_JS" + <include name="IDR_CR_ELEMENTS_POLICY_CR_TOOLTIP_ICON_M_JS" file="${root_gen_dir}/ui/webui/resources/cr_elements/policy/cr_tooltip_icon.m.js" use_base_dir="false" type="BINDATA" compress="gzip" /> + <include name="IDR_CR_ELEMENTS_POLICY_CR_POLICY_INDICATOR_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_elements/policy/cr_policy_indicator.m.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> + <include name="IDR_CR_ELEMENTS_POLICY_CR_POLICY_INDICATOR_BEHAVIOR_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.m.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> <include name="IDR_CR_ELEMENTS_CR_VIEW_MANAGER_M_JS" file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager.m.js" use_base_dir="false" @@ -185,11 +200,6 @@ use_base_dir="false" type="BINDATA" compress="gzip" /> - <include name="IDR_CR_ELEMENTS_CR_SLIDER_M_JS" - file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_slider/cr_slider.m.js" - use_base_dir="false" - type="BINDATA" - compress="gzip" /> <if expr="chromeos"> <include name="IDR_CR_ELEMENTS_CR_SEARCHABLE_DROP_DOWN_M_JS" file="${root_gen_dir}/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.js"