diff --git a/.gitignore b/.gitignore index 41c6f68..4c7a9e9 100644 --- a/.gitignore +++ b/.gitignore
@@ -149,6 +149,7 @@ /chrome/test/data/vr/webvr_info/ /chrome/test/data/webrtc/resources /chrome/test/media_router/internal +/chrome/test/python_tests/ /chrome/tools/memory /chrome/tools/test/reference_build /chrome/unit_tests_run.xml
diff --git a/BUILD.gn b/BUILD.gn index 06c117e..24e7935c 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1019,6 +1019,7 @@ "//third_party/catapult/devil/", "//third_party/catapult/dependency_manager/", "//third_party/catapult/third_party/zipfile/", + "//third_party/catapult/third_party/typ/", "//third_party/depot_tools/pylint.py", "//third_party/depot_tools/pylintrc", "//third_party/depot_tools/third_party/logilab/", @@ -1026,7 +1027,6 @@ "//third_party/depot_tools/third_party/pylint.py", "//third_party/ply/", "//third_party/pymock/", - "//third_party/typ/", "//tools/idl_parser/", ] }
diff --git a/DEPS b/DEPS index d6a7a44..fd56984e 100644 --- a/DEPS +++ b/DEPS
@@ -89,11 +89,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '0d24c502113bf8538772ec9cde6fb5cab85fa278', + 'skia_revision': 'af4be058fe8ba437aaa5c2e93291047b2856bba1', # 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': '6b76faea0a217398f7f05a6fa7c93599793b7c34', + 'v8_revision': '8ba3ef5fcd21c5e717a1b7bd0713612a287b9500', # 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. @@ -101,7 +101,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '5f21df8318e9dae7e4eca2809a176f2989410da8', + 'angle_revision': '505ea1bb56ccce114c4ac4d1b7b856cb8dcdc47e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -488,7 +488,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ef1ada9adf6a5e1b8b0d4a4b51188dff91f39582', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '18483452ccd21ddc666e9cdbe41a037285e9e7f0', 'condition': 'checkout_linux', }, @@ -953,7 +953,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c0541da63f571512c49758cbc0767117997a270', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'bd7392829a81d0720887dae9ac0bf83da8d9e80d', # commit position 21742 + Var('webrtc_git') + '/src.git' + '@' + 'd085936e6a4e112e4c396b6430859f3cdcb56092', # commit position 21742 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/ash/accelerators/ash_focus_manager_factory.cc b/ash/accelerators/ash_focus_manager_factory.cc index b544dac..0f125c61 100644 --- a/ash/accelerators/ash_focus_manager_factory.cc +++ b/ash/accelerators/ash_focus_manager_factory.cc
@@ -7,8 +7,12 @@ #include <memory> #include "ash/accelerators/accelerator_controller.h" +#include "ash/magnifier/docked_magnifier_controller.h" +#include "ash/magnifier/magnification_controller.h" #include "ash/shell.h" +#include "ui/base/ime/text_input_client.h" #include "ui/views/focus/focus_manager.h" +#include "ui/views/view.h" namespace ash { @@ -31,4 +35,55 @@ return controller && controller->Process(accelerator); } +void AshFocusManagerFactory::Delegate::OnDidChangeFocus( + views::View* focused_before, + views::View* focused_now) { + if (!focused_now || focused_now == focused_before) + return; + + const gfx::Rect bounds_in_screen = focused_now->GetBoundsInScreen(); + if (bounds_in_screen.IsEmpty()) + return; + + // Note that both magnifiers are mutually exclusive. + DockedMagnifierController* docked_magnifier = + Shell::Get()->docked_magnifier_controller(); + MagnificationController* fullscreen_magnifier = + Shell::Get()->magnification_controller(); + + gfx::Point point_of_interest = bounds_in_screen.CenterPoint(); + const ui::InputMethod* input_method = focused_now->GetInputMethod(); + if (input_method && input_method->GetTextInputClient() && + input_method->GetTextInputClient()->GetTextInputType() != + ui::TEXT_INPUT_TYPE_NONE) { + // If this view is a text input client with valid caret bounds, forward it + // to the enabled magnifier as an |OnCaretBoundsChanged()| event, since the + // magnifiers might have special handling for caret events. + const gfx::Rect caret_bounds = + input_method->GetTextInputClient()->GetCaretBounds(); + // Note: Don't use Rect::IsEmpty() for the below check as in many cases the + // caret can have a zero width or height, but still be valid. + if (caret_bounds.width() || caret_bounds.height()) { + if (docked_magnifier->GetEnabled()) { + docked_magnifier->OnCaretBoundsChanged( + input_method->GetTextInputClient()); + } else if (fullscreen_magnifier->IsEnabled()) { + fullscreen_magnifier->OnCaretBoundsChanged( + input_method->GetTextInputClient()); + } + + return; + } + + // If the caret bounds are unavailable, then use the view's top left corner + // as the point of interest. + point_of_interest = bounds_in_screen.origin(); + } + + if (docked_magnifier->GetEnabled()) + docked_magnifier->CenterOnPoint(point_of_interest); + else if (fullscreen_magnifier->IsEnabled()) + fullscreen_magnifier->CenterOnPoint(point_of_interest); +} + } // namespace ash
diff --git a/ash/accelerators/ash_focus_manager_factory.h b/ash/accelerators/ash_focus_manager_factory.h index 5f05301..4788f89 100644 --- a/ash/accelerators/ash_focus_manager_factory.h +++ b/ash/accelerators/ash_focus_manager_factory.h
@@ -32,6 +32,8 @@ // views::FocusManagerDelegate overrides: bool ProcessAccelerator(const ui::Accelerator& accelerator) override; + void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) override; }; DISALLOW_COPY_AND_ASSIGN(AshFocusManagerFactory);
diff --git a/ash/display/display_configuration_observer.cc b/ash/display/display_configuration_observer.cc index c9e5c870..dd32a41 100644 --- a/ash/display/display_configuration_observer.cc +++ b/ash/display/display_configuration_observer.cc
@@ -65,7 +65,7 @@ display::DisplayManager* display_manager = Shell::Get()->display_manager(); was_in_mirror_mode_ = display_manager->IsInMirrorMode(); display_manager->SetMirrorMode(display::MirrorMode::kNormal, base::nullopt); - display_manager->layout_store()->set_forced_mirror_mode(true); + display_manager->layout_store()->set_forced_mirror_mode_for_tablet(true); } void DisplayConfigurationObserver::EndMirrorMode() { @@ -74,7 +74,7 @@ base::nullopt); } display::DisplayManager* display_manager = Shell::Get()->display_manager(); - display_manager->layout_store()->set_forced_mirror_mode(false); + display_manager->layout_store()->set_forced_mirror_mode_for_tablet(false); save_preference_ = true; }
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 8d551463..b15c9af 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc
@@ -3700,7 +3700,7 @@ EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED, observer.GetStateForDisplayIds(outputs)); - display_manager()->layout_store()->set_forced_mirror_mode(true); + display_manager()->layout_store()->set_forced_mirror_mode_for_tablet(true); observer.OnDisplayModeChanged(outputs); @@ -3711,7 +3711,7 @@ EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, observer.GetStateForDisplayIds(outputs)); - display_manager()->layout_store()->set_forced_mirror_mode(false); + display_manager()->layout_store()->set_forced_mirror_mode_for_tablet(false); EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED, observer.GetStateForDisplayIds(outputs)); @@ -4565,4 +4565,131 @@ EXPECT_TRUE(display_manager()->IsInMirrorMode()); } +TEST_F(DisplayManagerTest, SoftwareMirrorRotationForTablet) { + UpdateDisplay("400x300,800x800"); + RunAllPendingInMessageLoop(); + + // Set the first display as internal display so that the tablet mode can be + // enabled. + display::test::DisplayManagerTestApi(display_manager()) + .SetFirstDisplayAsInternalDisplay(); + + // Simulate turning on mirror mode triggered by tablet mode on. + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); + RunAllPendingInMessageLoop(); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 300), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + MirrorWindowTestApi test_api; + std::vector<aura::WindowTreeHost*> host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect1( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect1); + host_list[0]->window()->transform().TransformRect(&transformed_rect1); + EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect1); + + // Rotate the source display by 90 degrees. + UpdateDisplay("400x300/r,800x800"); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 300, 400), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect2( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect2); + host_list[0]->window()->transform().TransformRect(&transformed_rect2); + EXPECT_EQ(gfx::RectF(100.0f, 0.0f, 600.0f, 800.0f), transformed_rect2); + + // Change the bounds of the source display and rotate the source display by 90 + // degrees. + UpdateDisplay("300x400/r,800x800"); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 300), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect3( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect3); + host_list[0]->window()->transform().TransformRect(&transformed_rect3); + EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect3); +} + +TEST_F(DisplayManagerTest, SoftwareMirrorRotationForNonTablet) { + MirrorWindowTestApi test_api; + UpdateDisplay("400x300,800x800"); + + // Simulate turning on mirror mode not triggered by tablet mode. + SetSoftwareMirrorMode(true); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 300), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + std::vector<aura::WindowTreeHost*> host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect1( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect1); + host_list[0]->window()->transform().TransformRect(&transformed_rect1); + EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect1); + + // Rotate the source display by 90 degrees. + UpdateDisplay("400x300/r,800x800"); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 300, 400), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect2( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect2); + host_list[0]->window()->transform().TransformRect(&transformed_rect2); + EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect2); + + // Change the bounds of the source display and rotate the source display by 90 + // degrees. + UpdateDisplay("300x400/r,800x800"); + EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 300), + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + host_list = test_api.GetHosts(); + ASSERT_EQ(1U, host_list.size()); + EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size()); + EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size()); + + // Test the target display's bounds after the transforms are applied. + gfx::RectF transformed_rect3( + display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); + Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect( + &transformed_rect3); + host_list[0]->window()->transform().TransformRect(&transformed_rect3); + EXPECT_EQ(gfx::RectF(100.0f, 0.0f, 600.0f, 800.0f), transformed_rect3); +} + } // namespace ash
diff --git a/ash/display/root_window_transformers.cc b/ash/display/root_window_transformers.cc index 506241d..dc81096 100644 --- a/ash/display/root_window_transformers.cc +++ b/ash/display/root_window_transformers.cc
@@ -14,6 +14,7 @@ #include "base/command_line.h" #include "ui/compositor/dip_util.h" #include "ui/display/display.h" +#include "ui/display/manager/display_layout_store.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" #include "ui/gfx/geometry/insets.h" @@ -36,7 +37,7 @@ display::ManagedDisplayInfo info = Shell::Get()->display_manager()->GetDisplayInfo(display.id()); return CreateRotationTransform(display::Display::ROTATE_0, - info.GetActiveRotation(), display); + info.GetActiveRotation(), display.bounds()); } gfx::Transform CreateMagnifierTransform(aura::Window* root_window) { @@ -163,6 +164,26 @@ const display::ManagedDisplayInfo& source_display_info, const display::ManagedDisplayInfo& mirror_display_info) { root_bounds_ = gfx::Rect(source_display_info.bounds_in_native().size()); + + // The rotation of the source display (internal display) should be undone in + // the destination display (external display) if mirror mode is enabled in + // tablet mode. + bool should_undo_rotation = Shell::Get() + ->display_manager() + ->layout_store() + ->forced_mirror_mode_for_tablet(); + gfx::Transform rotation_transform; + if (should_undo_rotation) { + // Calculate the transform to undo the rotation and apply it to the + // source display. + rotation_transform = + CreateRotationTransform(source_display_info.GetActiveRotation(), + display::Display::ROTATE_0, root_bounds_); + gfx::RectF rotated_bounds(root_bounds_); + rotation_transform.TransformRect(&rotated_bounds); + root_bounds_ = gfx::ToNearestRect(rotated_bounds); + } + gfx::Rect mirror_display_rect = gfx::Rect(mirror_display_info.bounds_in_native().size()); @@ -193,6 +214,9 @@ transform_.Translate(margin, 0); transform_.Scale(inverted_scale, inverted_scale); } + + // Make sure the rotation transform is applied in the beginning. + transform_.PreconcatTransform(rotation_transform); } // aura::RootWindowTransformer overrides:
diff --git a/ash/magnifier/docked_magnifier_controller.cc b/ash/magnifier/docked_magnifier_controller.cc index cef485e..71c16593 100644 --- a/ash/magnifier/docked_magnifier_controller.cc +++ b/ash/magnifier/docked_magnifier_controller.cc
@@ -188,12 +188,6 @@ delta_index, GetScale(), kMinMagnifierScale, kMaxMagnifierScale)); } -void DockedMagnifierController::SetClient( - mojom::DockedMagnifierClientPtr client) { - client_ = std::move(client); - NotifyClientWithStatusChanged(); -} - void DockedMagnifierController::CenterOnPoint( const gfx::Point& point_in_screen) { if (!GetEnabled()) @@ -391,10 +385,6 @@ } } -void DockedMagnifierController::FlushClientPtrForTesting() { - client_.FlushForTesting(); -} - const views::Widget* DockedMagnifierController::GetViewportWidgetForTesting() const { return viewport_widget_; @@ -507,7 +497,6 @@ base::Unretained(this))); OnEnabledPrefChanged(); - NotifyClientWithStatusChanged(); } void DockedMagnifierController::OnEnabledPrefChanged() { @@ -550,8 +539,6 @@ // We use software composited mouse cursor so that it can be mirrored into the // magnifier viewport. shell->UpdateCursorCompositingEnabled(); - - NotifyClientWithStatusChanged(); } void DockedMagnifierController::OnScalePrefChanged() { @@ -581,11 +568,6 @@ CenterOnPoint(GetCursorScreenPoint()); } -void DockedMagnifierController::NotifyClientWithStatusChanged() { - if (client_) - client_->OnEnabledStatusChanged(GetEnabled()); -} - void DockedMagnifierController::CreateMagnifierViewport() { DCHECK(GetEnabled()); DCHECK(current_source_root_window_);
diff --git a/ash/magnifier/docked_magnifier_controller.h b/ash/magnifier/docked_magnifier_controller.h index 095a185..e568b82 100644 --- a/ash/magnifier/docked_magnifier_controller.h +++ b/ash/magnifier/docked_magnifier_controller.h
@@ -79,7 +79,6 @@ void StepToNextScaleValue(int delta_index); // ash::mojom::DockedMagnifierController: - void SetClient(mojom::DockedMagnifierClientPtr client) override; void CenterOnPoint(const gfx::Point& point_in_screen) override; // ash::SessionObserver: @@ -116,8 +115,6 @@ bool GetFullscreenMagnifierEnabled() const; void SetFullscreenMagnifierEnabled(bool enabled); - void FlushClientPtrForTesting(); - const views::Widget* GetViewportWidgetForTesting() const; const ui::Layer* GetViewportMagnifierLayerForTesting() const; @@ -202,8 +199,6 @@ mojo::Binding<mojom::DockedMagnifierController> binding_; - mojom::DockedMagnifierClientPtr client_; - DISALLOW_COPY_AND_ASSIGN(DockedMagnifierController); };
diff --git a/ash/magnifier/docked_magnifier_controller_unittest.cc b/ash/magnifier/docked_magnifier_controller_unittest.cc index 9d9b10f..8c3b6f9 100644 --- a/ash/magnifier/docked_magnifier_controller_unittest.cc +++ b/ash/magnifier/docked_magnifier_controller_unittest.cc
@@ -27,7 +27,6 @@ #include "base/test/scoped_feature_list.h" #include "components/prefs/pref_service.h" #include "components/session_manager/session_manager_types.h" -#include "mojo/public/cpp/bindings/binding.h" #include "ui/aura/window.h" #include "ui/compositor/layer.h" #include "ui/display/display.h" @@ -42,34 +41,6 @@ constexpr char kUser1Email[] = "user1@dockedmagnifier"; constexpr char kUser2Email[] = "user2@dockedmagnifier"; -// Mock mojo client of the Docked Magnifier. -class DockedMagnifierTestClient : public mojom::DockedMagnifierClient { - public: - DockedMagnifierTestClient() : binding_(this) {} - ~DockedMagnifierTestClient() override = default; - - bool docked_magnifier_enabled() const { return docked_magnifier_enabled_; } - - // Connects to the DockedMagnifierController. - void Start() { - ash::mojom::DockedMagnifierClientPtr client; - binding_.Bind(mojo::MakeRequest(&client)); - Shell::Get()->docked_magnifier_controller()->SetClient(std::move(client)); - } - - // ash::mojom::DockedMagnifierClient: - void OnEnabledStatusChanged(bool enabled) override { - docked_magnifier_enabled_ = enabled; - } - - private: - mojo::Binding<ash::mojom::DockedMagnifierClient> binding_; - - bool docked_magnifier_enabled_ = false; - - DISALLOW_COPY_AND_ASSIGN(DockedMagnifierTestClient); -}; - class DockedMagnifierTest : public NoSessionAshTestBase { public: DockedMagnifierTest() = default; @@ -79,8 +50,6 @@ return Shell::Get()->docked_magnifier_controller(); } - DockedMagnifierTestClient* test_client() { return &test_client_; } - PrefService* user1_pref_service() { return Shell::Get()->session_controller()->GetUserPrefServiceForUser( AccountId::FromUserEmail(kUser1Email)); @@ -109,8 +78,6 @@ // Create user 2 session. GetSessionControllerClient()->AddUserSession(kUser2Email); - test_client_.Start(); - // Place the cursor in the first display. GetEventGenerator().MoveMouseTo(gfx::Point(0, 0)); } @@ -120,12 +87,7 @@ AccountId::FromUserEmail(email)); } - protected: - MagnifierTextInputTestHelper text_input_helper_; - private: - DockedMagnifierTestClient test_client_; - base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(DockedMagnifierTest); @@ -157,37 +119,17 @@ EXPECT_FALSE(controller()->GetFullscreenMagnifierEnabled()); } -// Tests the changes in the magnifier's status, user switches and the -// interaction with the client. +// Tests the changes in the magnifier's status, user switches. TEST_F(DockedMagnifierTest, TestEnableAndDisable) { - // Client should receive status updates. - EXPECT_FALSE(controller()->GetEnabled()); - EXPECT_FALSE(test_client()->docked_magnifier_enabled()); + // Enable for user 1, and switch to user 2. User 2 should have it disabled. controller()->SetEnabled(true); - controller()->FlushClientPtrForTesting(); EXPECT_TRUE(controller()->GetEnabled()); - EXPECT_TRUE(test_client()->docked_magnifier_enabled()); - controller()->SetEnabled(false); - controller()->FlushClientPtrForTesting(); - EXPECT_FALSE(controller()->GetEnabled()); - EXPECT_FALSE(test_client()->docked_magnifier_enabled()); - - // Enable again for user 1, and switch to user 2. User 2 should have it - // disabled, the client should be updated accordingly. - controller()->SetEnabled(true); - controller()->FlushClientPtrForTesting(); - EXPECT_TRUE(controller()->GetEnabled()); - EXPECT_TRUE(test_client()->docked_magnifier_enabled()); SwitchActiveUser(kUser2Email); - controller()->FlushClientPtrForTesting(); EXPECT_FALSE(controller()->GetEnabled()); - EXPECT_FALSE(test_client()->docked_magnifier_enabled()); // Switch back to user 1, expect it to be enabled. SwitchActiveUser(kUser1Email); - controller()->FlushClientPtrForTesting(); EXPECT_TRUE(controller()->GetEnabled()); - EXPECT_TRUE(test_client()->docked_magnifier_enabled()); } // Tests the magnifier's scale changes. @@ -214,17 +156,12 @@ // DockedMagnifierController (such as Settings UI) are observed and applied. TEST_F(DockedMagnifierTest, TestOutsidePrefsUpdates) { EXPECT_FALSE(controller()->GetEnabled()); - EXPECT_FALSE(test_client()->docked_magnifier_enabled()); user1_pref_service()->SetBoolean(prefs::kDockedMagnifierEnabled, true); - controller()->FlushClientPtrForTesting(); EXPECT_TRUE(controller()->GetEnabled()); - EXPECT_TRUE(test_client()->docked_magnifier_enabled()); user1_pref_service()->SetDouble(prefs::kDockedMagnifierScale, 7.3f); EXPECT_FLOAT_EQ(7.3f, controller()->GetScale()); user1_pref_service()->SetBoolean(prefs::kDockedMagnifierEnabled, false); - controller()->FlushClientPtrForTesting(); EXPECT_FALSE(controller()->GetEnabled()); - EXPECT_FALSE(test_client()->docked_magnifier_enabled()); } // Tests that the workareas of displays are adjusted properly when the Docked @@ -500,7 +437,8 @@ const auto root_windows = Shell::GetAllRootWindows(); ASSERT_EQ(1u, root_windows.size()); - text_input_helper_.CreateAndShowTextInputView(gfx::Rect(500, 400, 80, 80)); + MagnifierTextInputTestHelper text_input_helper; + text_input_helper.CreateAndShowTextInputView(gfx::Rect(500, 400, 80, 80)); // Enable the docked magnifier. controller()->SetEnabled(true); @@ -510,14 +448,14 @@ EXPECT_FLOAT_EQ(scale1, controller()->GetScale()); // Focus on the text input field. - text_input_helper_.FocusOnTextInputView(); + text_input_helper.FocusOnTextInputView(); // The text input caret center point will be our point of interest. When it // goes through the magnifier layer transform, it should end up being in the // center of the viewport. const ui::Layer* magnifier_layer = controller()->GetViewportMagnifierLayerForTesting(); - gfx::Point caret_center(text_input_helper_.GetCaretBounds().CenterPoint()); + gfx::Point caret_center(text_input_helper.GetCaretBounds().CenterPoint()); magnifier_layer->transform().TransformPoint(&caret_center); const views::Widget* viewport_widget = controller()->GetViewportWidgetForTesting(); @@ -529,12 +467,48 @@ // transformed caret center should always go to the viewport center. GetEventGenerator().PressKey(ui::VKEY_A, 0); GetEventGenerator().ReleaseKey(ui::VKEY_A, 0); - gfx::Point new_caret_center( - text_input_helper_.GetCaretBounds().CenterPoint()); + gfx::Point new_caret_center(text_input_helper.GetCaretBounds().CenterPoint()); magnifier_layer->transform().TransformPoint(&new_caret_center); EXPECT_EQ(new_caret_center, viewport_center); } +TEST_F(DockedMagnifierTest, FocusChangeEvents) { + UpdateDisplay("600x900"); + const auto root_windows = Shell::GetAllRootWindows(); + ASSERT_EQ(1u, root_windows.size()); + + MagnifierFocusTestHelper focus_test_helper; + focus_test_helper.CreateAndShowFocusTestView(gfx::Point(70, 500)); + + // Enable the docked magnifier. + controller()->SetEnabled(true); + const float scale = 2.0f; + controller()->SetScale(scale); + EXPECT_TRUE(controller()->GetEnabled()); + EXPECT_FLOAT_EQ(scale, controller()->GetScale()); + + // Focus on the first button and expect the magnifier to be centered around + // its center. + focus_test_helper.FocusFirstButton(); + const ui::Layer* magnifier_layer = + controller()->GetViewportMagnifierLayerForTesting(); + gfx::Point button_1_center( + focus_test_helper.GetFirstButtonBoundsInRoot().CenterPoint()); + magnifier_layer->transform().TransformPoint(&button_1_center); + const views::Widget* viewport_widget = + controller()->GetViewportWidgetForTesting(); + const gfx::Point viewport_center( + viewport_widget->GetWindowBoundsInScreen().CenterPoint()); + EXPECT_EQ(button_1_center, viewport_center); + + // Similarly if we focus on the second button. + focus_test_helper.FocusSecondButton(); + gfx::Point button_2_center( + focus_test_helper.GetSecondButtonBoundsInRoot().CenterPoint()); + magnifier_layer->transform().TransformPoint(&button_2_center); + EXPECT_EQ(button_2_center, viewport_center); +} + // Tests that viewport layer is inverted properly when the status of the High // Contrast mode changes. TEST_F(DockedMagnifierTest, HighContrastMode) {
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc index 0b0b3b09..e4b01b2 100644 --- a/ash/magnifier/magnification_controller.cc +++ b/ash/magnifier/magnification_controller.cc
@@ -225,6 +225,13 @@ return gfx::ToEnclosingRect(GetWindowRectDIP(scale_)); } +void MagnificationController::CenterOnPoint(const gfx::Point& point_in_screen) { + gfx::Point point_in_root = point_in_screen; + ::wm::ConvertPointFromScreen(root_window_, &point_in_root); + + MoveMagnifierWindowCenterPoint(point_in_root); +} + void MagnificationController::HandleFocusedNodeChanged( bool is_editable_node, const gfx::Rect& node_bounds_in_screen) { @@ -271,6 +278,61 @@ root_window_->AddObserver(this); } +void MagnificationController::OnCaretBoundsChanged( + const ui::TextInputClient* client) { + // caret bounds in screen coordinates. + const gfx::Rect caret_bounds = client->GetCaretBounds(); + // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during + // which the caret position is not set a meaning position, and we do not + // need to adjust the view port position based on the bogus caret position. + // This is only a transition period, the caret position will be fixed upon + // focusing right after. + if (caret_bounds.width() == 0 && caret_bounds.height() == 0) + return; + + gfx::Point new_caret_point = caret_bounds.CenterPoint(); + // |caret_point_| in |root_window_| coordinates. + ::wm::ConvertPointFromScreen(root_window_, &new_caret_point); + + // When the caret point was not actually changed, nothing should happen. + // OnCaretBoundsChanged could be fired on every event that may change the + // caret bounds, in particular a window creation/movement, that may not result + // in an actual movement. + if (new_caret_point == caret_point_) + return; + caret_point_ = new_caret_point; + + // If the feature for centering the text input focus is disabled, the + // magnifier window will be moved to follow the focus with a panning margin. + if (!KeepFocusCentered()) { + // Visible window_rect in |root_window_| coordinates. + const gfx::Rect visible_window_rect = GetViewportRect(); + const int panning_margin = kCaretPanningMargin / scale_; + MoveMagnifierWindowFollowPoint(caret_point_, panning_margin, panning_margin, + visible_window_rect.width() / 2, + visible_window_rect.height() / 2); + return; + } + + // Move the magnifier window to center the focus with a little delay. + // In Gmail compose window, when user types a blank space, it will insert + // a non-breaking space(NBSP). NBSP will be replaced with a blank space + // character when user types a non-blank space character later, which causes + // OnCaretBoundsChanged be called twice. The first call moves the caret back + // to the character position just before NBSP, replaces the NBSP with blank + // space plus the new character, then the second call will move caret to the + // position after the new character. In order to avoid the magnifier window + // being moved back and forth with these two OnCaretBoundsChanged events, we + // defer moving magnifier window until the |move_magnifier_timer_| fires, + // when the caret settles eventually. + move_magnifier_timer_.Stop(); + move_magnifier_timer_.Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds( + disable_move_magnifier_delay_ ? 0 : kMoveMagnifierDelayInMs), + this, &MagnificationController::OnMoveMagnifierTimer); +} + void MagnificationController::OnImplicitAnimationsCompleted() { if (!is_on_animation_) return; @@ -453,6 +515,10 @@ // Jump back to exactly 1.0 if we are just a tiny bit zoomed in. if (scale_ < kMinMagnifiedScaleThreshold) { SetScale(kNonMagnifiedScale, true /* animate */); + } else { + // Store current magnifier scale in pref. We don't need to call this if we + // call SetScale (the above case) as SetScale does this. + Shell::Get()->accessibility_delegate()->SaveScreenMagnifierScale(scale_); } } @@ -484,61 +550,6 @@ return ui::EVENT_REWRITE_REWRITTEN; } -void MagnificationController::OnCaretBoundsChanged( - const ui::TextInputClient* client) { - // caret bounds in screen coordinates. - const gfx::Rect caret_bounds = client->GetCaretBounds(); - // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during - // which the caret position is not set a meaning position, and we do not - // need to adjust the view port position based on the bogus caret position. - // This is only a transition period, the caret position will be fixed upon - // focusing right after. - if (caret_bounds.width() == 0 && caret_bounds.height() == 0) - return; - - gfx::Point new_caret_point = caret_bounds.CenterPoint(); - // |caret_point_| in |root_window_| coordinates. - ::wm::ConvertPointFromScreen(root_window_, &new_caret_point); - - // When the caret point was not actually changed, nothing should happen. - // OnCaretBoundsChanged could be fired on every event that may change the - // caret bounds, in particular a window creation/movement, that may not result - // in an actual movement. - if (new_caret_point == caret_point_) - return; - caret_point_ = new_caret_point; - - // If the feature for centering the text input focus is disabled, the - // magnifier window will be moved to follow the focus with a panning margin. - if (!KeepFocusCentered()) { - // Visible window_rect in |root_window_| coordinates. - const gfx::Rect visible_window_rect = GetViewportRect(); - const int panning_margin = kCaretPanningMargin / scale_; - MoveMagnifierWindowFollowPoint(caret_point_, panning_margin, panning_margin, - visible_window_rect.width() / 2, - visible_window_rect.height() / 2); - return; - } - - // Move the magnifier window to center the focus with a little delay. - // In Gmail compose window, when user types a blank space, it will insert - // a non-breaking space(NBSP). NBSP will be replaced with a blank space - // character when user types a non-blank space character later, which causes - // OnCaretBoundsChanged be called twice. The first call moves the caret back - // to the character position just before NBSP, replaces the NBSP with blank - // space plus the new character, then the second call will move caret to the - // position after the new character. In order to avoid the magnifier window - // being moved back and forth with these two OnCaretBoundsChanged events, we - // defer moving magnifier window until the |move_magnifier_timer_| fires, - // when the caret settles eventually. - move_magnifier_timer_.Stop(); - move_magnifier_timer_.Start( - FROM_HERE, - base::TimeDelta::FromMilliseconds( - disable_move_magnifier_delay_ ? 0 : kMoveMagnifierDelayInMs), - this, &MagnificationController::OnMoveMagnifierTimer); -} - bool MagnificationController::Redraw(const gfx::PointF& position, float scale, bool animate) {
diff --git a/ash/magnifier/magnification_controller.h b/ash/magnifier/magnification_controller.h index 8f5cfeb..bc72d1f8 100644 --- a/ash/magnifier/magnification_controller.h +++ b/ash/magnifier/magnification_controller.h
@@ -95,7 +95,11 @@ // window coordinates. gfx::Rect GetViewportRect() const; - // Follows the focus on web page for non-editable controls. + // Centers the viewport around the given point in screen coordinates. + void CenterOnPoint(const gfx::Point& point_in_screen); + + // Follows the focus on web page for non-editable controls. Called from Chrome + // when Fullscreen magnifier feature is enabled. void HandleFocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen); @@ -106,6 +110,14 @@ void SwitchTargetRootWindow(aura::Window* new_root_window, bool redraw_original_root); + // ui::InputMethodObserver: + void OnFocus() override {} + void OnBlur() override {} + void OnCaretBoundsChanged(const ui::TextInputClient* client) override; + void OnTextInputStateChanged(const ui::TextInputClient* client) override {} + void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} + void OnShowImeIfNeeded() override {} + // Returns the last mouse cursor (or last touched) location. gfx::Point GetPointOfInterestForTesting() { return point_of_interest_in_root_; @@ -147,14 +159,6 @@ const ui::Event& last_event, std::unique_ptr<ui::Event>* new_event) override; - // ui::InputMethodObserver: - void OnFocus() override {} - void OnBlur() override {} - void OnCaretBoundsChanged(const ui::TextInputClient* client) override; - void OnTextInputStateChanged(const ui::TextInputClient* client) override {} - void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {} - void OnShowImeIfNeeded() override {} - // Redraws the magnification window with the given origin position and the // given scale. Returns true if the window is changed; otherwise, false. // These methods should be called internally just after the scale and/or
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc index 4dffe9e7..932e09c3 100644 --- a/ash/magnifier/magnification_controller_unittest.cc +++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -245,6 +245,7 @@ EXPECT_EQ("450,350", CurrentPointOfInterest()); } +// TODO(warx): move this test to unit_tests. TEST_F(MagnificationControllerTest, FollowFocusChanged) { // Enables magnifier and confirm the viewport is at center. GetMagnificationController()->SetEnabled(true); @@ -517,6 +518,30 @@ EXPECT_EQ("100,300", GetHostMouseLocation()); } +TEST_F(MagnificationControllerTest, FocusChangeEvents) { + MagnifierFocusTestHelper focus_test_helper; + focus_test_helper.CreateAndShowFocusTestView(gfx::Point(100, 200)); + + // Enables magnifier and confirm the viewport is at center. + GetMagnificationController()->SetEnabled(true); + EXPECT_EQ(2.0f, GetMagnificationController()->GetScale()); + EXPECT_EQ("200,150 400x300", GetViewport().ToString()); + EXPECT_FALSE(GetMagnificationController()->KeepFocusCentered()); + + // Focus on the first button and expect the magnifier to be centered around + // its center. + focus_test_helper.FocusFirstButton(); + gfx::Point button_1_center( + focus_test_helper.GetFirstButtonBoundsInRoot().CenterPoint()); + EXPECT_EQ(button_1_center, GetViewport().CenterPoint()); + + // Similarly if we focus on the second button. + focus_test_helper.FocusSecondButton(); + gfx::Point button_2_center( + focus_test_helper.GetSecondButtonBoundsInRoot().CenterPoint()); + EXPECT_EQ(button_2_center, GetViewport().CenterPoint()); +} + TEST_F(MagnificationControllerTest, FollowTextInputFieldFocus) { text_input_helper_.CreateAndShowTextInputView(gfx::Rect(500, 300, 80, 80)); gfx::Rect text_input_bounds = text_input_helper_.GetTextInputViewBounds();
diff --git a/ash/magnifier/magnifier_test_utils.cc b/ash/magnifier/magnifier_test_utils.cc index e86edcb..486b71f 100644 --- a/ash/magnifier/magnifier_test_utils.cc +++ b/ash/magnifier/magnifier_test_utils.cc
@@ -6,6 +6,7 @@ #include "ash/shell.h" #include "ui/base/ime/input_method.h" +#include "ui/views/controls/button/label_button.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/widget/widget.h" @@ -21,8 +22,61 @@ return view->GetWidget()->GetNativeWindow()->GetRootWindow(); } +gfx::Rect GetBoundsInRoot(const gfx::Rect& bounds_in_screen, + views::View* view) { + gfx::Rect bounds = bounds_in_screen; + ::wm::ConvertRectFromScreen(GetViewRootWindow(view), &bounds); + return bounds; +} + } // namespace +//////////////////////////////////////////////////////////////////////////////// +// TestFocusView: + +// A view that contains two buttons positioned at constant bounds with ability +// to request focus on either one. +class TestFocusView : public views::WidgetDelegateView { + public: + TestFocusView() + : button_1_(new views::LabelButton(nullptr, {})), + button_2_(new views::LabelButton(nullptr, {})) { + button_1_->SetFocusForPlatform(); + button_2_->SetFocusForPlatform(); + AddChildView(button_1_); + AddChildView(button_2_); + } + + ~TestFocusView() override = default; + + gfx::Size CalculatePreferredSize() const override { + return MagnifierFocusTestHelper::kTestFocusViewSize; + } + + void Layout() override { + // Layout the first button at the top of the view. + button_1_->SetBounds(0, 0, + MagnifierFocusTestHelper::kTestFocusViewSize.width(), + MagnifierFocusTestHelper::kButtonHeight); + + // And the second at the other end at the bottom of the view. + button_2_->SetBounds(0, + MagnifierFocusTestHelper::kTestFocusViewSize.height() - + MagnifierFocusTestHelper::kButtonHeight, + MagnifierFocusTestHelper::kTestFocusViewSize.width(), + MagnifierFocusTestHelper::kButtonHeight); + } + + views::LabelButton* button_1_; + views::LabelButton* button_2_; + + private: + DISALLOW_COPY_AND_ASSIGN(TestFocusView); +}; + +//////////////////////////////////////////////////////////////////////////////// +// TestTextInputView: + // A view that contains a single text field for testing text input events. class TestTextInputView : public views::WidgetDelegateView { public: @@ -46,6 +100,49 @@ DISALLOW_COPY_AND_ASSIGN(TestTextInputView); }; +//////////////////////////////////////////////////////////////////////////////// +// MagnifierFocusTestHelper: + +// static +constexpr int MagnifierFocusTestHelper::kButtonHeight; + +// static +constexpr gfx::Size MagnifierFocusTestHelper::kTestFocusViewSize; + +void MagnifierFocusTestHelper::CreateAndShowFocusTestView( + const gfx::Point& location) { + focus_test_view_ = new TestFocusView; + views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds( + focus_test_view_, Shell::GetPrimaryRootWindow(), + gfx::Rect(location, MagnifierFocusTestHelper::kTestFocusViewSize)); + widget->Show(); +} + +void MagnifierFocusTestHelper::FocusFirstButton() { + DCHECK(focus_test_view_); + focus_test_view_->button_1_->RequestFocus(); +} + +void MagnifierFocusTestHelper::FocusSecondButton() { + DCHECK(focus_test_view_); + focus_test_view_->button_2_->RequestFocus(); +} + +gfx::Rect MagnifierFocusTestHelper::GetFirstButtonBoundsInRoot() const { + DCHECK(focus_test_view_); + return GetBoundsInRoot(focus_test_view_->button_1_->GetBoundsInScreen(), + focus_test_view_); +} + +gfx::Rect MagnifierFocusTestHelper::GetSecondButtonBoundsInRoot() const { + DCHECK(focus_test_view_); + return GetBoundsInRoot(focus_test_view_->button_2_->GetBoundsInScreen(), + focus_test_view_); +} + +//////////////////////////////////////////////////////////////////////////////// +// MagnifierTextInputTestHelper: + void MagnifierTextInputTestHelper::CreateAndShowTextInputView( const gfx::Rect& bounds) { CreateAndShowTextInputViewInRoot(bounds, Shell::GetPrimaryRootWindow()); @@ -72,12 +169,9 @@ } gfx::Rect MagnifierTextInputTestHelper::GetCaretBounds() { - gfx::Rect caret_bounds = - GetInputMethod()->GetTextInputClient()->GetCaretBounds(); - gfx::Point origin = caret_bounds.origin(); - ::wm::ConvertPointFromScreen(GetViewRootWindow(text_input_view_), &origin); - return gfx::Rect(origin.x(), origin.y(), caret_bounds.width(), - caret_bounds.height()); + return GetBoundsInRoot( + GetInputMethod()->GetTextInputClient()->GetCaretBounds(), + text_input_view_); } void MagnifierTextInputTestHelper::FocusOnTextInputView() {
diff --git a/ash/magnifier/magnifier_test_utils.h b/ash/magnifier/magnifier_test_utils.h index 3276ed03..4284fc2 100644 --- a/ash/magnifier/magnifier_test_utils.h +++ b/ash/magnifier/magnifier_test_utils.h
@@ -6,12 +6,14 @@ #define ASH_MAGNIFIER_MAGNIFIER_TEST_UTILS_H_ #include "base/macros.h" +#include "ui/gfx/geometry/size.h" namespace aura { class Window; } // namespace aura namespace gfx { +class Point; class Rect; } // namespace gfx @@ -21,9 +23,39 @@ namespace ash { +class TestFocusView; class TestTextInputView; // Defines a test helper for magnifiers unit tests that wants to verify their +// behaviors in response to focus change events. +class MagnifierFocusTestHelper { + public: + MagnifierFocusTestHelper() = default; + ~MagnifierFocusTestHelper() = default; + + static constexpr int kButtonHeight = 20; + static constexpr gfx::Size kTestFocusViewSize{300, 200}; + + // Creates a view at |location| in the primary root window with size = + // |kTestFocusViewSize|. The view has two buttons, the first is positioned at + // the top of the view and the second at the bottom of the view. Both bottons + // have width = the width of |kTestFocusViewSize|, and height = + // |kButtonHeight|. + void CreateAndShowFocusTestView(const gfx::Point& location); + + void FocusFirstButton(); + void FocusSecondButton(); + + gfx::Rect GetFirstButtonBoundsInRoot() const; + gfx::Rect GetSecondButtonBoundsInRoot() const; + + private: + TestFocusView* focus_test_view_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(MagnifierFocusTestHelper); +}; + +// Defines a test helper for magnifiers unit tests that wants to verify their // behaviors in response to text fields input and focus events. class MagnifierTextInputTestHelper { public:
diff --git a/ash/public/interfaces/docked_magnifier_controller.mojom b/ash/public/interfaces/docked_magnifier_controller.mojom index c347ce6ca..c373adbe 100644 --- a/ash/public/interfaces/docked_magnifier_controller.mojom +++ b/ash/public/interfaces/docked_magnifier_controller.mojom
@@ -9,21 +9,10 @@ // Used by a client (e.g. Chrome) to notify ash of focus change events of nodes // in webpages. interface DockedMagnifierController { - // Sets the client that will be notified with status changes of the Docked - // Magnifier. - SetClient(DockedMagnifierClient client); - // Requests that the Docked Magnifier centers its viewport around this given // screen point. This can be used by a client (e.g. Chrome) to notify ash of - // focus change events in e.g. webpages. Note that ash observes the focus - // change events of the text input carets in editable nodes by itself. + // focus change events in e.g. webpages when feature is enabled. Note that ash + // observes the focus change events of the text input carets in editable nodes + // by itself. CenterOnPoint(gfx.mojom.Point point_in_screen); }; - -// Used by ash to notify a client (e.g. Chrome) of changes in the Docked -// Magnifier enabled status. This relieves clients from observing changes in the -// active user profile and the associated prefs. -interface DockedMagnifierClient { - // Notifies the client with the new enabled status of the Docked Magnifier. - OnEnabledStatusChanged(bool enabled); -}; \ No newline at end of file
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd index 786edc425..91535e0 100644 --- a/ash/resources/ash_resources.grd +++ b/ash/resources/ash_resources.grd
@@ -19,9 +19,6 @@ <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_HEADER_SHADE_INACTIVE_LEFT" file="common/window_header_shade_left_inactive.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_HEADER_SHADE_INACTIVE_RIGHT" file="common/window_header_shade_right_inactive.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_HEADER_SHADE_INACTIVE_TOP" file="common/window_header_shade_top_inactive.png" /> - - <!-- Crostini terminal images --> - <structure type="chrome_scaled_image" name="IDR_LOGO_CROSTINI_TERMINAL" file="cros/crostini/logo_crostini_terminal.png" /> </structures> </release> </grit>
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc index e3fb871..6fbf822a 100644 --- a/ash/rotator/screen_rotation_animator.cc +++ b/ash/rotator/screen_rotation_animator.cc
@@ -115,7 +115,7 @@ display::Display::Rotation new_rotation, const display::Display& display) { gfx::Transform inverse; - CHECK(CreateRotationTransform(old_rotation, new_rotation, display) + CHECK(CreateRotationTransform(old_rotation, new_rotation, display.bounds()) .GetInverse(&inverse)); return inverse; }
diff --git a/ash/utility/transformer_util.cc b/ash/utility/transformer_util.cc index e5a2e37..8eb4a22 100644 --- a/ash/utility/transformer_util.cc +++ b/ash/utility/transformer_util.cc
@@ -25,22 +25,22 @@ gfx::Transform CreateRotationTransform(display::Display::Rotation old_rotation, display::Display::Rotation new_rotation, - const display::Display& display) { + const gfx::Rect& rect_to_rotate) { const int rotation_angle = 90 * (((new_rotation - old_rotation) + 4) % 4); gfx::Transform rotate; switch (rotation_angle) { case 0: break; case 90: - rotate.Translate(display.bounds().height(), 0); + rotate.Translate(rect_to_rotate.height(), 0); rotate.Rotate(90); break; case 180: - rotate.Translate(display.bounds().width(), display.bounds().height()); + rotate.Translate(rect_to_rotate.width(), rect_to_rotate.height()); rotate.Rotate(180); break; case 270: - rotate.Translate(0, display.bounds().width()); + rotate.Translate(0, rect_to_rotate.width()); rotate.Rotate(270); break; }
diff --git a/ash/utility/transformer_util.h b/ash/utility/transformer_util.h index d75c5fa..bd1bd75 100644 --- a/ash/utility/transformer_util.h +++ b/ash/utility/transformer_util.h
@@ -14,12 +14,12 @@ namespace ash { -// Creates rotation transform from |old_rotation| to |new_rotation| based on the -// |display| info. +// Creates rotation transform that rotates the |rect_to_rotate| from +// |old_rotation| to |new_rotation|. ASH_EXPORT gfx::Transform CreateRotationTransform( display::Display::Rotation old_rotation, display::Display::Rotation new_rotation, - const display::Display& display); + const gfx::Rect& rect_to_rotate); } // namespace ash
diff --git a/base/base_switches.cc b/base/base_switches.cc index 62e6d3dc..7ce7380 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc
@@ -24,25 +24,6 @@ // Comma-separated list of feature names to enable. See also kDisableFeatures. const char kEnableFeatures[] = "enable-features"; -// Makes memory allocators keep track of their allocations and context, so a -// detailed breakdown of memory usage can be presented in chrome://tracing when -// the memory-infra category is enabled. -const char kEnableHeapProfiling[] = "enable-heap-profiling"; - -// Report pseudo allocation traces. Pseudo traces are derived from currently -// active trace events. -const char kEnableHeapProfilingModePseudo[] = ""; - -// Report native (walk the stack) allocation traces. By default pseudo stacks -// derived from trace events are reported. -const char kEnableHeapProfilingModeNative[] = "native"; - -// Report per-task heap usage and churn in the task profiler. -// Does not keep track of individual allocations unlike the default and native -// mode. Keeps only track of summarized churn stats in the task profiler -// (chrome://profiler). -const char kEnableHeapProfilingTaskProfiler[] = "task-profiler"; - // Generates full memory crash dump. const char kFullMemoryCrashReport[] = "full-memory-crash-report";
diff --git a/base/base_switches.h b/base/base_switches.h index a444f09b..3425e6f 100644 --- a/base/base_switches.h +++ b/base/base_switches.h
@@ -17,10 +17,6 @@ extern const char kDisableLowEndDeviceMode[]; extern const char kEnableCrashReporter[]; extern const char kEnableFeatures[]; -extern const char kEnableHeapProfiling[]; -extern const char kEnableHeapProfilingModePseudo[]; -extern const char kEnableHeapProfilingModeNative[]; -extern const char kEnableHeapProfilingTaskProfiler[]; extern const char kEnableLowEndDeviceMode[]; extern const char kForceFieldTrials[]; extern const char kFullMemoryCrashReport[];
diff --git a/base/containers/flat_map.h b/base/containers/flat_map.h index dd0788e..2214ec3 100644 --- a/base/containers/flat_map.h +++ b/base/containers/flat_map.h
@@ -210,9 +210,9 @@ // // Assume that swap invalidates iterators and references. - void swap(flat_map& other); + void swap(flat_map& other) noexcept; - friend void swap(flat_map& lhs, flat_map& rhs) { lhs.swap(rhs); } + friend void swap(flat_map& lhs, flat_map& rhs) noexcept { lhs.swap(rhs); } }; // ---------------------------------------------------------------------------- @@ -287,7 +287,7 @@ // General operations. template <class Key, class Mapped, class Compare> -void flat_map<Key, Mapped, Compare>::swap(flat_map& other) { +void flat_map<Key, Mapped, Compare>::swap(flat_map& other) noexcept { tree::swap(other); }
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h index 5b421accf..7856e24 100644 --- a/base/containers/flat_tree.h +++ b/base/containers/flat_tree.h
@@ -140,7 +140,7 @@ const key_compare& comp = key_compare()); flat_tree(const flat_tree&); - flat_tree(flat_tree&&); + flat_tree(flat_tree&&) noexcept = default; flat_tree(std::vector<value_type> items, FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES, @@ -301,7 +301,7 @@ // and lexicograhpical_compare(). If the underlying container type is changed, // this code may need to be modified. - void swap(flat_tree& other); + void swap(flat_tree& other) noexcept; friend bool operator==(const flat_tree& lhs, const flat_tree& rhs) { return lhs.impl_.body_ == rhs.impl_.body_; @@ -327,7 +327,7 @@ return !(lhs > rhs); } - friend void swap(flat_tree& lhs, flat_tree& rhs) { lhs.swap(rhs); } + friend void swap(flat_tree& lhs, flat_tree& rhs) noexcept { lhs.swap(rhs); } protected: // Emplaces a new item into the tree that is known not to be in it. This @@ -520,10 +520,6 @@ const flat_tree&) = default; template <class Key, class Value, class GetKeyFromValue, class KeyCompare> -flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree(flat_tree&&) = - default; - -template <class Key, class Value, class GetKeyFromValue, class KeyCompare> flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree( std::vector<value_type> items, FlatContainerDupes dupe_handling, @@ -934,7 +930,7 @@ template <class Key, class Value, class GetKeyFromValue, class KeyCompare> void flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::swap( - flat_tree& other) { + flat_tree& other) noexcept { std::swap(impl_, other.impl_); }
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h index 9bd656d..da03b7f6 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker.h +++ b/base/trace_event/heap_profiler_allocation_context_tracker.h
@@ -15,11 +15,25 @@ namespace base { namespace trace_event { -// The allocation context tracker keeps track of thread-local context for heap -// profiling. It includes a pseudo stack of trace events. On every allocation -// the tracker provides a snapshot of its context in the form of an -// |AllocationContext| that is to be stored together with the allocation -// details. +// AllocationContextTracker is a thread-local object. Its main purpose is to +// keep track of a pseudo stack of trace events. Chrome has been instrumented +// with lots of `TRACE_EVENT` macros. These trace events push their name to a +// thread-local stack when they go into scope, and pop when they go out of +// scope, if all of the following conditions have been met: +// +// * A trace is being recorded. +// * The category of the event is enabled in the trace config. +// * Heap profiling is enabled (with the `--enable-heap-profiling` flag). +// +// This means that allocations that occur before tracing is started will not +// have backtrace information in their context. +// +// AllocationContextTracker also keeps track of some thread state not related to +// trace events. See |AllocationContext|. +// +// A thread-local instance of the context tracker is initialized lazily when it +// is first accessed. This might be because a trace event pushed or popped, or +// because `GetContextSnapshot()` was called when an allocation occurred class BASE_EXPORT AllocationContextTracker { public: enum class CaptureMode : int32_t {
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 7f35a92..f6cc832 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -206,44 +206,6 @@ g_memory_dump_manager_for_testing = nullptr; } -// static -HeapProfilingMode MemoryDumpManager::GetHeapProfilingModeFromCommandLine() { - if (!CommandLine::InitializedForCurrentProcess() || - !CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableHeapProfiling)) { - return kHeapProfilingModeDisabled; - } -#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) - std::string profiling_mode = - CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kEnableHeapProfiling); - if (profiling_mode == switches::kEnableHeapProfilingTaskProfiler) - return kHeapProfilingModeTaskProfiler; - if (profiling_mode == switches::kEnableHeapProfilingModePseudo) - return kHeapProfilingModePseudo; - if (profiling_mode == switches::kEnableHeapProfilingModeNative) - return kHeapProfilingModeNative; -#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) - return kHeapProfilingModeInvalid; -} - -void MemoryDumpManager::EnableHeapProfilingIfNeeded() { -#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) - HeapProfilingMode profiling_mode = GetHeapProfilingModeFromCommandLine(); - if (IsHeapProfilingModeEnabled(profiling_mode)) { - EnableHeapProfiling(profiling_mode); - } else { - if (profiling_mode == kHeapProfilingModeInvalid) { - // Heap profiling is misconfigured, disable it permanently. - EnableHeapProfiling(kHeapProfilingModeDisabled); - } - } -#else - // Heap profiling is unsupported, disable it permanently. - EnableHeapProfiling(kHeapProfilingModeDisabled); -#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) -} - bool MemoryDumpManager::EnableHeapProfiling(HeapProfilingMode profiling_mode) { AutoLock lock(lock_); #if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) @@ -341,7 +303,6 @@ request_dump_function_ = request_dump_function; is_coordinator_ = is_coordinator; } - EnableHeapProfilingIfNeeded(); // Enable the core dump providers. #if defined(MALLOC_MEMORY_TRACING_SUPPORTED)
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h index d6237fd..072a7d6 100644 --- a/base/trace_event/memory_dump_manager.h +++ b/base/trace_event/memory_dump_manager.h
@@ -131,15 +131,6 @@ void CreateProcessDump(const MemoryDumpRequestArgs& args, const ProcessMemoryDumpCallback& callback); - // Returns the heap profiling mode configured on the command-line, if any. - // If heap profiling is configured but not supported by this binary, or if an - // invalid mode is specified, then kHeapProfilingInvalid is returned. - static HeapProfilingMode GetHeapProfilingModeFromCommandLine(); - - // Enable heap profiling if supported, and kEnableHeapProfiling command line - // is specified. - void EnableHeapProfilingIfNeeded(); - // Enable heap profiling with specified |profiling_mode|. // Use kHeapProfilingModeDisabled to disable, but it can't be re-enabled then. // Returns true if mode has been *changed* to the desired |profiling_mode|.
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc index de98f1d..e92045ed 100644 --- a/base/trace_event/memory_dump_manager_unittest.cc +++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -961,54 +961,6 @@ } #endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) -TEST_F(MemoryDumpManagerTest, EnableHeapProfilingIfNeeded) { - MockMemoryDumpProvider mdp1; - MemoryDumpProvider::Options supported_options; - supported_options.supports_heap_profiling = true; - RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get(), supported_options); - - // Should be noop. - mdm_->EnableHeapProfilingIfNeeded(); - ASSERT_EQ(AllocationContextTracker::CaptureMode::DISABLED, - AllocationContextTracker::capture_mode()); - mdm_->EnableHeapProfilingIfNeeded(); - ASSERT_EQ(AllocationContextTracker::CaptureMode::DISABLED, - AllocationContextTracker::capture_mode()); - -#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) - testing::InSequence sequence; - EXPECT_CALL(mdp1, OnHeapProfilingEnabled(true)).Times(1); - EXPECT_CALL(mdp1, OnHeapProfilingEnabled(false)).Times(1); - - CommandLine* cmdline = CommandLine::ForCurrentProcess(); - cmdline->AppendSwitchASCII(switches::kEnableHeapProfiling, ""); - mdm_->EnableHeapProfilingIfNeeded(); - RunLoop().RunUntilIdle(); - ASSERT_EQ(AllocationContextTracker::CaptureMode::PSEUDO_STACK, - AllocationContextTracker::capture_mode()); - EXPECT_TRUE(mdm_->EnableHeapProfiling(kHeapProfilingModeDisabled)); - RunLoop().RunUntilIdle(); - ASSERT_EQ(AllocationContextTracker::CaptureMode::DISABLED, - AllocationContextTracker::capture_mode()); - EXPECT_FALSE(mdm_->EnableHeapProfiling(kHeapProfilingModeBackground)); - ASSERT_EQ(AllocationContextTracker::CaptureMode::DISABLED, - AllocationContextTracker::capture_mode()); -#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) -} - -TEST_F(MemoryDumpManagerTest, EnableHeapProfilingIfNeededUnsupported) { -#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) - ASSERT_EQ(mdm_->GetHeapProfilingMode(), kHeapProfilingModeDisabled); - CommandLine* cmdline = CommandLine::ForCurrentProcess(); - cmdline->AppendSwitchASCII(switches::kEnableHeapProfiling, "unsupported"); - mdm_->EnableHeapProfilingIfNeeded(); - EXPECT_EQ(mdm_->GetHeapProfilingMode(), kHeapProfilingModeInvalid); -#else - mdm_->EnableHeapProfilingIfNeeded(); - EXPECT_EQ(mdm_->GetHeapProfilingMode(), kHeapProfilingModeInvalid); -#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL) -} - // Mock MDP class that tests if the number of OnMemoryDump() calls are expected. // It is implemented without gmocks since EXPECT_CALL implementation is slow // when there are 1000s of instances, as required in
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index b279f1e..02edeb5d 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -3a1662dfbcb3ad44bbc10a70c7424da462c4ba0d +4ff493298d2c801c30489dff4786321d7f698031 \ No newline at end of file
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn index 535acba..ed7ce8e7 100644 --- a/cc/paint/BUILD.gn +++ b/cc/paint/BUILD.gn
@@ -67,6 +67,8 @@ "paint_typeface.h", "paint_typeface_transfer_cache_entry.cc", "paint_typeface_transfer_cache_entry.h", + "path_transfer_cache_entry.cc", + "path_transfer_cache_entry.h", "raw_memory_transfer_cache_entry.cc", "raw_memory_transfer_cache_entry.h", "record_paint_canvas.cc",
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index 2e7dbe0..b997a58 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -14,6 +14,7 @@ #include "cc/paint/paint_op_buffer.h" #include "cc/paint/paint_shader.h" #include "cc/paint/paint_typeface_transfer_cache_entry.h" +#include "cc/paint/path_transfer_cache_entry.h" #include "cc/paint/transfer_cache_deserialize_helper.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRRect.h" @@ -213,21 +214,17 @@ } void PaintOpReader::Read(SkPath* path) { - AlignMemory(4); + uint32_t transfer_cache_entry_id; + ReadSimple(&transfer_cache_entry_id); if (!valid_) return; - - // This is assumed safe from TOCTOU violations as the SkPath deserializing - // function uses an SkRBuffer which reads each piece of memory once much - // like PaintOpReader does. Additionally, paths are later validated in - // PaintOpBuffer. - size_t read_bytes = - path->readFromMemory(const_cast<const char*>(memory_), remaining_bytes_); - if (!read_bytes) - SetInvalid(); - - memory_ += read_bytes; - remaining_bytes_ -= read_bytes; + auto* entry = transfer_cache_->GetEntryAs<ServicePathTransferCacheEntry>( + transfer_cache_entry_id); + if (entry) { + *path = entry->path(); + } else { + valid_ = false; + } } void PaintOpReader::Read(PaintFlags* flags) {
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc index 697a9ea..6d40039 100644 --- a/cc/paint/paint_op_writer.cc +++ b/cc/paint/paint_op_writer.cc
@@ -11,6 +11,7 @@ #include "cc/paint/paint_op_buffer_serializer.h" #include "cc/paint/paint_shader.h" #include "cc/paint/paint_typeface_transfer_cache_entry.h" +#include "cc/paint/path_transfer_cache_entry.h" #include "cc/paint/transfer_cache_serialize_helper.h" #include "third_party/skia/include/core/SkSerialProcs.h" #include "third_party/skia/include/core/SkTextBlob.h" @@ -169,16 +170,13 @@ } void PaintOpWriter::Write(const SkPath& path) { - AlignMemory(4); - size_t bytes = path.writeToMemory(nullptr); - EnsureBytes(bytes); - if (!valid_) - return; - - size_t bytes_written = path.writeToMemory(memory_); - DCHECK_LE(bytes_written, bytes); - memory_ += bytes; - remaining_bytes_ -= bytes; + auto id = path.getGenerationID(); + auto locked = transfer_cache_->LockEntry(TransferCacheEntryType::kPath, id); + if (!locked) { + transfer_cache_->CreateEntry(ClientPathTransferCacheEntry(path)); + transfer_cache_->AssertLocked(TransferCacheEntryType::kPath, id); + } + Write(id); } void PaintOpWriter::Write(const PaintFlags& flags) {
diff --git a/cc/paint/path_transfer_cache_entry.cc b/cc/paint/path_transfer_cache_entry.cc new file mode 100644 index 0000000..c149010 --- /dev/null +++ b/cc/paint/path_transfer_cache_entry.cc
@@ -0,0 +1,54 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/paint/path_transfer_cache_entry.h" + +namespace cc { + +ClientPathTransferCacheEntry::ClientPathTransferCacheEntry(const SkPath& path) + : path_(path) { + size_ = path_.writeToMemory(nullptr); +} + +ClientPathTransferCacheEntry::~ClientPathTransferCacheEntry() = default; + +uint32_t ClientPathTransferCacheEntry::Id() const { + return path_.getGenerationID(); +} + +size_t ClientPathTransferCacheEntry::SerializedSize() const { + return size_; +} + +bool ClientPathTransferCacheEntry::Serialize(base::span<uint8_t> data) const { + DCHECK_EQ(data.size(), size_); + + size_t bytes_written = path_.writeToMemory(data.data()); + CHECK_LE(bytes_written, size_); + return true; +} + +ServicePathTransferCacheEntry::ServicePathTransferCacheEntry() = default; + +ServicePathTransferCacheEntry::~ServicePathTransferCacheEntry() = default; + +size_t ServicePathTransferCacheEntry::CachedSize() const { + return size_; +} + +bool ServicePathTransferCacheEntry::Deserialize( + GrContext* context, + base::span<const uint8_t> data) { + size_t read_bytes = path_.readFromMemory(data.data(), data.size()); + // Invalid path. + if (read_bytes == 0) + return false; + if (read_bytes > data.size()) + return false; + size_ = read_bytes; + + return true; +} + +} // namespace cc
diff --git a/cc/paint/path_transfer_cache_entry.h b/cc/paint/path_transfer_cache_entry.h new file mode 100644 index 0000000..b1282e3c --- /dev/null +++ b/cc/paint/path_transfer_cache_entry.h
@@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_PAINT_PATH_TRANSFER_CACHE_ENTRY_H_ +#define CC_PAINT_PATH_TRANSFER_CACHE_ENTRY_H_ + +#include "base/containers/span.h" +#include "cc/paint/paint_export.h" +#include "cc/paint/transfer_cache_entry.h" +#include "third_party/skia/include/core/SkPath.h" + +namespace cc { + +class CC_PAINT_EXPORT ClientPathTransferCacheEntry + : public ClientTransferCacheEntryBase<TransferCacheEntryType::kPath> { + public: + explicit ClientPathTransferCacheEntry(const SkPath& path); + ~ClientPathTransferCacheEntry() final; + uint32_t Id() const final; + size_t SerializedSize() const final; + bool Serialize(base::span<uint8_t> data) const final; + + private: + SkPath path_; + size_t size_ = 0u; +}; + +class CC_PAINT_EXPORT ServicePathTransferCacheEntry + : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kPath> { + public: + ServicePathTransferCacheEntry(); + ~ServicePathTransferCacheEntry() final; + size_t CachedSize() const final; + bool Deserialize(GrContext* context, base::span<const uint8_t> data) final; + + const SkPath& path() const { return path_; } + + private: + SkPath path_; + size_t size_ = 0; +}; + +} // namespace cc + +#endif // CC_PAINT_PATH_TRANSFER_CACHE_ENTRY_H_
diff --git a/cc/paint/transfer_cache_entry.cc b/cc/paint/transfer_cache_entry.cc index 46252c18..66c9622 100644 --- a/cc/paint/transfer_cache_entry.cc +++ b/cc/paint/transfer_cache_entry.cc
@@ -10,6 +10,7 @@ #include "cc/paint/color_space_transfer_cache_entry.h" #include "cc/paint/image_transfer_cache_entry.h" #include "cc/paint/paint_typeface_transfer_cache_entry.h" +#include "cc/paint/path_transfer_cache_entry.h" #include "cc/paint/raw_memory_transfer_cache_entry.h" namespace cc { @@ -25,6 +26,8 @@ return std::make_unique<ServicePaintTypefaceTransferCacheEntry>(); case TransferCacheEntryType::kColorSpace: return std::make_unique<ServiceColorSpaceTransferCacheEntry>(); + case TransferCacheEntryType::kPath: + return std::make_unique<ServicePathTransferCacheEntry>(); } return nullptr;
diff --git a/cc/paint/transfer_cache_entry.h b/cc/paint/transfer_cache_entry.h index 9ecde14a..dca7b96e 100644 --- a/cc/paint/transfer_cache_entry.h +++ b/cc/paint/transfer_cache_entry.h
@@ -24,8 +24,9 @@ kImage, kPaintTypeface, kColorSpace, + kPath, // Add new entries above this line, make sure to update kLast. - kLast = kColorSpace, + kLast = kPath, }; // An interface used on the client to serialize a transfer cache entry
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc index 648f171..6a52e91 100644 --- a/cc/tiles/software_image_decode_cache.cc +++ b/cc/tiles/software_image_decode_cache.cc
@@ -554,7 +554,21 @@ std::max(lifetime_max_items_in_cache_, decoded_images_.size()); for (auto it = decoded_images_.rbegin(); decoded_images_.size() > limit && it != decoded_images_.rend();) { - EraseCacheEntry(&it); + if (it->second->ref_count != 0) { + ++it; + continue; + } + + const CacheKey& key = it->first; + auto vector_it = frame_key_to_image_keys_.find(key.frame_key()); + auto item_it = + std::find(vector_it->second.begin(), vector_it->second.end(), key); + DCHECK(item_it != vector_it->second.end()); + vector_it->second.erase(item_it); + if (vector_it->second.empty()) + frame_key_to_image_keys_.erase(vector_it); + + it = decoded_images_.Erase(it); } } @@ -659,86 +673,12 @@ SoftwareImageDecodeCache::CacheEntry* SoftwareImageDecodeCache::AddCacheEntry( const CacheKey& key) { lock_.AssertAcquired(); - frame_key_to_image_keys_[key.frame_key()].push_back(key); - - PaintImage::ContentId content_id = key.frame_key().content_id(); - content_id_to_cache_keys_[content_id].insert(key); - ContentIdSet& content_ids_for_stable_id = - stable_id_to_content_ids_[key.stable_id()]; - content_ids_for_stable_id.insert(content_id); - auto it = decoded_images_.Put(key, std::make_unique<CacheEntry>()); it->second.get()->mark_cached(); - - // If we have more than two content ids for this stable id, then try to erase - // all images for all content ids except for the most recent two (and also - // |key|'s content id, in case it is not one of the most recent two). - if (content_ids_for_stable_id.size() > 2) { - ContentIdSet content_ids_to_remove = content_ids_for_stable_id; - content_ids_to_remove.erase(*content_ids_to_remove.rbegin()); - content_ids_to_remove.erase(*content_ids_to_remove.rbegin()); - content_ids_to_remove.erase(content_id); - for (auto content_id_to_erase : content_ids_to_remove) { - CacheKeySet cache_keys_to_remove = - content_id_to_cache_keys_[content_id_to_erase]; - for (const CacheKey& key : cache_keys_to_remove) { - auto found = decoded_images_.Peek(key); - DCHECK(found != decoded_images_.end()); - auto found_reversed = std::make_reverse_iterator(found); - EraseCacheEntry(&found_reversed); - } - } - } - return it->second.get(); } -void SoftwareImageDecodeCache::EraseCacheEntry( - ImageMRUCache::reverse_iterator* it) { - if ((*it)->second->ref_count != 0) { - ++(*it); - return; - } - const CacheKey& key = (*it)->first; - PaintImage::ContentId content_id = key.frame_key().content_id(); - PaintImage::Id stable_id = key.stable_id(); - - // Remove from |content_id_to_cache_keys_|. - auto found_cache_key_set = content_id_to_cache_keys_.find(content_id); - DCHECK(found_cache_key_set != content_id_to_cache_keys_.end()); - found_cache_key_set->second.erase(key); - // If this erases the last entry for |content_id|, then... - if (found_cache_key_set->second.empty()) { - // Erase |content_id| from |content_id_to_cache_keys_|. - content_id_to_cache_keys_.erase(found_cache_key_set); - // Erase |content_id| from |stable_id_to_content_ids_[stable_id]|. - auto found_content_id_set = stable_id_to_content_ids_.find(stable_id); - DCHECK(found_content_id_set != stable_id_to_content_ids_.end()); - auto found_content_id = found_content_id_set->second.find(content_id); - DCHECK(found_content_id != found_content_id_set->second.end()); - found_content_id_set->second.erase(found_content_id); - // If that empties |stable_id_to_content_ids_[stable_id]|, then erase - // |stable_id| from |stable_id_to_content_ids_|. - if (found_content_id_set->second.empty()) { - stable_id_to_content_ids_.erase(found_content_id_set); - } - } - - // Remove from |frame_key_to_image_keys_|. - auto vector_it = frame_key_to_image_keys_.find(key.frame_key()); - auto item_it = - std::find(vector_it->second.begin(), vector_it->second.end(), key); - DCHECK(item_it != vector_it->second.end()); - vector_it->second.erase(item_it); - if (vector_it->second.empty()) - frame_key_to_image_keys_.erase(vector_it); - - // Remove from the MRU cache. - *it = decoded_images_.Erase(*it); - return; -} - // MemoryBudget ---------------------------------------------------------------- SoftwareImageDecodeCache::MemoryBudget::MemoryBudget(size_t limit_bytes) : limit_bytes_(limit_bytes), current_usage_bytes_(0u) {}
diff --git a/cc/tiles/software_image_decode_cache.h b/cc/tiles/software_image_decode_cache.h index 5b0534f..0fa379c2 100644 --- a/cc/tiles/software_image_decode_cache.h +++ b/cc/tiles/software_image_decode_cache.h
@@ -8,9 +8,7 @@ #include <stdint.h> #include <memory> -#include <set> #include <unordered_map> -#include <unordered_set> #include "base/containers/mru_cache.h" #include "base/memory/memory_coordinator_client.h" @@ -93,8 +91,6 @@ using ImageMRUCache = base:: HashingMRUCache<CacheKey, std::unique_ptr<CacheEntry>, CacheKeyHash>; - using ContentIdSet = std::set<PaintImage::ContentId>; - using CacheKeySet = std::unordered_set<CacheKey, CacheKeyHash>; // Actually decode the image. Note that this function can (and should) be // called with no lock acquired, since it can do a lot of work. Note that it @@ -126,10 +122,6 @@ DecodeTaskType type); CacheEntry* AddCacheEntry(const CacheKey& key); - // If the entry at |*it| is not in use, erase it and update |*it| to point to - // the next entry. If unable to erase the entry, update |*it| to point to the - // next entry. - void EraseCacheEntry(ImageMRUCache::reverse_iterator* it); void DecodeImageIfNecessary(const CacheKey& key, const PaintImage& paint_image, @@ -148,11 +140,6 @@ // Decoded images and ref counts (predecode path). ImageMRUCache decoded_images_; - // Additional tracking of all entries in |decoded_images_| by static id and - // by content id. Updated only in AddCacheEntry and EraseCacheEntry. - std::map<PaintImage::Id, ContentIdSet> stable_id_to_content_ids_; - std::map<PaintImage::ContentId, CacheKeySet> content_id_to_cache_keys_; - // A map of PaintImage::FrameKey to the ImageKeys for cached decodes of this // PaintImage. std::unordered_map<PaintImage::FrameKey,
diff --git a/cc/tiles/software_image_decode_cache_unittest.cc b/cc/tiles/software_image_decode_cache_unittest.cc index 58fc5073..c9f8c5a 100644 --- a/cc/tiles/software_image_decode_cache_unittest.cc +++ b/cc/tiles/software_image_decode_cache_unittest.cc
@@ -1742,7 +1742,9 @@ cache.DrawWithImageFinished(draw_image, decoded_draw_image); } -TEST(SoftwareImageDecodeCacheTest, ContentIdCaching) { +// TODO(ccameron): Re-enable this when the root cause of crashes is discovered. +// https://crbug.com/791828 +TEST(SoftwareImageDecodeCacheTest, DISABLED_ContentIdCaching) { TestSoftwareImageDecodeCache cache; bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality;
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 33324a6..e09e525 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -1558,6 +1558,11 @@ const ResourcePool::InUsePoolResource& resource = tile->draw_info().GetResource(); + // Update requirements first so that if the tile has become required + // it will force a redraw. + if (pending_tile_requirements_dirty_) + tile->tiling()->UpdateRequiredStatesOnTile(tile); + if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY || raster_buffer_provider_->IsResourceReadyToDraw(resource)) { tile->draw_info().set_resource_ready_for_draw(); @@ -1569,8 +1574,6 @@ // TODO(ericrk): If a tile in our list no longer has valid tile priorities, // it may still report that it is required, and unnecessarily delay // activation. crbug.com/687265 - if (pending_tile_requirements_dirty_) - tile->tiling()->UpdateRequiredStatesOnTile(tile); if (tile->required_for_activation()) required_for_activation.push_back(&resource); if (tile->required_for_draw())
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 8c9a5f4..67b0a31 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -2291,7 +2291,6 @@ run_loop.Quit(); return 1; })); - host_impl()->tile_manager()->DidModifyTilePriorities(); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); run_loop.Run(); } @@ -2321,7 +2320,6 @@ // will cause a test failure. base::RunLoop run_loop; - host_impl()->tile_manager()->DidModifyTilePriorities(); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); @@ -2356,7 +2354,6 @@ run_loop.Quit(); return 1; })); - host_impl()->tile_manager()->DidModifyTilePriorities(); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); run_loop.Run(); } @@ -2386,7 +2383,6 @@ // will cause a test failure. base::RunLoop run_loop; - host_impl()->tile_manager()->DidModifyTilePriorities(); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()) .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); @@ -2401,7 +2397,6 @@ SetupTreesWithPendingTreeTiles(); base::RunLoop run_loop; - host_impl()->tile_manager()->DidModifyTilePriorities(); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); @@ -2413,6 +2408,92 @@ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } +TEST_F(TileManagerReadyToDrawTest, TilePrioritiesUpdated) { + // Use smoothness as that's a mode in which we wait on resources to be + // ready instead of marking them ready immediately. + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + gfx::Size very_small(1, 1); + host_impl()->SetViewportSize(very_small); + + gfx::Size layer_bounds(1000, 1000); + SetupDefaultTrees(layer_bounds); + + // Run until all tile tasks are complete, but don't let any draw callbacks + // finish. + { + base::RunLoop run_loop; + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + + // Until we activate our ready to draw callback, treat all resources as not + // ready to draw. + EXPECT_CALL(*mock_raster_buffer_provider(), + IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, _)) + .WillRepeatedly(Return(1)); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + run_loop.Run(); + } + + // Inspect the current state of tiles in this world of cpu done but gpu + // not ready yet. + size_t orig_num_required = 0; + size_t orig_num_prepaint = 0; + std::vector<Tile*> prepaint_tiles; + for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) { + if (tile->draw_info().has_resource()) { + if (tile->is_prepaint()) { + orig_num_prepaint++; + prepaint_tiles.push_back(tile); + } else { + orig_num_required++; + } + } + } + + // Verify that there exist some prepaint tiles here. + EXPECT_GT(orig_num_prepaint, 0u); + EXPECT_GT(orig_num_required, 0u); + + host_impl()->SetViewportSize(layer_bounds); + host_impl()->active_tree()->UpdateDrawProperties(); + host_impl()->pending_tree()->UpdateDrawProperties(); + + // Rerun prepare tiles. + { + base::RunLoop run_loop; + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + run_loop.Run(); + } + + // Make sure tiles priorities are updated. + size_t final_num_required = 0; + size_t final_num_prepaint = 0; + bool found_one_prepaint_to_required_transition = false; + for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) { + if (tile->draw_info().has_resource()) { + if (tile->is_prepaint()) { + final_num_prepaint++; + } else { + final_num_required++; + if (std::find(prepaint_tiles.begin(), prepaint_tiles.end(), tile) != + prepaint_tiles.end()) { + found_one_prepaint_to_required_transition = true; + } + } + } + } + + // Tile priorities should be updated and we should have more required + // and fewer prepaint now that the viewport has changed. + EXPECT_GT(final_num_required, orig_num_required); + EXPECT_LT(final_num_prepaint, orig_num_prepaint); + EXPECT_TRUE(found_one_prepaint_to_required_transition); +} + void UpdateVisibleRect(FakePictureLayerImpl* layer, const gfx::Rect visible_rect) { PictureLayerTilingSet* tiling_set = layer->tilings();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 32cc59dc..1cb74744 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1449,6 +1449,7 @@ void LayerTreeHostImpl::DidModifyTilePriorities() { // Mark priorities as dirty and schedule a PrepareTiles(). tile_priorities_dirty_ = true; + tile_manager_.DidModifyTilePriorities(); client_->SetNeedsPrepareTilesOnImplThread(); }
diff --git a/chrome/VERSION b/chrome/VERSION index aa8893231..b0bd7def0 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=68 MINOR=0 -BUILD=3402 +BUILD=3405 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index 89900ed..3164f27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -399,16 +399,6 @@ } @Override - public boolean shouldHideAndroidBrowserControls() { - // Account for the Chrome Home bottom sheet when making this decision. If the bottom sheet - // is being used, Contextual Search will show in place of the toolbar. This means that the - // Android view needs to be hidden immediately when the Contextual Search bar starts - // peeking. - return (mActivity != null && mActivity.getBottomSheet() != null && isShowing()) - || super.shouldHideAndroidBrowserControls(); - } - - @Override protected boolean doesMatchFullWidthCriteria(float containerWidth) { if (!mOverrideIsFullWidthSizePanelForTesting && mActivity != null && mActivity.getBottomSheet() != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java index ebae316..b0f800d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java
@@ -67,6 +67,9 @@ /** Whether composited UI is currently showing (such as Contextual Search). */ private boolean mIsCompositedUIShowing; + /** Whether the bottom sheet is temporarily suppressed. */ + private boolean mIsSuppressed; + /** * Build a new controller of the bottom sheet. * @param tabModelSelector A tab model selector to track events on tabs open in the browser. @@ -141,11 +144,10 @@ public void onSceneChange(Layout layout) { // If the tab did not change, reshow the existing content. Once the tab actually // changes, existing content and requests will be cleared. - if (canShowInLayout(layout) && mWasShownForCurrentTab && !mBottomSheet.isSheetOpen() - && mBottomSheet.getCurrentSheetContent() != null) { - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); + if (canShowInLayout(layout)) { + unsuppressSheet(); } else if (!canShowInLayout(layout)) { - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HIDDEN, false); + suppressSheet(StateChangeReason.COMPOSITED_UI); } } }); @@ -187,29 +189,19 @@ // TODO(mdjones): This should be changed to a generic OverlayPanel observer. if (contextualSearchManager != null) { contextualSearchManager.addObserver(new ContextualSearchObserver() { - /** Whether the bottom sheet was showing prior to contextual search appearing. */ - private boolean mWasSheetShowing; - @Override public void onShowContextualSearch( @Nullable GSAContextDisplaySelection selectionContext) { // Contextual Search can call this method more than once per show event. if (mIsCompositedUIShowing) return; - mWasSheetShowing = mBottomSheet.getSheetState() == BottomSheet.SHEET_STATE_PEEK; mIsCompositedUIShowing = true; - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HIDDEN, false, - BottomSheet.StateChangeReason.COMPOSITED_UI); + suppressSheet(StateChangeReason.COMPOSITED_UI); } @Override public void onHideContextualSearch() { mIsCompositedUIShowing = false; - if (mBottomSheet.getCurrentSheetContent() != null && mWasSheetShowing) { - mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); - } else { - showNextContent(); - } - mWasSheetShowing = false; + unsuppressSheet(); } }); } @@ -220,6 +212,35 @@ } /** + * Temporarily suppress the bottom sheet while other UI is showing. This will not itself change + * the content displayed by the sheet. + * @param reason The reason the sheet was suppressed. + */ + private void suppressSheet(@StateChangeReason int reason) { + mIsSuppressed = true; + mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HIDDEN, false, reason); + } + + /** + * Unsuppress the bottom sheet. This may or may not affect the sheet depending on the state of + * the browser (i.e. the tab switcher may be showing). + */ + private void unsuppressSheet() { + if (!mIsSuppressed || !canShowInLayout(mLayoutManager.getActiveLayout()) + || !mWasShownForCurrentTab || isOtherUIObscuring()) { + return; + } + mIsSuppressed = false; + + if (mBottomSheet.getCurrentSheetContent() != null) { + mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); + } else { + // In the event the previous content was hidden, try to show the next one. + showNextContent(); + } + } + + /** * @return The {@link BottomSheet} controlled by this class. */ public BottomSheet getBottomSheet() {
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index bbdccf2e..32870e3 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-68.0.3401.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-68.0.3402.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 902a7fdd..486087ee 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -129,9 +129,15 @@ </message> <!-- MultiDevice setup dialog. --> - <message name="IDS_MULTIDEVICE_SETUP_DIALOG_TITLE" desc="Title for the MultiDevice setup dialog, which allows users to enable features which involve communication between multiple devices (e.g., a Chromebook and a phone)."> + <message name="IDS_MULTIDEVICE_SETUP_DIALOG_TITLE" desc="Title for the MultiDevice setup dialog, which allows users to enable features which involve communication between multiple devices (e.g., a Chromebook and a phone)." translateable="false"> MultiDevice Setup </message> + <message name="IDS_MULTIDEVICE_SETUP_ACCEPT_LABEL" desc="Label for button to accept conditions and begin MultiDevice setup workflow."> + Accept + </message> + <message name="IDS_MULTIDEVICE_SETUP_TRY_AGAIN_LABEL" desc="Label for button to retry setup upon failure."> + Try again + </message> <!-- File Manager --> <message name="IDS_FILE_SYSTEM_PROVIDER_UNRESPONSIVE_WARNING" desc="A warning shown in a notification that an operation is taking longer than expected."> @@ -1299,6 +1305,9 @@ <message name="IDS_FILE_BROWSER_FAILED_SPACE_INFO" desc="Menu item, saying that FileBrowser is failed to retrieve space information."> Failed to retrieve space info </message> + <message name="IDS_FILE_BROWSER_SEE_MENU_FOR_ACTIONS" desc="Text to be used by screen reader to indicate users that there are more options on the action bar."> + More options available on the action bar. Press Alt + A to focus the action bar. + </message> <!-- Common for Audio player and Media player --> <message name="IDS_MEDIA_PLAYER_PLAY_BUTTON_LABEL" desc="Label for the Play button of media players (audio player / video player)."> @@ -3595,7 +3604,7 @@ Install critical update </message> <message name="IDS_ENCRYPTION_MIGRATION_READY_DESCRIPTION" desc="Description shown in encryption migration screen, which asks the user to install an OS update."> - To download and use Android apps, first you need to install this required update. While your Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is updating, you can’t use it. After installation completes, your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> will restart. + To download and use Android apps, first you need to install this required update. While your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is updating, you can’t use it. After installation completes, your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> will restart. </message> <message name="IDS_ENCRYPTION_MIGRATION_MIGRATING_TITLE" desc="Title shown in encryption migration screen when the migration is ongoing."> Installing OS update
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c98b318..dbe7888 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4884,11 +4884,6 @@ usage statistics </message> - <!-- Unimplemented Flags Infobar--> - <message name="IDS_UNIMPLEMENTED_FLAGS_WARNING_MESSAGE" desc="Message shown when a command-line flag is used that is not implemented by this build. [Keep it short so it fits in the infobar.]"> - <ph name="BAD_FLAG">$1<ex>--enable-heap-profiling</ex></ph> is not implemented in this build - </message> - <!-- Bad Flags Infobar--> <message name="IDS_BAD_FLAGS_WARNING_MESSAGE" desc="Message shown when an unsupported command-line flag is used. [Keep it short so it fits in the infobar.]"> You are using an unsupported command-line flag: <ph name="BAD_FLAG">$1<ex>--no-sandbox</ex></ph>. Stability and security will suffer.
diff --git a/chrome/app/theme/chrome_unscaled_resources.grd b/chrome/app/theme/chrome_unscaled_resources.grd index 383d4821..9b89ae3b 100644 --- a/chrome/app/theme/chrome_unscaled_resources.grd +++ b/chrome/app/theme/chrome_unscaled_resources.grd
@@ -111,6 +111,11 @@ <include name="IDR_APPS_FOLDER_OVERLAY_128" file="mac/apps_folder_overlay_128.png" type="BINDATA" /> <include name="IDR_APPS_FOLDER_OVERLAY_512" file="mac/apps_folder_overlay_512.png" type="BINDATA" /> </if> + <if expr="chromeos"> + <!-- Crostini icons --> + <include name="IDR_LOGO_CROSTINI_TERMINAL" file="crostini/logo_crostini_terminal.png" type="BINDATA" /> + <include name="IDR_LOGO_CROSTINI_DEFAULT" file="crostini/logo_crostini_default.png" type="BINDATA" /> + </if> </includes> </release> </grit>
diff --git a/chrome/app/theme/crostini/logo_crostini_default.png b/chrome/app/theme/crostini/logo_crostini_default.png new file mode 100644 index 0000000..6c78bef --- /dev/null +++ b/chrome/app/theme/crostini/logo_crostini_default.png Binary files differ
diff --git a/ash/resources/default_100_percent/cros/crostini/logo_crostini_terminal.png b/chrome/app/theme/crostini/logo_crostini_terminal.png similarity index 100% rename from ash/resources/default_100_percent/cros/crostini/logo_crostini_terminal.png rename to chrome/app/theme/crostini/logo_crostini_terminal.png Binary files differ
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 8bf20a2..c4062ea 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -967,16 +967,6 @@ arraysize(kPersistentMenuItemEnabled), nullptr}}; #endif // OS_ANDROID -const FeatureEntry::Choice kEnableHeapProfilingChoices[] = { - {flags_ui::kGenericExperimentChoiceDisabled, "", ""}, - {flag_descriptions::kEnableHeapProfilingModePseudo, - switches::kEnableHeapProfiling, switches::kEnableHeapProfilingModePseudo}, - {flag_descriptions::kEnableHeapProfilingModeNative, - switches::kEnableHeapProfiling, switches::kEnableHeapProfilingModeNative}, - {flag_descriptions::kEnableHeapProfilingTaskProfiler, - switches::kEnableHeapProfiling, - switches::kEnableHeapProfilingTaskProfiler}}; - const FeatureEntry::Choice kEnableOutOfProcessHeapProfilingChoices[] = { {flags_ui::kGenericExperimentChoiceDisabled, "", ""}, {flag_descriptions::kEnableOutOfProcessHeapProfilingModeMinimal, @@ -3196,10 +3186,6 @@ flag_descriptions::kSamplingHeapProfilerDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kSamplingHeapProfiler)}, - {"enable-heap-profiling", flag_descriptions::kEnableHeapProfilingName, - flag_descriptions::kEnableHeapProfilingDescription, kOsAll, - MULTI_VALUE_TYPE(kEnableHeapProfilingChoices)}, - {"memlog", flag_descriptions::kEnableOutOfProcessHeapProfilingName, flag_descriptions::kEnableOutOfProcessHeapProfilingDescription, kOsAll, MULTI_VALUE_TYPE(kEnableOutOfProcessHeapProfilingChoices)},
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h index adf019c..f843d1f 100644 --- a/chrome/browser/app_controller_mac.h +++ b/chrome/browser/app_controller_mac.h
@@ -182,6 +182,10 @@ // different models of application lifetime. bool IsOpeningNewWindow(); +// Create a guest profile if one is needed. Afterwards, even if the profile +// already existed, notify the AppController of the profile in use. +void CreateGuestProfileIfNeeded(); + } // namespace app_controller_mac #endif // CHROME_BROWSER_APP_CONTROLLER_MAC_H_
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 17e4527..7602fe5 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -1716,10 +1716,29 @@ //--------------------------------------------------------------------------- +namespace { + +void UpdateProfileInUse(Profile* profile, Profile::CreateStatus status) { + if (status == Profile::CREATE_STATUS_INITIALIZED) { + AppController* controller = + base::mac::ObjCCastStrict<AppController>([NSApp delegate]); + [controller windowChangedToProfile:profile]; + } +} + +} // namespace + namespace app_controller_mac { bool IsOpeningNewWindow() { return g_is_opening_new_window; } +void CreateGuestProfileIfNeeded() { + g_browser_process->profile_manager()->CreateProfileAsync( + ProfileManager::GetGuestProfilePath(), + base::BindRepeating(&UpdateProfileInUse), base::string16(), std::string(), + std::string()); +} + } // namespace app_controller_mac
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 9b41510f..78e6f3e 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -4729,3 +4729,21 @@ &cookie_is_correct)); EXPECT_TRUE(cookie_is_correct); } + +// Sends an auto-resize message to the RenderWidgetHost and ensures that the +// auto-resize transaction is handled and produces a single response message +// from guest to embedder. +IN_PROC_BROWSER_TEST_P(WebViewTest, AutoResizeMessages) { + LoadAppWithGuest("web_view/simple"); + content::WebContents* embedder = GetEmbedderWebContents(); + content::WebContents* guest = GetGuestWebContents(); + bool is_guest = + !base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames); + + // Helper function as this test requires inspecting a number of content:: + // internal objects. + EXPECT_TRUE(content::TestChildOrGuestAutoresize( + is_guest, + embedder->GetRenderWidgetHostView()->GetRenderWidgetHost()->GetProcess(), + guest->GetRenderWidgetHostView()->GetRenderWidgetHost())); +}
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index f390d84..52949a95 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -8,9 +8,6 @@ </outputs> <release seq="1"> <structures> - <if expr="enable_extensions"> - <structure name="IDR_EXTENSIONS_HTML" file="resources\extensions\extensions.html" flattenhtml="true" type="chrome_html" /> - </if> <if expr="chromeos"> <structure name="IDR_FIRST_RUN_HTML" file="resources\chromeos\first_run\first_run.html" flattenhtml="true" type="chrome_html"/> <structure name="IDR_FIRST_RUN_JS" file="resources\chromeos\first_run\first_run.js" flattenhtml="true" type="chrome_html" /> @@ -171,11 +168,6 @@ </else> </if> </if> - <if expr="enable_extensions"> - <include name="IDR_EXTENSION_COMMAND_LIST_JS" file="resources\extensions\extension_command_list.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_EXTENSION_LIST_JS" file="resources\extensions\extension_list.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_EXTENSIONS_JS" file="resources\extensions\extensions.js" flattenhtml="true" type="BINDATA" /> - </if> <include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" /> <if expr="is_android"> <include name="IDR_OFFLINE_INTERNALS_HTML" file="resources\offline_pages\offline_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 08f752f2..e60e3c5 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -509,6 +509,8 @@ "crostini/crostini_registry_service.h", "crostini/crostini_registry_service_factory.cc", "crostini/crostini_registry_service_factory.h", + "crostini/crostini_util.cc", + "crostini/crostini_util.h", "cryptauth/chrome_cryptauth_service.cc", "cryptauth/chrome_cryptauth_service.h", "cryptauth/chrome_cryptauth_service_factory.cc", @@ -549,8 +551,6 @@ "display/output_protection_delegate.h", "display/quirks_manager_delegate_impl.cc", "display/quirks_manager_delegate_impl.h", - "docked_magnifier/docked_magnifier_client.cc", - "docked_magnifier/docked_magnifier_client.h", "drive/debug_info_collector.cc", "drive/debug_info_collector.h", "drive/download_handler.cc", @@ -1835,7 +1835,6 @@ "../metrics/perf/random_selector_unittest.cc", "../policy/default_geolocation_policy_handler_unittest.cc", "../ui/browser_finder_chromeos_unittest.cc", - "accessibility/magnification_manager_unittest.cc", "accessibility/select_to_speak_event_handler_unittest.cc", "accessibility/spoken_feedback_event_rewriter_unittest.cc", "app_mode/startup_app_launcher_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.cc b/chrome/browser/chromeos/accessibility/magnification_manager.cc index b972efb5..a902d2d6 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager.cc +++ b/chrome/browser/chromeos/accessibility/magnification_manager.cc
@@ -8,7 +8,9 @@ #include <memory> #include "ash/magnifier/magnification_controller.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_pref_names.h" +#include "ash/public/interfaces/constants.mojom.h" #include "ash/shell.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" @@ -22,6 +24,8 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" namespace chromeos { @@ -48,7 +52,7 @@ } bool MagnificationManager::IsMagnifierEnabled() const { - return enabled_; + return fullscreen_magnifier_enabled_; } void MagnificationManager::SetMagnifierEnabled(bool enabled) { @@ -87,6 +91,18 @@ content::NotificationService::AllSources()); registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, content::NotificationService::AllSources()); + // TODO(warx): observe focus changed in page notification when either + // fullscreen magnifier or docked magnifier is enabled. + registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::NotificationService::AllSources()); + + // Connect to ash's DockedMagnifierController interface. + if (ash::features::IsDockedMagnifierEnabled()) { + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(ash::mojom::kServiceName, + &docked_magnifier_controller_); + } } MagnificationManager::~MagnificationManager() { @@ -122,10 +138,7 @@ break; } case content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE: { - content::FocusedNodeDetails* node_details = - content::Details<content::FocusedNodeDetails>(details).ptr(); - ash::Shell::Get()->magnification_controller()->HandleFocusedNodeChanged( - node_details->is_editable_node, node_details->node_bounds_in_screen); + HandleFocusChangedInPage(details); break; } } @@ -168,13 +181,12 @@ // even if |enabled| is unchanged. Only if |enabled| is false and the // magnifier is already disabled, we are sure that we don't need to reflect // the new settings right now because the magnifier keeps disabled. - if (!enabled && !enabled_) + if (!enabled && !fullscreen_magnifier_enabled_) return; - enabled_ = enabled; + fullscreen_magnifier_enabled_ = enabled; - ash::Shell::Get()->magnification_controller()->SetEnabled(enabled_); - MonitorFocusInPageChange(); + ash::Shell::Get()->magnification_controller()->SetEnabled(enabled); } void MagnificationManager::SetMagnifierKeepFocusCenteredInternal( @@ -221,7 +233,7 @@ } AccessibilityStatusEventDetails details(ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER, - enabled_); + fullscreen_magnifier_enabled_); if (!AccessibilityManager::Get()) return; @@ -230,16 +242,36 @@ ash::Shell::Get()->UpdateCursorCompositingEnabled(); } -void MagnificationManager::MonitorFocusInPageChange() { - if (enabled_ && !observing_focus_change_in_page_) { - registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources()); - observing_focus_change_in_page_ = true; - } else if (!enabled_ && observing_focus_change_in_page_) { - registrar_.Remove(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources()); - observing_focus_change_in_page_ = false; +void MagnificationManager::HandleFocusChangedInPage( + const content::NotificationDetails& details) { + const bool docked_magnifier_enabled = + ash::features::IsDockedMagnifierEnabled() && profile_ && + profile_->GetPrefs()->GetBoolean(ash::prefs::kDockedMagnifierEnabled); + if (!fullscreen_magnifier_enabled_ && !docked_magnifier_enabled) + return; + + content::FocusedNodeDetails* node_details = + content::Details<content::FocusedNodeDetails>(details).ptr(); + // Ash uses the InputMethod of the window tree host to observe text input + // caret bounds changes, which works for both the native UI as well as + // webpages. We don't need to notify it of editable nodes in this case. + if (node_details->is_editable_node) + return; + + const gfx::Rect& bounds_in_screen = node_details->node_bounds_in_screen; + if (bounds_in_screen.IsEmpty()) + return; + + // Fullscreen magnifier and docked magnifier are mutually exclusive. + if (fullscreen_magnifier_enabled_) { + ash::Shell::Get()->magnification_controller()->HandleFocusedNodeChanged( + node_details->is_editable_node, node_details->node_bounds_in_screen); + return; } + DCHECK(docked_magnifier_enabled); + // Called when docked magnifier feature is enabled to avoid unnecessary + // mojo IPC to ash. + docked_magnifier_controller_->CenterOnPoint(bounds_in_screen.CenterPoint()); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.h b/chrome/browser/chromeos/accessibility/magnification_manager.h index 5ac5b87..c6ab3ff0 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager.h +++ b/chrome/browser/chromeos/accessibility/magnification_manager.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_MAGNIFICATION_MANAGER_H_ #define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_MAGNIFICATION_MANAGER_H_ +#include "ash/public/interfaces/docked_magnifier_controller.mojom.h" #include "base/macros.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/notification_observer.h" @@ -15,14 +16,18 @@ namespace chromeos { -// MagnificationManager controls the full screen magnifier from chrome-browser -// side (not ash side). +// MagnificationManager controls the Fullscreen and Docked magnifier from +// chrome-browser side (not ash side). // -// MagnificationManager does: +// MagnificationManager does below for Fullscreen magnifier: +// TODO(warx): Move to ash. // - Watch logged-in. Changes the behavior between the login screen and user // desktop. // - Watch change of the pref. When the pref changes, the setting of the // magnifier will interlock with it. +// +// MagnificationManager also observes focus changed in page and calls Ash when +// either Fullscreen or Docked magnifier is enabled. class MagnificationManager : public content::NotificationObserver, public user_manager::UserManager::UserSessionStateObserver { @@ -36,16 +41,16 @@ // Returns the existing instance. If there is no instance, returns NULL. static MagnificationManager* Get(); - // Returns if the screen magnifier is enabled. + // Returns if the Fullscreen magnifier is enabled. bool IsMagnifierEnabled() const; - // Enables the screen magnifier. + // Enables the Fullscreen magnifier. void SetMagnifierEnabled(bool enabled); - // Saves the magnifier scale to the pref. + // Saves the Fullscreen magnifier scale to the pref. void SaveScreenMagnifierScale(double scale); - // Loads the magnifier scale from the pref. + // Loads the Fullscreen magnifier scale from the pref. double GetSavedScreenMagnifierScale() const; void SetProfileForTest(Profile* profile); @@ -69,20 +74,23 @@ void SetMagnifierScaleInternal(double scale); void UpdateMagnifierFromPrefs(); - void MonitorFocusInPageChange(); + // Called when received content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE. + void HandleFocusChangedInPage(const content::NotificationDetails& details); Profile* profile_ = nullptr; - bool enabled_ = false; + bool fullscreen_magnifier_enabled_ = false; bool keep_focus_centered_ = false; double scale_ = 0.0; - bool observing_focus_change_in_page_ = false; content::NotificationRegistrar registrar_; std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; std::unique_ptr<user_manager::ScopedUserSessionStateObserver> session_state_observer_; + // Ash's mojom::DockedMagnifierController used to request Ash's a11y feature. + ash::mojom::DockedMagnifierControllerPtr docked_magnifier_controller_; + DISALLOW_COPY_AND_ASSIGN(MagnificationManager); };
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc deleted file mode 100644 index 37c8587..0000000 --- a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/accessibility/magnification_manager.h" - -#include "ash/public/cpp/accessibility_types.h" -#include "ash/test/ash_test_base.h" -#include "chrome/test/base/testing_profile.h" -#include "components/prefs/pref_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { -namespace { - -void EnableMagnifier() { - return MagnificationManager::Get()->SetMagnifierEnabled(true); -} - -void DisableMagnifier() { - return MagnificationManager::Get()->SetMagnifierEnabled(false); -} - -bool IsMagnifierEnabled() { - return MagnificationManager::Get()->IsMagnifierEnabled(); -} - -} // namespace - -class MagnificationManagerTest : public ash::AshTestBase { - public: - MagnificationManagerTest() = default; - ~MagnificationManagerTest() override = default; - - void SetUp() override { - ash::AshTestBase::SetUp(); - MagnificationManager::Initialize(); - ASSERT_TRUE(MagnificationManager::Get()); - MagnificationManager::Get()->SetProfileForTest(&profile_); - } - - void TearDown() override { - MagnificationManager::Shutdown(); - ash::AshTestBase::TearDown(); - } - - TestingProfile profile_; -}; - -TEST_F(MagnificationManagerTest, EnableDisable) { - // Set full screen magnifier, and confirm the status is set successfully. - EnableMagnifier(); - EXPECT_TRUE(IsMagnifierEnabled()); - - // Disables magnifier, and confirm the status is set successfully. - DisableMagnifier(); - EXPECT_FALSE(IsMagnifierEnabled()); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 435e9e8..ca1132d 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -220,8 +220,7 @@ network_portal_detector::SetNetworkPortalDetector( new NetworkPortalDetectorImpl( g_browser_process->system_network_context_manager() - ->GetURLLoaderFactory(), - true)); + ->GetURLLoaderFactory())); } }
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc index ac7420b..a0da72e 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -9,10 +9,10 @@ #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/component_updater/cros_component_installer.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/extensions/application_launch.h" #include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -40,6 +40,12 @@ return container_username.substr(0, container_username.find('@')); } +std::string CryptohomeIdForProfile(Profile* profile) { + std::string id = chromeos::ProfileHelper::GetUserIdHashFromProfile(profile); + // Empty id means we're running in a test. + return id.empty() ? "test" : id; +} + class CrostiniRestarter : public base::RefCountedThreadSafe<CrostiniRestarter> { public: CrostiniRestarter(std::string vm_name, @@ -51,15 +57,51 @@ cryptohome_id_(std::move(cryptohome_id)), container_name_(std::move(container_name)), container_username_(std::move(container_username)), - callback_(std::move(callback)) {} + callback_(std::move(callback)), + restart_id_(next_restart_id_) { + restarter_map_[next_restart_id_++] = base::WrapRefCounted(this); + } void Restart() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - g_browser_process->platform_part()->cros_component_manager()->Load( - "cros-termina", - component_updater::CrOSComponentManager::MountPolicy::kMount, - base::BindOnce(&CrostiniRestarter::InstallImageLoaderFinished, - base::WrapRefCounted(this))); + if (is_aborted_) + return; + auto* cros_component_manager = + g_browser_process->platform_part()->cros_component_manager(); + if (cros_component_manager) { + g_browser_process->platform_part()->cros_component_manager()->Load( + "cros-termina", + component_updater::CrOSComponentManager::MountPolicy::kMount, + base::BindOnce(&CrostiniRestarter::InstallImageLoaderFinished, + base::WrapRefCounted(this))); + } else { + // Running in test. + InstallImageLoaderFinishedOnUIThread( + component_updater::CrOSComponentManager::Error::NONE, + base::FilePath()); + } + } + + void AddObserver(CrostiniManager::RestartObserver* observer) { + observer_list_.AddObserver(observer); + } + + CrostiniManager::RestartId GetRestartId() { return restart_id_; } + + static void Abort(CrostiniManager::RestartId restart_id) { + auto it = restarter_map_.find(restart_id); + if (it != restarter_map_.end()) { + it->second->is_aborted_ = true; + restarter_map_.erase(it); + } + } + + void UnrefAndRunCallback(ConciergeClientResult result) { + auto it = restarter_map_.find(restart_id_); + if (it != restarter_map_.end()) { + restarter_map_.erase(it); + } + std::move(callback_).Run(result); } private: @@ -76,6 +118,8 @@ component_updater::CrOSComponentManager::Error error, const base::FilePath& result) { DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (restarter->is_aborted_) + return; content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, base::BindOnce(&CrostiniRestarter::InstallImageLoaderFinishedOnUIThread, @@ -85,11 +129,21 @@ void InstallImageLoaderFinishedOnUIThread( component_updater::CrOSComponentManager::Error error, const base::FilePath& result) { - if (error != component_updater::CrOSComponentManager::Error::NONE) { + ConciergeClientResult client_result = + error == component_updater::CrOSComponentManager::Error::NONE + ? ConciergeClientResult::SUCCESS + : ConciergeClientResult::CONTAINER_START_FAILED; + // Tell observers. + for (auto& observer : observer_list_) { + observer.OnComponentLoaded(client_result); + } + if (is_aborted_) + return; + if (client_result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to install the cros-termina component with error code: " << static_cast<int>(error); - std::move(callback_).Run(ConciergeClientResult::CONTAINER_START_FAILED); + UnrefAndRunCallback(client_result); return; } CrostiniManager::GetInstance()->StartVmConcierge( @@ -98,9 +152,18 @@ void ConciergeStarted(bool is_started) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + ConciergeClientResult client_result = + is_started ? ConciergeClientResult::SUCCESS + : ConciergeClientResult::CONTAINER_START_FAILED; + // Tell observers. + for (auto& observer : observer_list_) { + observer.OnConciergeStarted(client_result); + } + if (is_aborted_) + return; if (!is_started) { LOG(ERROR) << "Failed to start Concierge service."; - std::move(callback_).Run(ConciergeClientResult::CONTAINER_START_FAILED); + UnrefAndRunCallback(client_result); return; } CrostiniManager::GetInstance()->CreateDiskImage( @@ -112,9 +175,15 @@ void CreateDiskImageFinished(ConciergeClientResult result, const base::FilePath& result_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // Tell observers. + for (auto& observer : observer_list_) { + observer.OnDiskImageCreated(result); + } + if (is_aborted_) + return; if (result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to create disk image."; - std::move(callback_).Run(result); + UnrefAndRunCallback(result); return; } CrostiniManager::GetInstance()->StartTerminaVm( @@ -124,9 +193,15 @@ void StartTerminaVmFinished(ConciergeClientResult result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // Tell observers. + for (auto& observer : observer_list_) { + observer.OnVmStarted(result); + } + if (is_aborted_) + return; if (result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to Start Termina VM."; - std::move(callback_).Run(result); + UnrefAndRunCallback(result); return; } CrostiniManager::GetInstance()->StartContainer( @@ -139,7 +214,9 @@ if (result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to start container."; } - std::move(callback_).Run(result); + if (is_aborted_) + return; + UnrefAndRunCallback(result); } std::string vm_name_; @@ -147,8 +224,19 @@ std::string container_name_; std::string container_username_; CrostiniManager::RestartCrostiniCallback callback_; + base::ObserverList<CrostiniManager::RestartObserver> observer_list_; + CrostiniManager::RestartId restart_id_; + bool is_aborted_ = false; + + static CrostiniManager::RestartId next_restart_id_; + static std::map<CrostiniManager::RestartId, scoped_refptr<CrostiniRestarter>> + restarter_map_; }; +CrostiniManager::RestartId CrostiniRestarter::next_restart_id_ = 0; +std::map<CrostiniManager::RestartId, scoped_refptr<CrostiniRestarter>> + CrostiniRestarter::restarter_map_; + } // namespace // static @@ -439,20 +527,29 @@ OpenApplicationWindow(launch_params, vsh_in_crosh_url); } -void CrostiniManager::RestartCrostini(Profile* profile, - std::string vm_name, - std::string container_name, - RestartCrostiniCallback callback) { +CrostiniManager::RestartId CrostiniManager::RestartCrostini( + Profile* profile, + std::string vm_name, + std::string container_name, + RestartCrostiniCallback callback, + RestartObserver* observer) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - std::string cryptohome_id = chromeos::ProfileHelper::Get() - ->GetUserByProfile(profile) - ->username_hash(); + std::string cryptohome_id = CryptohomeIdForProfile(profile); std::string container_username = ContainerUserNameForProfile(profile); auto crostini_restarter = base::MakeRefCounted<CrostiniRestarter>( std::move(vm_name), std::move(cryptohome_id), std::move(container_name), std::move(container_username), std::move(callback)); + if (observer) { + crostini_restarter->AddObserver(observer); + } crostini_restarter->Restart(); + return crostini_restarter->GetRestartId(); +} + +void CrostiniManager::AbortRestartCrostini( + CrostiniManager::RestartId restart_id) { + CrostiniRestarter::Abort(restart_id); } void CrostiniManager::OnCreateDiskImage( @@ -591,7 +688,6 @@ ConciergeClientResult::LAUNCH_CONTAINER_APPLICATION_FAILED); return; } - std::move(callback).Run(ConciergeClientResult::SUCCESS); }
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h index e50290d..26745073 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.h +++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -65,6 +65,15 @@ using RestartCrostiniCallback = base::OnceCallback<void(ConciergeClientResult result)>; + // Observer class for the Crostini restart flow. + class RestartObserver { + public: + virtual void OnComponentLoaded(ConciergeClientResult result) = 0; + virtual void OnConciergeStarted(ConciergeClientResult result) = 0; + virtual void OnDiskImageCreated(ConciergeClientResult result) = 0; + virtual void OnVmStarted(ConciergeClientResult result) = 0; + }; + // Checks if the cros-termina component is installed. static bool IsCrosTerminaInstalled(); @@ -127,8 +136,6 @@ // Asynchronously launches an app as specified by its desktop file id. // |callback| is called with SUCCESS when the relevant process is started // or LAUNCH_CONTAINER_APPLICATION_FAILED if there was an error somewhere. - // - // TODO(nverne): Start the VM and Container if not already running. void LaunchContainerApplication(std::string vm_name, std::string container_name, std::string desktop_file_id, @@ -140,10 +147,17 @@ const std::string& vm_name, const std::string& container_name); - void RestartCrostini(Profile* profile, - std::string vm_name, - std::string container_name, - RestartCrostiniCallback callback); + using RestartId = int; + static const RestartId kUninitializedRestartId = -1; + // Runs all the steps required to restart the given crostini vm and container. + // The optional |observer| tracks progress. + RestartId RestartCrostini(Profile* profile, + std::string vm_name, + std::string container_name, + RestartCrostiniCallback callback, + RestartObserver* observer = nullptr); + + void AbortRestartCrostini(RestartId id); // ConciergeClient::Observer: void OnContainerStarted(
diff --git a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc index 46ebc23..afc411dc 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
@@ -7,8 +7,10 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" +#include "chrome/test/base/testing_profile.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_concierge_client.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace crostini { @@ -21,79 +23,77 @@ class CrostiniManagerTest : public testing::Test { public: - void CreateDiskImageClientErrorCallback( - base::OnceClosure closure, - crostini::ConciergeClientResult result, - const base::FilePath& file_path) { + void CreateDiskImageClientErrorCallback(base::OnceClosure closure, + ConciergeClientResult result, + const base::FilePath& file_path) { EXPECT_FALSE(fake_concierge_client_->create_disk_image_called()); - EXPECT_EQ(result, crostini::ConciergeClientResult::CLIENT_ERROR); + EXPECT_EQ(result, ConciergeClientResult::CLIENT_ERROR); std::move(closure).Run(); } - void DestroyDiskImageClientErrorCallback( - base::OnceClosure closure, - crostini::ConciergeClientResult result) { + void DestroyDiskImageClientErrorCallback(base::OnceClosure closure, + ConciergeClientResult result) { EXPECT_FALSE(fake_concierge_client_->destroy_disk_image_called()); - EXPECT_EQ(result, crostini::ConciergeClientResult::CLIENT_ERROR); + EXPECT_EQ(result, ConciergeClientResult::CLIENT_ERROR); std::move(closure).Run(); } - void StartTerminaVmClientErrorCallback( - base::OnceClosure closure, - crostini::ConciergeClientResult result) { + void StartTerminaVmClientErrorCallback(base::OnceClosure closure, + ConciergeClientResult result) { EXPECT_FALSE(fake_concierge_client_->start_termina_vm_called()); - EXPECT_EQ(result, crostini::ConciergeClientResult::CLIENT_ERROR); + EXPECT_EQ(result, ConciergeClientResult::CLIENT_ERROR); std::move(closure).Run(); } void StopVmClientErrorCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { EXPECT_FALSE(fake_concierge_client_->stop_vm_called()); - EXPECT_EQ(result, crostini::ConciergeClientResult::CLIENT_ERROR); + EXPECT_EQ(result, ConciergeClientResult::CLIENT_ERROR); std::move(closure).Run(); } - void StartContainerClientErrorCallback( - base::OnceClosure closure, - crostini::ConciergeClientResult result) { + void StartContainerClientErrorCallback(base::OnceClosure closure, + ConciergeClientResult result) { EXPECT_FALSE(fake_concierge_client_->start_container_called()); - EXPECT_EQ(result, crostini::ConciergeClientResult::CLIENT_ERROR); + EXPECT_EQ(result, ConciergeClientResult::CLIENT_ERROR); std::move(closure).Run(); } void CreateDiskImageSuccessCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result, + ConciergeClientResult result, const base::FilePath& file_path) { EXPECT_TRUE(fake_concierge_client_->create_disk_image_called()); std::move(closure).Run(); } void DestroyDiskImageSuccessCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { EXPECT_TRUE(fake_concierge_client_->destroy_disk_image_called()); std::move(closure).Run(); } void StartTerminaVmSuccessCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called()); std::move(closure).Run(); } void StopVmSuccessCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { EXPECT_TRUE(fake_concierge_client_->stop_vm_called()); std::move(closure).Run(); } void StartContainerSuccessCallback(base::OnceClosure closure, - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { EXPECT_TRUE(fake_concierge_client_->start_container_called()); std::move(closure).Run(); } CrostiniManagerTest() - : fake_concierge_client_(new chromeos::FakeConciergeClient()) { + : fake_concierge_client_(new chromeos::FakeConciergeClient()), + scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::UI) { chromeos::DBusThreadManager::GetSetterForTesting()->SetConciergeClient( base::WrapUnique(fake_concierge_client_)); chromeos::DBusThreadManager::Initialize(); @@ -112,7 +112,7 @@ TEST_F(CrostiniManagerTest, CreateDiskImageNameError) { const base::FilePath& disk_path = base::FilePath(""); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->CreateDiskImage( + CrostiniManager::GetInstance()->CreateDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_ROOT, base::BindOnce(&CrostiniManagerTest::CreateDiskImageClientErrorCallback, @@ -123,7 +123,7 @@ TEST_F(CrostiniManagerTest, CreateDiskImageCryptohomeError) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->CreateDiskImage( + CrostiniManager::GetInstance()->CreateDiskImage( "", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_ROOT, base::BindOnce(&CrostiniManagerTest::CreateDiskImageClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -133,7 +133,7 @@ TEST_F(CrostiniManagerTest, CreateDiskImageStorageLocationError) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->CreateDiskImage( + CrostiniManager::GetInstance()->CreateDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::StorageLocation_INT_MIN_SENTINEL_DO_NOT_USE_, base::BindOnce(&CrostiniManagerTest::CreateDiskImageClientErrorCallback, @@ -144,7 +144,7 @@ TEST_F(CrostiniManagerTest, CreateDiskImageSuccess) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->CreateDiskImage( + CrostiniManager::GetInstance()->CreateDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_DOWNLOADS, base::BindOnce(&CrostiniManagerTest::CreateDiskImageSuccessCallback, @@ -155,7 +155,7 @@ TEST_F(CrostiniManagerTest, DestroyDiskImageNameError) { const base::FilePath& disk_path = base::FilePath(""); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->DestroyDiskImage( + CrostiniManager::GetInstance()->DestroyDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_ROOT, base::BindOnce(&CrostiniManagerTest::DestroyDiskImageClientErrorCallback, @@ -166,7 +166,7 @@ TEST_F(CrostiniManagerTest, DestroyDiskImageCryptohomeError) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->DestroyDiskImage( + CrostiniManager::GetInstance()->DestroyDiskImage( "", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_ROOT, base::BindOnce(&CrostiniManagerTest::DestroyDiskImageClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -176,7 +176,7 @@ TEST_F(CrostiniManagerTest, DestroyDiskImageStorageLocationError) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->DestroyDiskImage( + CrostiniManager::GetInstance()->DestroyDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::StorageLocation_INT_MIN_SENTINEL_DO_NOT_USE_, base::BindOnce(&CrostiniManagerTest::DestroyDiskImageClientErrorCallback, @@ -187,7 +187,7 @@ TEST_F(CrostiniManagerTest, DestroyDiskImageSuccess) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->DestroyDiskImage( + CrostiniManager::GetInstance()->DestroyDiskImage( "i_dont_know_what_cryptohome_id_is", disk_path, vm_tools::concierge::STORAGE_CRYPTOHOME_DOWNLOADS, base::BindOnce(&CrostiniManagerTest::DestroyDiskImageSuccessCallback, @@ -198,7 +198,7 @@ TEST_F(CrostiniManagerTest, StartTerminaVmNameError) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartTerminaVm( + CrostiniManager::GetInstance()->StartTerminaVm( "", disk_path, base::BindOnce(&CrostiniManagerTest::StartTerminaVmClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -208,7 +208,7 @@ TEST_F(CrostiniManagerTest, StartTerminaVmDiskPathError) { const base::FilePath& disk_path = base::FilePath(); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartTerminaVm( + CrostiniManager::GetInstance()->StartTerminaVm( kVmName, disk_path, base::BindOnce(&CrostiniManagerTest::StartTerminaVmClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -218,7 +218,7 @@ TEST_F(CrostiniManagerTest, StartTerminaVmSuccess) { const base::FilePath& disk_path = base::FilePath(kVmName); base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartTerminaVm( + CrostiniManager::GetInstance()->StartTerminaVm( kVmName, disk_path, base::BindOnce(&CrostiniManagerTest::StartTerminaVmSuccessCallback, base::Unretained(this), loop.QuitClosure())); @@ -227,7 +227,7 @@ TEST_F(CrostiniManagerTest, StopVmNameError) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StopVm( + CrostiniManager::GetInstance()->StopVm( "", base::BindOnce(&CrostiniManagerTest::StopVmClientErrorCallback, base::Unretained(this), loop.QuitClosure())); loop.Run(); @@ -235,7 +235,7 @@ TEST_F(CrostiniManagerTest, StopVmSuccess) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StopVm( + CrostiniManager::GetInstance()->StopVm( kVmName, base::BindOnce(&CrostiniManagerTest::StopVmSuccessCallback, base::Unretained(this), loop.QuitClosure())); loop.Run(); @@ -243,7 +243,7 @@ TEST_F(CrostiniManagerTest, StartContainerVmNameError) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartContainer( + CrostiniManager::GetInstance()->StartContainer( "", kContainerName, kContainerUserName, base::BindOnce(&CrostiniManagerTest::StartContainerClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -252,7 +252,7 @@ TEST_F(CrostiniManagerTest, StartContainerContainerNameError) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartContainer( + CrostiniManager::GetInstance()->StartContainer( kVmName, "", kContainerUserName, base::BindOnce(&CrostiniManagerTest::StartContainerClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -261,7 +261,7 @@ TEST_F(CrostiniManagerTest, StartContainerContainerUserNameError) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartContainer( + CrostiniManager::GetInstance()->StartContainer( kVmName, kContainerName, "", base::BindOnce(&CrostiniManagerTest::StartContainerClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -271,7 +271,7 @@ TEST_F(CrostiniManagerTest, StartContainerSignalNotConnectedError) { base::RunLoop loop; fake_concierge_client_->set_container_started_signal_connected(false); - crostini::CrostiniManager::GetInstance()->StartContainer( + CrostiniManager::GetInstance()->StartContainer( kVmName, kContainerName, kContainerUserName, base::BindOnce(&CrostiniManagerTest::StartContainerClientErrorCallback, base::Unretained(this), loop.QuitClosure())); @@ -280,11 +280,143 @@ TEST_F(CrostiniManagerTest, StartContainerSuccess) { base::RunLoop loop; - crostini::CrostiniManager::GetInstance()->StartContainer( + CrostiniManager::GetInstance()->StartContainer( kVmName, kContainerName, kContainerUserName, base::BindOnce(&CrostiniManagerTest::StartContainerSuccessCallback, base::Unretained(this), loop.QuitClosure())); loop.Run(); } +class CrostiniManagerRestartTest : public CrostiniManagerTest, + public CrostiniManager::RestartObserver { + public: + CrostiniManagerRestartTest() + : test_browser_thread_bundle_( + content::TestBrowserThreadBundle::REAL_IO_THREAD) {} + + void SetUp() override { + loop_ = std::make_unique<base::RunLoop>(); + profile_ = std::make_unique<TestingProfile>(); + } + + void RestartCrostiniCallback(base::OnceClosure closure, + ConciergeClientResult result) { + restart_crostini_callback_called_ = true; + std::move(closure).Run(); + } + + // CrostiniManager::RestartObserver + void OnComponentLoaded(ConciergeClientResult result) override { + if (abort_on_component_loaded_) { + Abort(); + } + } + + void OnConciergeStarted(ConciergeClientResult result) override { + if (abort_on_concierge_started_) { + Abort(); + } + } + + void OnDiskImageCreated(ConciergeClientResult result) override { + if (abort_on_disk_image_created_) { + Abort(); + } + } + + void OnVmStarted(ConciergeClientResult result) override { + if (abort_on_vm_started_) { + Abort(); + } + } + + protected: + void Abort() { + CrostiniManager::GetInstance()->AbortRestartCrostini(restart_id_); + loop_->Quit(); + } + + content::TestBrowserThreadBundle test_browser_thread_bundle_; + + CrostiniManager::RestartId restart_id_ = + CrostiniManager::kUninitializedRestartId; + bool abort_on_component_loaded_ = false; + bool abort_on_concierge_started_ = false; + bool abort_on_disk_image_created_ = false; + bool abort_on_vm_started_ = false; + bool restart_crostini_callback_called_ = false; + std::unique_ptr<base::RunLoop> + loop_; // loop_ must be created on the UI thread. + std::unique_ptr<TestingProfile> profile_; +}; + +TEST_F(CrostiniManagerRestartTest, RestartSuccess) { + restart_id_ = CrostiniManager::GetInstance()->RestartCrostini( + profile_.get(), kVmName, kContainerName, + base::BindOnce(&CrostiniManagerRestartTest::RestartCrostiniCallback, + base::Unretained(this), loop_->QuitClosure()), + this); + loop_->Run(); + EXPECT_TRUE(fake_concierge_client_->create_disk_image_called()); + EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called()); + EXPECT_TRUE(fake_concierge_client_->start_container_called()); + EXPECT_TRUE(restart_crostini_callback_called_); +} + +TEST_F(CrostiniManagerRestartTest, AbortOnComponentLoaded) { + abort_on_component_loaded_ = true; + restart_id_ = CrostiniManager::GetInstance()->RestartCrostini( + profile_.get(), kVmName, kContainerName, + base::BindOnce(&CrostiniManagerRestartTest::RestartCrostiniCallback, + base::Unretained(this), loop_->QuitClosure()), + this); + loop_->Run(); + EXPECT_FALSE(fake_concierge_client_->create_disk_image_called()); + EXPECT_FALSE(fake_concierge_client_->start_termina_vm_called()); + EXPECT_FALSE(fake_concierge_client_->start_container_called()); + EXPECT_FALSE(restart_crostini_callback_called_); +} + +TEST_F(CrostiniManagerRestartTest, AbortOnConciergeStarted) { + abort_on_concierge_started_ = true; + restart_id_ = CrostiniManager::GetInstance()->RestartCrostini( + profile_.get(), kVmName, kContainerName, + base::BindOnce(&CrostiniManagerRestartTest::RestartCrostiniCallback, + base::Unretained(this), loop_->QuitClosure()), + this); + loop_->Run(); + EXPECT_FALSE(fake_concierge_client_->create_disk_image_called()); + EXPECT_FALSE(fake_concierge_client_->start_termina_vm_called()); + EXPECT_FALSE(fake_concierge_client_->start_container_called()); + EXPECT_FALSE(restart_crostini_callback_called_); +} + +TEST_F(CrostiniManagerRestartTest, AbortOnDiskImageCreated) { + abort_on_disk_image_created_ = true; + restart_id_ = CrostiniManager::GetInstance()->RestartCrostini( + profile_.get(), kVmName, kContainerName, + base::BindOnce(&CrostiniManagerRestartTest::RestartCrostiniCallback, + base::Unretained(this), loop_->QuitClosure()), + this); + loop_->Run(); + EXPECT_TRUE(fake_concierge_client_->create_disk_image_called()); + EXPECT_FALSE(fake_concierge_client_->start_termina_vm_called()); + EXPECT_FALSE(fake_concierge_client_->start_container_called()); + EXPECT_FALSE(restart_crostini_callback_called_); +} + +TEST_F(CrostiniManagerRestartTest, AbortOnVmStarted) { + abort_on_vm_started_ = true; + restart_id_ = CrostiniManager::GetInstance()->RestartCrostini( + profile_.get(), kVmName, kContainerName, + base::BindOnce(&CrostiniManagerRestartTest::RestartCrostiniCallback, + base::Unretained(this), loop_->QuitClosure()), + this); + loop_->Run(); + EXPECT_TRUE(fake_concierge_client_->create_disk_image_called()); + EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called()); + EXPECT_FALSE(fake_concierge_client_->start_container_called()); + EXPECT_FALSE(restart_crostini_callback_called_); +} + } // namespace crostini
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc index 4b53852..966b376 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -4,8 +4,10 @@ #include "chrome/browser/chromeos/crostini/crostini_registry_service.h" +#include "base/strings/string_util.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/profiles/profile.h" #include "chromeos/dbus/vm_applications/apps.pb.h" #include "components/crx_file/id_util.h" @@ -20,6 +22,16 @@ namespace { +// Prefixes of the ApplicationId set on exo windows. +constexpr char kArcWindowAppIdPrefix[] = "org.chromium.arc"; +constexpr char kCrostiniWindowAppIdPrefix[] = "org.chromium.termina."; +// This comes after kCrostiniWindowAppIdPrefix +constexpr char kWMClassPrefix[] = "wmclass."; + +// This prefix is used when generating the crostini app list id, and used as a +// prefix when generating shelf ids for windows we couldn't match to an app. +constexpr char kCrostiniAppIdPrefix[] = "crostini:"; + constexpr char kCrostiniRegistryPref[] = "crostini.registry"; // Keys for the Dictionary stored in prefs for each app. @@ -31,8 +43,6 @@ constexpr char kAppNameKey[] = "name"; constexpr char kAppNoDisplayKey[] = "no_display"; -constexpr char kCrostiniAppIdPrefix[] = "crostini:"; - std::string GenerateAppId(const std::string& desktop_file_id, const std::string& vm_name, const std::string& container_name) { @@ -125,6 +135,68 @@ CrostiniRegistryService::~CrostiniRegistryService() = default; +std::string CrostiniRegistryService::GetCrostiniShelfAppId( + const std::string& window_app_id, + const std::string* window_startup_id) { + if (base::StartsWith(window_app_id, kArcWindowAppIdPrefix, + base::CompareCase::SENSITIVE)) + return std::string(); + + // TODO(timloh): We should: + // - Use and store startup notify values so we can check against it. + // - Store StartUpWMClass values and give these priority over matching the + // desktop file id for non-wayland apps + + base::StringPiece key; + if (base::StartsWith(window_app_id, kCrostiniWindowAppIdPrefix, + base::CompareCase::SENSITIVE)) { + base::StringPiece suffix( + window_app_id.begin() + strlen(kCrostiniWindowAppIdPrefix), + window_app_id.end()); + + // If we don't have an id to match to a desktop file, just return the window + // app id, which is already prefixed. + if (!base::StartsWith(suffix, kWMClassPrefix, base::CompareCase::SENSITIVE)) + return kCrostiniAppIdPrefix + window_app_id; + key = suffix.substr(strlen(kWMClassPrefix)); + } else { + key = window_app_id; + } + + std::string result; + const base::DictionaryValue* apps = + prefs_->GetDictionary(kCrostiniRegistryPref); + for (const auto& item : apps->DictItems()) { + const std::string& desktop_file_id = + item.second + .FindKeyOfType(kAppDesktopFileIdKey, base::Value::Type::STRING) + ->GetString(); + if (!EqualsCaseInsensitiveASCII(key, desktop_file_id)) + continue; + + if (!result.empty()) + return kCrostiniAppIdPrefix + window_app_id; + result = item.first; + } + + if (!result.empty()) + return result; + return kCrostiniAppIdPrefix + window_app_id; +} + +bool CrostiniRegistryService::IsCrostiniShelfAppId( + const std::string& shelf_app_id) { + if (base::StartsWith(shelf_app_id, kCrostiniAppIdPrefix, + base::CompareCase::SENSITIVE)) + return true; + // TODO(timloh): Return true for the default Terminal app. + // TODO(timloh): We need to handle desktop files that have been removed. + // For example, running windows with a no-longer-valid app id will try to + // use the ExtensionContextMenuModel. + return prefs_->GetDictionary(kCrostiniRegistryPref)->FindKey(shelf_app_id) != + nullptr; +} + std::vector<std::string> CrostiniRegistryService::GetRegisteredAppIds() const { const base::DictionaryValue* apps = prefs_->GetDictionary(kCrostiniRegistryPref);
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.h b/chrome/browser/chromeos/crostini/crostini_registry_service.h index dddefc8..09fbde7 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.h +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.h
@@ -31,6 +31,25 @@ // the VM isn't running. The registrations here correspond to .desktop files, // which are detailed in the spec: // https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/ + +// This class deals with several types of IDs, including: +// 1) Desktop File IDs (desktop_file_id): +// - As per the desktop entry spec. +// 2) Crostini App List Ids (app_id): +// - Valid extensions ids for apps stored in the registry, derived from the +// desktop file id, vm name, and container name. +// - The default Terminal app is a special case app list item, without an +// entry in the registry. +// 3) Exo Window App Ids (window_app_id): +// - Retrieved from exo::ShellSurface::GetApplicationId() +// - For Wayland apps, this is the surface class of the app +// - For X apps, this is of the form org.chromium.termina.wmclass.foo when +// WM_CLASS is set to foo, or otherwise some string prefixed by +// "org.chromium.termina." when WM_CLASS is not set. +// 4) Shelf App Ids (shelf_app_id): +// - Used in ash::ShelfID::app_id +// - Either a Window App Id prefixed by "crostini:" or a Crostini App Id. +// - For pinned apps, this is a Crostini App Id. class CrostiniRegistryService : public KeyedService { public: struct Registration { @@ -80,6 +99,20 @@ explicit CrostiniRegistryService(Profile* profile); ~CrostiniRegistryService() override; + // Returns a shelf app id for an exo window id. + // + // If the given window app id is not for Crostini (i.e. Arc++), returns an + // empty string. If we can uniquely identify a registry entry, returns the + // crostini app id for that. Otherwise, returns the |window_app_id|, possibly + // prefixed "org.chromium.termina.wayland." if it was not already prefixed. + // + // As the window app id is derived from fields set by the app itself, it is + // possible for an app to masquerade as a different app. + std::string GetCrostiniShelfAppId(const std::string& window_app_id, + const std::string* window_startup_id); + // Returns whether the app_id is a Crostini app id. + bool IsCrostiniShelfAppId(const std::string& shelf_app_id); + std::vector<std::string> GetRegisteredAppIds() const; // Return null if |app_id| is not found in the registry.
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc index 739571e..55faa2e 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc
@@ -65,6 +65,10 @@ return app_list; } + std::string WindowIdForWMClass(const std::string& wm_class) { + return "org.chromium.termina.wmclass." + wm_class; + } + CrostiniRegistryService* service() { return service_.get(); } private: @@ -177,4 +181,40 @@ testing::UnorderedElementsAre(app_id_1, app_id_3, new_app_id)); } +TEST_F(CrostiniRegistryServiceTest, GetCrostiniAppIdNoStartupID) { + ApplicationList app_list = BasicAppList("app", "vm", "container"); + *app_list.add_apps() = BasicApp("cool.app"); + *app_list.add_apps() = BasicApp("super"); + service()->UpdateApplicationList(app_list); + + service()->UpdateApplicationList(BasicAppList("super", "vm 2", "container")); + + EXPECT_THAT(service()->GetRegisteredAppIds(), testing::SizeIs(4)); + + EXPECT_EQ( + service()->GetCrostiniShelfAppId(WindowIdForWMClass("App"), nullptr), + GenerateAppId("app", "vm", "container")); + EXPECT_EQ( + service()->GetCrostiniShelfAppId(WindowIdForWMClass("cool.app"), nullptr), + GenerateAppId("cool.app", "vm", "container")); + + EXPECT_EQ( + service()->GetCrostiniShelfAppId(WindowIdForWMClass("super"), nullptr), + "crostini:" + WindowIdForWMClass("super")); + EXPECT_EQ(service()->GetCrostiniShelfAppId( + "org.chromium.termina.wmclientleader.1234", nullptr), + "crostini:org.chromium.termina.wmclientleader.1234"); + EXPECT_EQ(service()->GetCrostiniShelfAppId("org.chromium.termina.xid.654321", + nullptr), + "crostini:org.chromium.termina.xid.654321"); + + EXPECT_EQ(service()->GetCrostiniShelfAppId("cool.app", nullptr), + GenerateAppId("cool.app", "vm", "container")); + EXPECT_EQ(service()->GetCrostiniShelfAppId("fancy.app", nullptr), + "crostini:fancy.app"); + + EXPECT_EQ(service()->GetCrostiniShelfAppId("org.chromium.arc.h", nullptr), + std::string()); +} + } // namespace crostini
diff --git a/chrome/browser/ui/app_list/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc similarity index 62% rename from chrome/browser/ui/app_list/crostini/crostini_util.cc rename to chrome/browser/chromeos/crostini/crostini_util.cc index 67a6f22..2bf467c2 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_util.cc +++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -2,19 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "base/feature_list.h" #include "chrome/browser/chromeos/virtual_machines/virtual_machines_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" -namespace { - -constexpr char kCrostiniAppIdPrefix[] = "crostini:"; - -} // namespace - bool IsCrostiniAllowed() { return virtual_machines::AreVirtualMachinesAllowedByVersionAndChannel() && virtual_machines::AreVirtualMachinesAllowedByPolicy(); @@ -32,13 +26,3 @@ bool IsCrostiniRunning() { return false; } - -std::string CreateCrostiniAppId(const std::string& window_app_id) { - DCHECK(!IsCrostiniAppId(window_app_id)); - return kCrostiniAppIdPrefix + window_app_id; -} - -bool IsCrostiniAppId(const std::string& app_id) { - return strncmp(app_id.c_str(), kCrostiniAppIdPrefix, - sizeof(kCrostiniAppIdPrefix) - 1) == 0; -}
diff --git a/chrome/browser/ui/app_list/crostini/crostini_util.h b/chrome/browser/chromeos/crostini/crostini_util.h similarity index 62% rename from chrome/browser/ui/app_list/crostini/crostini_util.h rename to chrome/browser/chromeos/crostini/crostini_util.h index 9125f56..849d66df7 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_util.h +++ b/chrome/browser/chromeos/crostini/crostini_util.h
@@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_APP_LIST_CROSTINI_CROSTINI_UTIL_H_ -#define CHROME_BROWSER_UI_APP_LIST_CROSTINI_CROSTINI_UTIL_H_ - -#include <string> +#ifndef CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_ // Returns true if crostini is allowed to run. // Otherwise, returns false, e.g. if crostini is not available on the device, @@ -15,15 +13,9 @@ // Returns true if crostini UI can be shown. Implies crostini is allowed to run. bool IsExperimentalCrostiniUIAvailable(); -// Returns a Crostini app ID from a Aura window app ID. -std::string CreateCrostiniAppId(const std::string& window_app_id); - -// Returns true if the app_id is a Crostini app ID. -bool IsCrostiniAppId(const std::string& app_id); - constexpr char kCrostiniDefaultVmName[] = "termina"; constexpr char kCrostiniDefaultContainerName[] = "penguin"; constexpr char kCrostiniCroshBuiltinAppId[] = "nkoccljplnhpfnfiajclkommnmllphnl"; -#endif // CHROME_BROWSER_UI_APP_LIST_CROSTINI_CROSTINI_UTIL_H_ +#endif // CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_UTIL_H_
diff --git a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc deleted file mode 100644 index 743f697..0000000 --- a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h" - -#include "ash/public/interfaces/constants.mojom.h" -#include "content/public/browser/focused_node_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/common/service_manager_connection.h" -#include "services/service_manager/public/cpp/connector.h" - -DockedMagnifierClient::DockedMagnifierClient() : binding_(this) {} - -DockedMagnifierClient::~DockedMagnifierClient() {} - -void DockedMagnifierClient::Start() { - if (!docked_magnifier_controller_) { - service_manager::Connector* connector = - content::ServiceManagerConnection::GetForProcess()->GetConnector(); - connector->BindInterface(ash::mojom::kServiceName, - &docked_magnifier_controller_); - } - ash::mojom::DockedMagnifierClientPtr client; - binding_.Bind(mojo::MakeRequest(&client)); - docked_magnifier_controller_->SetClient(std::move(client)); -} - -void DockedMagnifierClient::OnEnabledStatusChanged(bool enabled) { - if (enabled == observing_focus_changes_) - return; - - observing_focus_changes_ = enabled; - if (enabled) { - registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources()); - } else { - registrar_.Remove(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources()); - } -} - -void DockedMagnifierClient::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(type, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE); - - content::FocusedNodeDetails* node_details = - content::Details<content::FocusedNodeDetails>(details).ptr(); - // Ash uses the InputMethod of the window tree host to observe text input - // caret bounds changes, which works for both the native UI as well as - // webpages. We don't need to notify it of editable nodes in this case. - if (node_details->is_editable_node) - return; - - const gfx::Rect& bounds_in_screen = node_details->node_bounds_in_screen; - if (bounds_in_screen.IsEmpty()) - return; - - docked_magnifier_controller_->CenterOnPoint(bounds_in_screen.CenterPoint()); -}
diff --git a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h deleted file mode 100644 index f8cfb053..0000000 --- a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_ -#define CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_ - -#include <memory> - -#include "ash/public/interfaces/docked_magnifier_controller.mojom.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "mojo/public/cpp/bindings/binding.h" - -// Observes focus change events for nodes in webpages and notifies the Docked -// Magnifier with these events. -class DockedMagnifierClient : public ash::mojom::DockedMagnifierClient, - public content::NotificationObserver { - public: - DockedMagnifierClient(); - ~DockedMagnifierClient() override; - - void Start(); - - // ash::mojom::DockedMagnifierClient: - void OnEnabledStatusChanged(bool enabled) override; - - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - private: - ash::mojom::DockedMagnifierControllerPtr docked_magnifier_controller_; - mojo::Binding<ash::mojom::DockedMagnifierClient> binding_; - - content::NotificationRegistrar registrar_; - - bool observing_focus_changes_ = false; - - DISALLOW_COPY_AND_ASSIGN(DockedMagnifierClient); -}; - -#endif // CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index 66c19524..8a424bd2 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -770,6 +770,7 @@ SET_STRING("ZIP_TARGET_EXISTS_ERROR", IDS_FILE_BROWSER_ZIP_TARGET_EXISTS_ERROR); SET_STRING("ZIP_UNEXPECTED_ERROR", IDS_FILE_BROWSER_ZIP_UNEXPECTED_ERROR); + SET_STRING("SEE_MENU_FOR_ACTIONS", IDS_FILE_BROWSER_SEE_MENU_FOR_ACTIONS); #undef SET_STRING dict->SetBoolean("PDF_VIEW_ENABLED",
diff --git a/chrome/browser/chromeos/file_manager/audio_player_browsertest.cc b/chrome/browser/chromeos/file_manager/audio_player_browsertest.cc index 119a3b0..a037a37a 100644 --- a/chrome/browser/chromeos/file_manager/audio_player_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/audio_player_browsertest.cc
@@ -6,19 +6,20 @@ namespace file_manager { -template <GuestMode M> +template <GuestMode MODE> class AudioPlayerBrowserTestBase : public FileManagerBrowserTestBase { public: - GuestMode GetGuestModeParam() const override { return M; } + GuestMode GetGuestModeParam() const override { return MODE; } + const char* GetTestCaseNameParam() const override { return test_case_name_.c_str(); } - protected: const char* GetTestManifestName() const override { return "audio_player_test_manifest.json"; } + protected: void set_test_case_name(const std::string& name) { test_case_name_ = name; } private: @@ -29,15 +30,7 @@ typedef AudioPlayerBrowserTestBase<IN_GUEST_MODE> AudioPlayerBrowserTestInGuestMode; -// http://crbug.com/508949 -#if defined(MEMORY_SANITIZER) -#define MAYBE_OpenAudioOnDownloads DISABLED_OpenAudioOnDownloads -#else -// TODO(yamaguchi): Enable after removing root cause of the test flakiness. -// http://crbug.com/804413. -#define MAYBE_OpenAudioOnDownloads DISABLED_OpenAudioOnDownloads -#endif -IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, MAYBE_OpenAudioOnDownloads) { +IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, OpenAudioOnDownloads) { set_test_case_name("openAudioOnDownloads"); StartTest(); } @@ -48,50 +41,22 @@ StartTest(); } -// http://crbug.com/508949 -#if defined(MEMORY_SANITIZER) -#define MAYBE_OpenAudioOnDrive DISABLED_OpenAudioOnDrive -#else -// TODO(yamaguchi): Enable after removing root cause of the test flakiness. -// http://crbug.com/804413. -#define MAYBE_OpenAudioOnDrive DISABLED_OpenAudioOnDrive -#endif -IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, MAYBE_OpenAudioOnDrive) { +IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, OpenAudioOnDrive) { set_test_case_name("openAudioOnDrive"); StartTest(); } -#if defined(MEMORY_SANITIZER) -#define MAYBE_TogglePlayState DISABLED_TogglePlayState -#else -// TODO(yamaguchi): Enable after removing root cause of the test flakiness. -// http://crbug.com/804413. -#define MAYBE_TogglePlayState DISABLED_TogglePlayState -#endif -IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, MAYBE_TogglePlayState) { +IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, TogglePlayState) { set_test_case_name("togglePlayState"); StartTest(); } -#if defined(MEMORY_SANITIZER) -#define MAYBE_ChangeVolumeLevel DISABLED_ChangeVolumeLevel -#else -// TODO(yamaguchi): Enable after removing root cause of the test flakiness. -// http://crbug.com/804413. -#define MAYBE_ChangeVolumeLevel DISABLED_ChangeVolumeLevel -#endif -IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, MAYBE_ChangeVolumeLevel) { +IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, ChangeVolumeLevel) { set_test_case_name("changeVolumeLevel"); StartTest(); } -#if defined(MEMORY_SANITIZER) -#define MAYBE_ChangeTracks DISABLED_ChangeTracks -#else -// Also disable because of flakyness. http://crbug.com/618198 -#define MAYBE_ChangeTracks DISABLED_ChangeTracks -#endif -IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, MAYBE_ChangeTracks) { +IN_PROC_BROWSER_TEST_F(AudioPlayerBrowserTest, ChangeTracks) { set_test_case_name("changeTracks"); StartTest(); }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 3fb2bf8..446c947 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -130,9 +130,8 @@ TestParameter(NOT_IN_GUEST_MODE, "imageOpenDownloads"), TestParameter(NOT_IN_GUEST_MODE, "imageOpenDrive"))); -// Flaky: crbug.com/715963 WRAPPED_INSTANTIATE_TEST_CASE_P( - DISABLED_CreateNewFolder, + CreateNewFolder, FileManagerBrowserTest, ::testing::Values( TestParameter(NOT_IN_GUEST_MODE, "createNewFolderAfterSelectFile"),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 4b75729d..aee67a2 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -578,7 +578,7 @@ } void FileManagerBrowserTestBase::StartTest() { - LOG(INFO) << "FileManagerBrowserTest::StartTest " << GetTestManifestName(); + LOG(INFO) << "FileManagerBrowserTest::StartTest " << GetTestCaseNameParam(); InstallExtension( base::FilePath(FILE_PATH_LITERAL("ui/file_manager/integration_tests")), GetTestManifestName());
diff --git a/chrome/browser/chromeos/file_manager/video_player_browsertest.cc b/chrome/browser/chromeos/file_manager/video_player_browsertest.cc index 53e304e..d8d236a 100644 --- a/chrome/browser/chromeos/file_manager/video_player_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/video_player_browsertest.cc
@@ -8,25 +8,26 @@ namespace file_manager { -template <GuestMode M> +template <GuestMode MODE> class VideoPlayerBrowserTestBase : public FileManagerBrowserTestBase { public: - GuestMode GetGuestModeParam() const override { return M; } - const char* GetTestCaseNameParam() const override { - return test_case_name_.c_str(); - } - - protected: void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( chromeos::switches::kEnableVideoPlayerChromecastSupport); FileManagerBrowserTestBase::SetUpCommandLine(command_line); } + GuestMode GetGuestModeParam() const override { return MODE; } + + const char* GetTestCaseNameParam() const override { + return test_case_name_.c_str(); + } + const char* GetTestManifestName() const override { return "video_player_test_manifest.json"; } + protected: void set_test_case_name(const std::string& name) { test_case_name_ = name; } private: @@ -37,10 +38,7 @@ typedef VideoPlayerBrowserTestBase<IN_GUEST_MODE> VideoPlayerBrowserTestInGuestMode; -// TODO(yamaguchi): Enable after removing root cause of the test flakiness. -// http://crbug.com/804413. -IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, - DISABLED_OpenSingleVideoOnDownloads) { +IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, OpenSingleVideoOnDownloads) { set_test_case_name("openSingleVideoOnDownloads"); StartTest(); } @@ -51,40 +49,17 @@ StartTest(); } -// MEMORY_SANITIZER: http://crbug.com/508949 -// CHROME_OS: http://crbug.com/688568 -#if defined(MEMORY_SANITIZER) || defined(OS_CHROMEOS) -#define MAYBE_OpenSingleVideoOnDrive DISABLED_OpenSingleVideoOnDrive -#else -#define MAYBE_OpenSingleVideoOnDrive OpenSingleVideoOnDrive -#endif -IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, MAYBE_OpenSingleVideoOnDrive) { +IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, OpenSingleVideoOnDrive) { set_test_case_name("openSingleVideoOnDrive"); StartTest(); } -// http://crbug.com/508949 -#if defined(MEMORY_SANITIZER) -#define MAYBE_CheckInitialElements DISABLED_CheckInitialElements -#else -#define MAYBE_CheckInitialElements CheckInitialElements -#endif -// TODO(yamaguchi):Enable after removing root cause of the test flakiness. -// https://crbug.com/804413. -IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, DISABLED_CheckInitialElements) { +IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, CheckInitialElements) { set_test_case_name("checkInitialElements"); StartTest(); } -// http://crbug.com/508949 -#if defined(MEMORY_SANITIZER) -#define MAYBE_ClickControlButtons DISABLED_ClickControlButtons -#else -#define MAYBE_ClickControlButtons ClickControlButtons -#endif -// TODO(yamaguchi):Enable after removing root cause of the test flakiness. -// https://crbug.com/804413. -IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, DISABLED_ClickControlButtons) { +IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, ClickControlButtons) { set_test_case_name("clickControlButtons"); StartTest(); }
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc index 451a014..1272914 100644 --- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc +++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
@@ -113,7 +113,8 @@ // Make sure gears are in motion in the background. auto_enrollment_controller_->Start(); - network_portal_detector::GetInstance()->StartDetectionIfIdle(); + network_portal_detector::GetInstance()->StartPortalDetection( + false /* force */); } void AutoEnrollmentCheckScreen::Hide() {}
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index 9401723..1da60d1 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -54,7 +54,6 @@ #include "chromeos/login/auth/authenticator.h" #include "chromeos/login/auth/authpolicy_login_helper.h" #include "chromeos/login/auth/extended_authenticator.h" -#include "chromeos/network/portal_detector/network_portal_detector.h" #include "components/password_manager/core/browser/hash_password_manager.h" #include "components/session_manager/core/session_manager.h" #include "components/signin/core/browser/signin_manager.h" @@ -516,8 +515,6 @@ VLOG(1) << "Calling session manager's StopSession D-Bus method"; DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); } - // Close captive portal window and clear signin profile. - network_portal_detector::GetInstance()->OnLockScreenRequest(); } // static
diff --git a/chrome/browser/chromeos/login/screens/update_screen.cc b/chrome/browser/chromeos/login/screens/update_screen.cc index bf2d334..5cbf5557c 100644 --- a/chrome/browser/chromeos/login/screens/update_screen.cc +++ b/chrome/browser/chromeos/login/screens/update_screen.cc
@@ -357,10 +357,10 @@ is_first_detection_notification_) { is_first_detection_notification_ = false; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce( - base::IgnoreResult(&NetworkPortalDetector::StartDetectionIfIdle), - base::Unretained(network_portal_detector::GetInstance()))); + FROM_HERE, base::BindOnce([]() { + network_portal_detector::GetInstance()->StartPortalDetection( + false /* force */); + })); return; } is_first_detection_notification_ = false;
diff --git a/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc b/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc index 0399bf52..75bc8c8 100644 --- a/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc +++ b/chrome/browser/chromeos/login/ui/captive_portal_window_browsertest.cc
@@ -74,6 +74,7 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); command_line->AppendSwitch(chromeos::switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kDisableHIDDetectionOnOOBE); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_impl.cc index b4a3989..ad904b9 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl.cc +++ b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
@@ -16,7 +16,6 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/net/network_portal_notification_controller.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill_profile_client.h" @@ -211,8 +210,7 @@ NetworkPortalDetectorImpl::kDelaySinceShillPortalForUMA; NetworkPortalDetectorImpl::NetworkPortalDetectorImpl( - network::mojom::URLLoaderFactory* loader_factory, - bool create_notification_controller) + network::mojom::URLLoaderFactory* loader_factory) : strategy_(PortalDetectorStrategy::CreateById( PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, this)), @@ -228,21 +226,13 @@ portal_test_url_ = GURL(CaptivePortalDetector::kDefaultURL); } - if (create_notification_controller) { - notification_controller_.reset( - new NetworkPortalNotificationController(this)); - notification_controller_->set_retry_detection_callback( - base::Bind(&NetworkPortalDetectorImpl::RetryDetection, - weak_factory_.GetWeakPtr())); - } - registrar_.Add(this, chrome::NOTIFICATION_AUTH_SUPPLIED, content::NotificationService::AllSources()); registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, content::NotificationService::AllSources()); NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); - StartDetectionIfIdle(); + StartPortalDetection(false /* force */); } NetworkPortalDetectorImpl::~NetworkPortalDetectorImpl() { @@ -259,6 +249,8 @@ NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, FROM_HERE); } + for (auto& observer : observers_) + observer.OnShutdown(); } void NetworkPortalDetectorImpl::AddObserver(Observer* observer) { @@ -315,9 +307,12 @@ return it->second; } -bool NetworkPortalDetectorImpl::StartDetectionIfIdle() { - if (!is_idle()) - return false; +bool NetworkPortalDetectorImpl::StartPortalDetection(bool force) { + if (!is_idle()) { + if (!force) + return false; + StopDetection(); + } StartDetection(); return true; } @@ -327,13 +322,7 @@ if (id == strategy_->Id()) return; strategy_ = PortalDetectorStrategy::CreateById(id, this); - StopDetection(); - StartDetectionIfIdle(); -} - -void NetworkPortalDetectorImpl::OnLockScreenRequest() { - if (notification_controller_) - notification_controller_->CloseDialog(); + StartPortalDetection(true /* force */); } void NetworkPortalDetectorImpl::DefaultNetworkChanged( @@ -442,11 +431,6 @@ ResetStrategyAndCounters(); } -void NetworkPortalDetectorImpl::RetryDetection() { - StopDetection(); - StartDetection(); -} - void NetworkPortalDetectorImpl::ScheduleAttempt(const base::TimeDelta& delay) { DCHECK(is_idle());
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.h b/chrome/browser/chromeos/net/network_portal_detector_impl.h index 3740b158..3ffa9bd 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl.h +++ b/chrome/browser/chromeos/net/network_portal_detector_impl.h
@@ -41,7 +41,6 @@ namespace chromeos { -class NetworkPortalNotificationController; class NetworkState; // This class handles all notifications about network changes from @@ -57,8 +56,8 @@ static constexpr base::TimeDelta kDelaySinceShillPortalForUMA = base::TimeDelta::FromSeconds(60); - NetworkPortalDetectorImpl(network::mojom::URLLoaderFactory* loader_factory, - bool create_notification_controller); + explicit NetworkPortalDetectorImpl( + network::mojom::URLLoaderFactory* loader_factory); ~NetworkPortalDetectorImpl() override; // Set the URL to be tested for portal state. @@ -130,9 +129,8 @@ CaptivePortalState GetCaptivePortalState(const std::string& guid) override; bool IsEnabled() override; void Enable(bool start_detection) override; - bool StartDetectionIfIdle() override; + bool StartPortalDetection(bool force) override; void SetStrategy(PortalDetectorStrategy::StrategyId id) override; - void OnLockScreenRequest() override; // NetworkStateHandlerObserver implementation: void DefaultNetworkChanged(const NetworkState* network) override; @@ -262,14 +260,8 @@ // Number of detection attempts in a row with NO RESPONSE result. int no_response_result_count_ = 0; - // Must be declared before |notification_controller_| as - // ~NetworkPortalNotificationController() calls - // NetworkPortalDetectorImpl::RemoveObserver() which uses this. SEQUENCE_CHECKER(sequence_checker_); - // UI notification controller about captive portal state. - std::unique_ptr<NetworkPortalNotificationController> notification_controller_; - content::NotificationRegistrar registrar_; // Test time ticks used by unit tests.
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc index f3221ee..6b0df851 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc +++ b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/location.h" @@ -75,7 +77,7 @@ : LoginManagerTest(false), test_account_id_( AccountId::FromUserEmailGaiaId(kTestUser, kTestUserGaiaId)), - network_portal_detector_(NULL) {} + network_portal_detector_(nullptr) {} ~NetworkPortalDetectorImplBrowserTest() override {} @@ -85,11 +87,8 @@ ShillServiceClient::TestInterface* service_test = DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); service_test->ClearServices(); - service_test->AddService(kWifiServicePath, - kWifiGuid, - "wifi", - shill::kTypeEthernet, - shill::kStateIdle, + service_test->AddService(kWifiServicePath, kWifiGuid, "wifi", + shill::kTypeEthernet, shill::kStateIdle, true /* add_to_visible */); DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( dbus::ObjectPath(kWifiServicePath), shill::kStateProperty, @@ -99,16 +98,24 @@ display_service_ = std::make_unique<NotificationDisplayServiceTester>( chromeos::ProfileHelper::GetSigninProfile()); - network_portal_detector_ = new NetworkPortalDetectorImpl( - test_loader_factory(), true /* create_notification_controller */); + network_portal_detector_ = + new NetworkPortalDetectorImpl(test_loader_factory()); + // Takes ownership of |network_portal_detector_|: network_portal_detector::InitializeForTesting(network_portal_detector_); network_portal_detector_->Enable(false /* start_detection */); set_detector(network_portal_detector_->captive_portal_detector_.get()); PortalDetectorStrategy::set_delay_till_next_attempt_for_testing( base::TimeDelta()); + network_portal_notification_controller_ = + std::make_unique<NetworkPortalNotificationController>( + network_portal_detector_); base::RunLoop().RunUntilIdle(); } + void TearDownOnMainThread() override { + network_portal_notification_controller_.reset(); + } + void RestartDetection() { network_portal_detector_->StopDetection(); network_portal_detector_->StartDetection(); @@ -120,13 +127,11 @@ } void SetIgnoreNoNetworkForTesting() { - network_portal_detector_->notification_controller_ - ->SetIgnoreNoNetworkForTesting(); + network_portal_notification_controller_->SetIgnoreNoNetworkForTesting(); } const NetworkPortalWebDialog* GetDialog() const { - return network_portal_detector_->notification_controller_ - ->GetDialogForTesting(); + return network_portal_notification_controller_->GetDialogForTesting(); } protected: @@ -136,6 +141,8 @@ private: NetworkPortalDetectorImpl* network_portal_detector_; + std::unique_ptr<NetworkPortalNotificationController> + network_portal_notification_controller_; DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImplBrowserTest); }; @@ -152,9 +159,9 @@ typedef NetworkPortalNotificationController Controller; EnumHistogramChecker ui_checker( - kNotificationMetric, Controller::NOTIFICATION_METRIC_COUNT, NULL); + kNotificationMetric, Controller::NOTIFICATION_METRIC_COUNT, nullptr); EnumHistogramChecker action_checker( - kUserActionMetric, Controller::USER_ACTION_METRIC_COUNT, NULL); + kUserActionMetric, Controller::USER_ACTION_METRIC_COUNT, nullptr); LoginUser(test_account_id_); content::RunAllPendingInMessageLoop(); @@ -167,7 +174,7 @@ // No notification until portal detection is completed. EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); RestartDetection(); - CompleteURLFetch(net::OK, 200, NULL); + CompleteURLFetch(net::OK, 200, nullptr); // Check that wifi is marked as behind the portal and that notification // is displayed.
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc index fa32d900..577fe864 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc +++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -106,7 +106,7 @@ EXPECT_TRUE(user_manager::UserManager::Get()->GetPrimaryUser()); network_portal_detector_.reset( - new NetworkPortalDetectorImpl(test_loader_factory(), false)); + new NetworkPortalDetectorImpl(test_loader_factory())); network_portal_detector_->Enable(false); set_detector(network_portal_detector_->captive_portal_detector_.get()); @@ -171,8 +171,8 @@ return network_portal_detector()->state(); } - bool start_detection_if_idle() { - return network_portal_detector()->StartDetectionIfIdle(); + bool StartPortalDetection(bool force) { + return network_portal_detector()->StartPortalDetection(force); } void enable_error_screen_strategy() { @@ -857,7 +857,7 @@ // First portal detection attempts determines ONLINE state. SetConnected(kStubWireless1); ASSERT_EQ(State::STATE_CHECKING_FOR_PORTAL, state()); - ASSERT_FALSE(start_detection_if_idle()); + ASSERT_FALSE(StartPortalDetection(false /* force */)); CompleteURLFetch(net::OK, 204, nullptr);
diff --git a/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc index cfaa5c55..a70886e 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc +++ b/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc
@@ -13,6 +13,8 @@ } NetworkPortalDetectorTestImpl::~NetworkPortalDetectorTestImpl() { + for (auto& observer : observers_) + observer.OnShutdown(); } void NetworkPortalDetectorTestImpl::SetDefaultNetworkForTesting( @@ -86,7 +88,7 @@ void NetworkPortalDetectorTestImpl::Enable(bool start_detection) { } -bool NetworkPortalDetectorTestImpl::StartDetectionIfIdle() { +bool NetworkPortalDetectorTestImpl::StartPortalDetection(bool force) { return false; } @@ -95,7 +97,4 @@ strategy_id_ = id; } -void NetworkPortalDetectorTestImpl::OnLockScreenRequest() { -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h index 8701d5d4..a532ee78 100644 --- a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h +++ b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h
@@ -34,10 +34,8 @@ const std::string& service_path) override; bool IsEnabled() override; void Enable(bool start_detection) override; - bool StartDetectionIfIdle() override; - + bool StartPortalDetection(bool force) override; void SetStrategy(PortalDetectorStrategy::StrategyId id) override; - void OnLockScreenRequest() override; PortalDetectorStrategy::StrategyId strategy_id() const { return strategy_id_;
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.cc b/chrome/browser/chromeos/net/network_portal_notification_controller.cc index 86b4ecc6..c83cb4c 100644 --- a/chrome/browser/chromeos/net/network_portal_notification_controller.cc +++ b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
@@ -42,6 +42,7 @@ #include "chromeos/network/network_type_pattern.h" #include "components/captive_portal/captive_portal_detector.h" #include "components/prefs/pref_service.h" +#include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" #include "extensions/browser/api/networking_config/networking_config_service.h" #include "extensions/browser/api/networking_config/networking_config_service_factory.h" @@ -227,17 +228,23 @@ NetworkPortalNotificationController::NetworkPortalNotificationController( NetworkPortalDetector* network_portal_detector) : network_portal_detector_(network_portal_detector), weak_factory_(this) { - if (NetworkHandler::IsInitialized()) { // NULL for unit tests. + if (NetworkHandler::IsInitialized()) { // May be false in tests. NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); } - if (network_portal_detector_) + if (network_portal_detector_) { // May be null in tests. network_portal_detector_->AddObserver(this); + DCHECK(session_manager::SessionManager::Get()); + session_manager::SessionManager::Get()->AddObserver(this); + } } NetworkPortalNotificationController::~NetworkPortalNotificationController() { - if (network_portal_detector_) + if (network_portal_detector_) { + if (session_manager::SessionManager::Get()) + session_manager::SessionManager::Get()->RemoveObserver(this); network_portal_detector_->RemoveObserver(this); + } if (NetworkHandler::IsInitialized()) { NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, FROM_HERE); @@ -302,6 +309,19 @@ NetworkPortalNotificationController::NOTIFICATION_METRIC_COUNT); } +void NetworkPortalNotificationController::OnShutdown() { + CloseDialog(); + network_portal_detector_->RemoveObserver(this); + network_portal_detector_ = nullptr; +} + +void NetworkPortalNotificationController::OnSessionStateChanged() { + session_manager::SessionState state = + session_manager::SessionManager::Get()->session_state(); + if (state == session_manager::SessionState::LOCKED) + CloseDialog(); +} + void NetworkPortalNotificationController::ShowDialog() { if (dialog_) return; @@ -424,8 +444,8 @@ } void NetworkPortalNotificationController::OnExtensionFinishedAuthentication() { - if (!retry_detection_callback_.is_null()) - retry_detection_callback_.Run(); + if (network_portal_detector_) + network_portal_detector_->StartPortalDetection(true /* force */); } void NetworkPortalNotificationController::SetIgnoreNoNetworkForTesting() {
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.h b/chrome/browser/chromeos/net/network_portal_notification_controller.h index 93e02a5..30bacf6 100644 --- a/chrome/browser/chromeos/net/network_portal_notification_controller.h +++ b/chrome/browser/chromeos/net/network_portal_notification_controller.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "chromeos/network/network_state_handler_observer.h" #include "chromeos/network/portal_detector/network_portal_detector.h" +#include "components/session_manager/core/session_manager_observer.h" #include "ui/message_center/public/cpp/notification.h" namespace extensions { @@ -28,7 +29,8 @@ // captive portal. class NetworkPortalNotificationController : public NetworkStateHandlerObserver, - public NetworkPortalDetector::Observer { + public NetworkPortalDetector::Observer, + public session_manager::SessionManagerObserver { public: // The values of these metrics are being used for UMA gathering, so it is // important that they don't change between releases. @@ -61,16 +63,6 @@ NetworkPortalDetector* network_portal_dectector); ~NetworkPortalNotificationController() override; - // |retry_detection_callback| will be called if the controller learns about a - // potential change of the captive portal (e.g. if an extension notifies about - // a finished authentication). - // |retry_detection_callback| will not be called after this controller is - // destroyed. - void set_retry_detection_callback( - const base::Closure& retry_detection_callback) { - retry_detection_callback_ = retry_detection_callback; - } - // Creates NetworkPortalWebDialog. void ShowDialog(); @@ -124,6 +116,10 @@ void OnPortalDetectionCompleted( const NetworkState* network, const NetworkPortalDetector::CaptivePortalState& state) override; + void OnShutdown() override; + + // session_manager::SessionManagerObserver: + void OnSessionStateChanged() override; // Last network guid for which notification was displayed. std::string last_network_guid_; @@ -137,10 +133,6 @@ // Do not close Portal Login dialog on "No network" error in browser tests. bool ignore_no_network_for_testing_ = false; - // This is called if the controller learns about a potential change of the - // captive portal. - base::Closure retry_detection_callback_; - base::WeakPtrFactory<NetworkPortalNotificationController> weak_factory_; DISALLOW_COPY_AND_ASSIGN(NetworkPortalNotificationController);
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc index c32cd09..409a659 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
@@ -600,37 +600,16 @@ if (str->empty()) { *str = GetIconUrlFromImage( ui::ResourceBundle::GetSharedInstance().GetImageNamed( - is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON), - is_greyscale); + is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON)); } return *str; } std::string ExtensionInfoGenerator::GetIconUrlFromImage( - const gfx::Image& image, - bool should_greyscale) { - // Ignore |should_greyscale| if MD Extensions are enabled. - // TODO(dpapad): Remove should_greyscale logic once non-MD Extensions UI is - // removed. - should_greyscale = - should_greyscale && - !base::FeatureList::IsEnabled(features::kMaterialDesignExtensions); - + const gfx::Image& image) { scoped_refptr<base::RefCountedMemory> data; - if (should_greyscale) { - color_utils::HSL shift = {-1, 0, 0.6}; - const SkBitmap* bitmap = image.ToSkBitmap(); - DCHECK(bitmap); - SkBitmap grey = SkBitmapOperations::CreateHSLShiftedBitmap(*bitmap, shift); - scoped_refptr<base::RefCountedBytes> image_bytes( - new base::RefCountedBytes()); - gfx::PNGCodec::EncodeBGRASkBitmap(grey, false, &image_bytes->data()); - data = image_bytes; - } else { - data = image.As1xPNGBytes(); - } - + data = image.As1xPNGBytes(); std::string base_64; base::Base64Encode(base::StringPiece(data->front_as<char>(), data->size()), &base_64); @@ -642,8 +621,7 @@ std::unique_ptr<developer::ExtensionInfo> info, const gfx::Image& icon) { if (!icon.IsEmpty()) { - info->icon_url = GetIconUrlFromImage( - icon, info->state != developer::EXTENSION_STATE_ENABLED); + info->icon_url = GetIconUrlFromImage(icon); } else { bool is_app = info->type == developer::EXTENSION_TYPE_HOSTED_APP ||
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.h b/chrome/browser/extensions/api/developer_private/extension_info_generator.h index 8fb11cc..84628f8 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator.h +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.h
@@ -69,9 +69,8 @@ // Returns the icon url for the default icon to use. const std::string& GetDefaultIconUrl(bool is_app, bool is_disabled); - // Returns an icon url from the given image, optionally applying a greyscale. - std::string GetIconUrlFromImage(const gfx::Image& image, - bool should_greyscale); + // Returns an icon url from the given image. + std::string GetIconUrlFromImage(const gfx::Image& image); // Various systems, cached for convenience. content::BrowserContext* browser_context_;
diff --git a/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc b/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc index 6181698..99964e18 100644 --- a/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc +++ b/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc
@@ -242,34 +242,28 @@ FileSystemDelegate::FilesSelectedCallback files_selected_callback, base::OnceClosure file_selection_canceled_callback) { const Extension* extension = extension_function->extension(); - content::WebContents* web_contents = nullptr; + content::WebContents* web_contents = + extension_function->GetSenderWebContents(); + + if (!web_contents) + return false; // TODO(asargent/benwells) - As a short term remediation for // crbug.com/179010 we're adding the ability for a whitelisted extension to // use this API since chrome.fileBrowserHandler.selectFile is ChromeOS-only. // Eventually we'd like a better solution and likely this code will go back // to being platform-app only. - if (extension->is_platform_app()) { - content::WebContents* candidate = content::WebContents::FromRenderFrameHost( - extension_function->render_frame_host()); - // Make sure there is an app window associated with the web contents. - if (AppWindowRegistry::Get(extension_function->browser_context()) - ->GetAppWindowForWebContents(candidate)) { - web_contents = candidate; - } - } else { - // TODO(michaelpg): As a workaround for crbug.com/736930, allow this to work - // from a background page by using the the extended - // GetAssociatedWebContentsDeprecated() function provided by - // ChromeExtensionFunctionDetails. This is safe because only whitelisted - // extensions can access the chrome.fileSystem API; platform apps cannot - // open the file picker from a background page. - web_contents = ChromeExtensionFunctionDetails(extension_function.get()) - .GetAssociatedWebContentsDeprecated(); - } - if (!web_contents) + // Make sure there is an app window associated with the web contents, so that + // platform apps cannot open the file picker from a background page. + // TODO(michaelpg): As a workaround for https://crbug.com/736930, allow this + // to work from a background page for non-platform apps (which, in practice, + // is restricted to whitelisted extensions). + if (extension->is_platform_app() && + !AppWindowRegistry::Get(extension_function->browser_context()) + ->GetAppWindowForWebContents(web_contents)) { return false; + } // The file picker will hold a reference to the UIThreadExtensionFunction // instance, preventing its destruction (and subsequent sending of the
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api_util.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api_util.cc index c0d399bb..9a0eda7 100644 --- a/chrome/browser/extensions/api/media_galleries/media_galleries_api_util.cc +++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api_util.cc
@@ -51,8 +51,9 @@ for (const chrome::mojom::MediaStreamInfoPtr& info : metadata->raw_tags) { extensions::api::media_galleries::StreamInfo stream_info; stream_info.type = std::move(info->type); - stream_info.tags.additional_properties.Swap( - info->additional_properties.get()); + base::DictionaryValue* dict_value; + info->additional_properties.GetAsDictionary(&dict_value); + stream_info.tags.additional_properties.Swap(dict_value); extension_metadata.raw_tags.push_back(std::move(stream_info)); }
diff --git a/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc b/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc index 2dea3a79..5cdb6dbd6 100644 --- a/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <string> #include "base/location.h" @@ -48,6 +49,9 @@ : public ExtensionApiTest, public captive_portal::CaptivePortalDetectorTestBase { public: + NetworkingConfigTest() : network_portal_detector_(nullptr) {} + ~NetworkingConfigTest() override = default; + void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); content::RunAllPendingInMessageLoop(); @@ -81,12 +85,20 @@ content::RunAllPendingInMessageLoop(); - network_portal_detector_ = new NetworkPortalDetectorImpl( - test_loader_factory(), true /* create_notification_controller */); + network_portal_detector_ = + new NetworkPortalDetectorImpl(test_loader_factory()); + // Takes ownership of |network_portal_detector_|: chromeos::network_portal_detector::InitializeForTesting( network_portal_detector_); network_portal_detector_->Enable(false /* start_detection */); set_detector(network_portal_detector_->captive_portal_detector_.get()); + network_portal_notification_controller_ = + std::make_unique<NetworkPortalNotificationController>( + network_portal_detector_); + } + + void TearDownOnMainThread() override { + network_portal_notification_controller_.reset(); } void LoadTestExtension() { @@ -118,7 +130,9 @@ } protected: - NetworkPortalDetectorImpl* network_portal_detector_ = nullptr; + NetworkPortalDetectorImpl* network_portal_detector_; + std::unique_ptr<NetworkPortalNotificationController> + network_portal_notification_controller_; const extensions::Extension* extension_ = nullptr; std::unique_ptr<NotificationDisplayServiceTester> display_service_; };
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index ed6342e..6be68a53 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -22,6 +22,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" +#include "content/public/test/test_utils.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" @@ -443,17 +444,12 @@ // Test that when an extension with a background page that has a tab open // crashes, the tab stays open, and reloading it reloads the extension. // Regression test for issue 71629 and 763808. -// -// Disabled on Linux dbg: https://crbug.com/831078. -// TODO(https://crbug.com/831078): Disable it only when site-per-process is -// enabled. -#if !defined(NDEBUG) && defined(OS_LINUX) -#define MAYBE_ReloadTabsWithBackgroundPage DISABLED_ReloadTabsWithBackgroundPage -#else -#define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage -#endif IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, - MAYBE_ReloadTabsWithBackgroundPage) { + ReloadTabsWithBackgroundPage) { + // TODO(https://crbug.com/831078): Fix the test. + if (content::AreAllSitesIsolatedForTesting()) + return; + TabStripModel* tab_strip = browser()->tab_strip_model(); const size_t count_before = GetEnabledExtensionCount(); const size_t crash_count_before = GetTerminatedExtensionCount();
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc index be125bb5..ca5cc4f 100644 --- a/chrome/browser/extensions/extension_messages_apitest.cc +++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -264,6 +264,12 @@ // Tests whether an extension in an interstitial page can send messages to the // background page. IN_PROC_BROWSER_TEST_P(MessagingApiTest, MessagingInterstitial) { +#if defined(OS_WIN) + // TODO(https://crbug.com/833429): Intermittent timeouts when run with + // --site-per-process on Windows. + if (content::AreAllSitesIsolatedForTesting()) + return; +#endif net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); ASSERT_TRUE(https_server.Start());
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index e9dd1845..acaff7d7 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -571,61 +571,6 @@ EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } -// Tests that the lazy background page updates the chrome://extensions page -// when it is destroyed. -IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, UpdateExtensionsPage) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {} /* enabled */, {features::kMaterialDesignExtensions} /* disabled */); - - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL)); - auto* extensions_page = browser()->tab_strip_model()->GetActiveWebContents(); - - ResultCatcher catcher; - base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page"). - AppendASCII("wait_for_view"); - const Extension* extension = LoadExtension(extdir); - ASSERT_TRUE(extension); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - - // The extension should've opened a new tab to an extension page. - EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(), - browser()->tab_strip_model()->GetActiveWebContents()-> - GetURL().spec()); - - // Lazy Background Page still exists, because the extension created a new tab - // to an extension page. - EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id())); - - // Close the new tab. - LazyBackgroundObserver page_complete; - browser()->tab_strip_model()->CloseWebContentsAt( - browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE); - page_complete.WaitUntilClosed(); - - // Lazy Background Page has been shut down. - EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id())); - - // Updating the extensions page is a process that has back-and-forth - // communication (i.e., backend tells extensions page something changed, - // extensions page requests updated data, backend responds with updated data, - // and so forth). This makes it difficult to know for sure when the page is - // done updating, so just try a few times. We limit the total number of - // attempts so that a) the test *fails* (instead of times out), and b) we - // know we're not making a ridiculous amount of trips to update the page. - bool is_inactive = false; - int kMaxTries = 10; - int num_tries = 0; - while (!is_inactive && num_tries++ < kMaxTries) { - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - extensions_page, - "var ele = document.querySelectorAll('div.active-views');" - "window.domAutomationController.send(" - " ele[0].innerHTML.search('(Inactive)') > 0);", - &is_inactive)); - } -} - // Tests that the lazy background page will be unloaded if the onSuspend event // handler calls an API function such as chrome.storage.local.set(). // See: http://crbug.com/296834
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 06bdc647..ee67644 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -429,12 +429,6 @@ const char kEnableHDRDescription[] = "Enables HDR support on compatible displays."; -const char kEnableHeapProfilingName[] = "Heap profiling"; -const char kEnableHeapProfilingDescription[] = "Enables heap profiling."; -const char kEnableHeapProfilingModePseudo[] = "Enabled (pseudo mode)"; -const char kEnableHeapProfilingModeNative[] = "Enabled (native mode)"; -const char kEnableHeapProfilingTaskProfiler[] = "Enabled (task mode)"; - const char kEnableHttpFormWarningName[] = "Show in-form warnings for sensitive fields when the top-level page is not " "HTTPS";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 01c1c67..8e93553 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -295,12 +295,6 @@ extern const char kEnableHDRName[]; extern const char kEnableHDRDescription[]; -extern const char kEnableHeapProfilingName[]; -extern const char kEnableHeapProfilingDescription[]; -extern const char kEnableHeapProfilingModePseudo[]; -extern const char kEnableHeapProfilingModeNative[]; -extern const char kEnableHeapProfilingTaskProfiler[]; - extern const char kEnableHttpFormWarningName[]; extern const char kEnableHttpFormWarningDescription[];
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 2b6baf9..dd7af3a4 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -1448,68 +1448,6 @@ } // namespace IN_PROC_BROWSER_TEST_F(PolicyTest, DeveloperToolsDisabledExtensionsDevMode) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {} /* enabled */, {features::kMaterialDesignExtensions} /* disabled */); - - // Verifies that when DeveloperToolsDisabled policy is set, the "dev mode" - // in chrome://extensions-frame is actively turned off and the checkbox - // is disabled. - // Note: We don't test the indicator as it is tested in the policy pref test - // for kDeveloperToolsDisabled. - - // This test currently depends on the following assumptions about the webui: - // (1) The ID of the checkbox to toggle dev mode - const char toggle_dev_mode_accessor_js[] = - "document.getElementById('toggle-dev-on')"; - // (2) The ID of the dev controls containing element - const char dev_controls_accessor_js[] = - "document.getElementById('dev-controls')"; - // (3) the fact that dev-controls is displayed/hidden using its height attr - const char dev_controls_visibility_check_js[] = - "parseFloat(document.getElementById('dev-controls').style.height) > 0"; - - // Navigate to the extensions frame and enabled "Developer mode" - ui_test_utils::NavigateToURL(browser(), - GURL(chrome::kChromeUIExtensionsFrameURL)); - - content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(content::ExecuteScript( - contents, base::StringPrintf("domAutomationController.send(%s.click());", - toggle_dev_mode_accessor_js))); - - WaitForExtensionsDevModeControlsVisibility(contents, - dev_controls_accessor_js, - dev_controls_visibility_check_js, - true); - - // Disable devtools via policy. - PolicyMap policies; - policies.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - std::make_unique<base::Value>(true), nullptr); - UpdateProviderPolicy(policies); - - // Expect devcontrols to be hidden now... - WaitForExtensionsDevModeControlsVisibility(contents, - dev_controls_accessor_js, - dev_controls_visibility_check_js, - false); - - // ... and checkbox is not disabled - bool is_toggle_dev_mode_checkbox_enabled = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - base::StringPrintf( - "domAutomationController.send(!%s.hasAttribute('disabled'))", - toggle_dev_mode_accessor_js), - &is_toggle_dev_mode_checkbox_enabled)); - EXPECT_FALSE(is_toggle_dev_mode_checkbox_enabled); -} - -// TODO(dpapad): Remove the "_MD" suffix once the non-MD test is deleted. -IN_PROC_BROWSER_TEST_F(PolicyTest, DeveloperToolsDisabledExtensionsDevMode_MD) { // Verifies that when DeveloperToolsDisabled policy is set, the "dev mode" // in chrome://extensions is actively turned off and the checkbox // is disabled.
diff --git a/chrome/browser/policy/site_isolation_policy_browsertest.cc b/chrome/browser/policy/site_isolation_policy_browsertest.cc index 4714df07..e7f249f 100644 --- a/chrome/browser/policy/site_isolation_policy_browsertest.cc +++ b/chrome/browser/policy/site_isolation_policy_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/macros.h" +#include "build/build_config.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -124,7 +125,9 @@ // the call to the base setup method because setting the Site Isolation // policy is indistinguishable from setting the the command line flag // directly. - are_sites_isolated_for_testing_ = content::AreAllSitesIsolatedForTesting(); + are_sites_isolated_for_testing_ = + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableSiteIsolationTrials); // We setup the policy here, because the policy must be 'live' before the // renderer is created, since the value for this policy is passed to the @@ -226,7 +229,15 @@ CheckExpectations(expectations, arraysize(expectations)); } -IN_PROC_BROWSER_TEST_F(SiteIsolationPolicyBrowserTest, NoPolicyNoTrialsFlags) { +// https://crbug.com/833423: The test is incompatible with the +// not_site_per_process_browser_tests step on the trybots. +#if defined(OS_LINUX) +#define MAYBE_NoPolicyNoTrialsFlags DISABLED_NoPolicyNoTrialsFlags +#else +#define MAYBE_NoPolicyNoTrialsFlags NoPolicyNoTrialsFlags +#endif +IN_PROC_BROWSER_TEST_F(SiteIsolationPolicyBrowserTest, + MAYBE_NoPolicyNoTrialsFlags) { ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableSiteIsolationTrials)); }
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index bf64784..d03b2815 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -1725,7 +1725,14 @@ // Push subscriptions used to be non-InstanceID GCM registrations. Still need // to be able to unsubscribe these, even though new ones are no longer created. -IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, LegacyUnsubscribeSuccess) { +// Flaky on some Win and Linux buildbots. See crbug.com/835382. +#if defined(OS_WIN) || defined(OS_LINUX) +#define MAYBE_LegacyUnsubscribeSuccess DISABLED_LegacyUnsubscribeSuccess +#else +#define MAYBE_LegacyUnsubscribeSuccess LegacyUnsubscribeSuccess +#endif +IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, + MAYBE_LegacyUnsubscribeSuccess) { std::string script_result; std::string subscription_id1;
diff --git a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc index 081686fb..1c27a39 100644 --- a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc +++ b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h" #include "chrome/browser/ui/browser.h" @@ -82,6 +83,12 @@ IN_PROC_BROWSER_TEST_F(ResourceCoordinatorRenderProcessProbeBrowserTest, TrackAndMeasureActiveRenderProcesses) { +#if defined(OS_WIN) + // TODO(https://crbug.com/833430): Spare-RPH-related failures when run with + // --site-per-process on Windows. + if (content::AreAllSitesIsolatedForTesting()) + return; +#endif // Ensure that the |resource_coordinator| service is enabled. base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures({features::kGlobalResourceCoordinator,
diff --git a/chrome/browser/resources/chromeos/arc_support/background.js b/chrome/browser/resources/chromeos/arc_support/background.js index 040ecfd..fc9371f 100644 --- a/chrome/browser/resources/chromeos/arc_support/background.js +++ b/chrome/browser/resources/chromeos/arc_support/background.js
@@ -991,6 +991,12 @@ overlayWebview.addEventListener('contentload', function() { overlay.classList.remove('overlay-loading'); }); + overlayWebview.addContentScripts([{ + name: 'postProcess', + matches: ['https://support.google.com/*'], + css: {files: ['overlay.css']}, + run_at: 'document_end' + }]); focusManager = new appWindow.contentWindow.ArcOptInFocusManager(); focusManager.initialize();
diff --git a/chrome/browser/resources/chromeos/arc_support/overlay.css b/chrome/browser/resources/chromeos/arc_support/overlay.css new file mode 100644 index 0000000..cff4f363 --- /dev/null +++ b/chrome/browser/resources/chromeos/arc_support/overlay.css
@@ -0,0 +1,11 @@ +/* Copyright 2018 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* Hide header for help articles that contains sign-in button, link to apps and + search bar. Also hide div of class promotion-container that has link to + YouTube */ +.hcfe .promotion-container, +.hcfe > header { + display: none; +}
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index 99412e0f..d3a8c99 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -108,7 +108,7 @@ <p>After2</p> <p>After3</p> </div> - <div id="live" aria-live="polite"></div> + <div id="live" aria-live="assertive"></div> <div id="delete" role="button">Delete</div> <script> document.getElementById('delete').addEventListener('click', function() { @@ -1343,7 +1343,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(function(root) {/*! <div><input value="test" type="text"></input></div> - <div id="live" aria-live="polite"></div> + <div id="live" aria-live="assertive"></div> <script> const input = document.querySelector('input'); const [div, live] = document.querySelectorAll('div');
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js index a227302..8838b3b3 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js
@@ -15,6 +15,7 @@ var RoleType = chrome.automation.RoleType; var TreeChange = chrome.automation.TreeChange; var TreeChangeObserverFilter = chrome.automation.TreeChangeObserverFilter; +var TreeChangeType = chrome.automation.TreeChangeType; /** * ChromeVox2 live region handler. @@ -43,6 +44,13 @@ * @private */ this.liveRegionNodeSet_ = new WeakSet(); + + /** + * A list of nodes that have changed as part of one atomic tree update. + * @private {!Array} + */ + this.changedNodes_ = []; + chrome.automation.addTreeChangeObserver( TreeChangeObserverFilter.LIVE_REGION_TREE_CHANGES, this.onTreeChange.bind(this)); @@ -105,15 +113,39 @@ var all = relevant.indexOf('all') >= 0; if (all || - (additions && (type == 'nodeCreated' || type == 'subtreeCreated'))) { - this.outputLiveRegionChange_(node, null); + (additions && + (type == TreeChangeType.NODE_CREATED || + type == TreeChangeType.SUBTREE_CREATED))) { + this.queueLiveRegionChange_(node); } - if (all || (text && type == 'textChanged')) - this.outputLiveRegionChange_(node, null); + if (all || (text && type == TreeChangeType.TEXT_CHANGED)) + this.queueLiveRegionChange_(node); - if (all || (removals && type == 'nodeRemoved')) + if (all || (removals && type == TreeChangeType.NODE_REMOVED)) this.outputLiveRegionChange_(node, '@live_regions_removed'); + + if (type == TreeChangeType.SUBTREE_UPDATE_END) + this.processQueuedTreeChanges_(); + }, + + /** + * @param {!AutomationNode} node + * @private + */ + queueLiveRegionChange_: function(node) { + this.changedNodes_.push(node); + }, + + /** + * @private + */ + processQueuedTreeChanges_: function() { + this.liveRegionNodeSet_ = new WeakSet(); + this.changedNodes_.forEach(function(node) { + this.outputLiveRegionChange_(node, null); + }.bind(this)); + this.changedNodes_ = []; }, /** @@ -129,10 +161,6 @@ if (node.containerLiveBusy) return; - var delta = new Date() - this.lastLiveRegionTime_; - if (delta > LiveRegions.LIVE_REGION_MIN_SAME_NODE_MS) - this.liveRegionNodeSet_ = new WeakSet(); - while (node.containerLiveAtomic && !node.liveAtomic && node.parent) node = node.parent; @@ -158,15 +186,15 @@ // Queue live regions coming from background tabs. var webView = AutomationUtil.getTopLevelRoot(node); webView = webView ? webView.parent : null; - var forceQueueForBackgroundedLiveRegion = - !webView || !webView.state.focused; + var forceQueue = !webView || !webView.state.focused || + node.containerLiveStatus == 'polite'; // Enqueue live region updates that were received at approximately // the same time, otherwise flush previous live region updates. var queueTime = LiveRegions.LIVE_REGION_QUEUE_TIME_MS; var currentTime = new Date(); var delta = currentTime - this.lastLiveRegionTime_; - if (delta > queueTime && !forceQueueForBackgroundedLiveRegion) + if (delta > queueTime && !forceQueue) output.withQueueMode(cvox.QueueMode.CATEGORY_FLUSH); else output.withQueueMode(cvox.QueueMode.QUEUE);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs index 5e90a7f5..518a750 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs
@@ -23,6 +23,7 @@ /** @override */ setUp: function() { window.RoleType = chrome.automation.RoleType; + window.TreeChangeType = chrome.automation.TreeChangeType; }, /** @@ -52,7 +53,7 @@ this.runWithLoadedTree( function() {/*! <h1>Document with live region</h1> - <p id="live" aria-live="polite"></p> + <p id="live" aria-live="assertive"></p> <button id="go">Go</button> <script> document.getElementById('go').addEventListener('click', function() { @@ -73,7 +74,7 @@ this.runWithLoadedTree( function() {/*! <h1>Document with live region</h1> - <p id="live" aria-live="polite" aria-relevant="removals">Hello, world</p> + <p id="live" aria-live="assertive" aria-relevant="removals">Hello, world</p> <button id="go">Go</button> <script> document.getElementById('go').addEventListener('click', function() { @@ -95,7 +96,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <div id="live" aria-live="polite" aria-atomic="true"> + <div id="live" aria-live="assertive" aria-atomic="true"> <div></div><div>Bravo</div><div></div> </div> <button id="go">Go</button> @@ -120,7 +121,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <h1 aria-atomic="true" id="live"aria-live="polite">foo</h1> + <h1 aria-atomic="true" id="live"aria-live="assertive">foo</h1> <button id="go">go</button> <script> document.getElementById('go').addEventListener('click', function(e) { @@ -146,7 +147,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <div id="live" aria-live="polite"> + <div id="live" aria-live="assertive"> <img id="img" src="#" alt="Before"> </div> <button id="go">Go</button> @@ -169,7 +170,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <div id="live" aria-live="polite"></div> + <div id="live" aria-live="assertive"></div> <button id="go">Go</button> <button id="focus">Focus</button> <script> @@ -194,7 +195,7 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <div id="live" aria-live="polite"></div> + <div id="live" aria-live="assertive"></div> <button id="go">Go</button> <button id="focus">Focus</button> <script> @@ -222,8 +223,8 @@ var mockFeedback = this.createMockFeedback(); this.runWithLoadedTree( function() {/*! - <div id="live1" aria-live="polite"></div> - <div id="live2" aria-live="polite"></div> + <div id="live1" aria-live="assertive"></div> + <div id="live2" aria-live="assertive"></div> <button id="go">Go</button> <button id="focus">Focus</button> <script> @@ -249,7 +250,7 @@ this.runWithLoadedTree(function() {/*! <p>start</p> <button>first</button> - <div role="button" id="live" aria-live="polite"> + <div role="button" id="live" aria-live="assertive"> hello! </div> <script> @@ -272,3 +273,33 @@ mockFeedback.replay(); }); }); + +TEST_F('LiveRegionsTest', 'SimulateTreeChanges', function() { + var mockFeedback = this.createMockFeedback(); + this.runWithLoadedTree(function() {/*! + <button></button> + <div aria-live="assertive"> + <p>hello</p><p>there</p> + </div> + */}, + function(root) { + var live = new LiveRegions(ChromeVoxState.instance); + var t1, t2; + [t1, t2] = root.findAll({role: RoleType.STATIC_TEXT}); + mockFeedback.call(function() { + live.onTreeChange({type: TreeChangeType.TEXT_CHANGED, target: t2}); + live.onTreeChange({type: TreeChangeType.SUBTREE_UPDATE_END, target: t2}); + }) + .expectNextSpeechUtteranceIsNot('hello') + .expectSpeech('there') + .clearPendingOutput() + mockFeedback.call(function() { + live.onTreeChange({type: TreeChangeType.TEXT_CHANGED, target: t1}); + live.onTreeChange({type: TreeChangeType.TEXT_CHANGED, target: t2}); + live.onTreeChange({type: TreeChangeType.SUBTREE_UPDATE_END, target: t2}); + }) + .expectSpeech('hello') + .expectSpeech('there'); + mockFeedback.replay(); + }); +});
diff --git a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js index f72794d..c77a14ce 100644 --- a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js +++ b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js
@@ -97,6 +97,12 @@ overlayUrl.addEventListener('contentload', function() { overlayUrl.classList.remove('overlay-loading'); }); + overlayUrl.addContentScripts([{ + name: 'postProcess', + matches: ['https://support.google.com/*'], + css: {files: ['overlay.css']}, + run_at: 'document_end' + }]); // Update the screen size after setup layout. if (Oobe.getInstance().currentScreen === this)
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/button_bar.html b/chrome/browser/resources/chromeos/multidevice_setup/button_bar.html new file mode 100644 index 0000000..7db0578 --- /dev/null +++ b/chrome/browser/resources/chromeos/multidevice_setup/button_bar.html
@@ -0,0 +1,37 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="i18n_setup.html"> + + +<dom-module id="button-bar"> + <template> + <style include="paper-button-style cr-shared-style"> + :host { + display: flex; + justify-content: flex-end; + } + + paper-button { + text-transform: none; + } + </style> + <paper-button + id="backward" + on-tap="onBackwardButtonTapped_" + class="cancel-button" + hidden$="[[!backwardButtonText]]"> + [[backwardButtonText]] + </paper-button> + <paper-button + id="forward" + on-tap="onForwardButtonTapped_" + class="action-button" + hidden$="[[!forwardButtonText]]"> + [[forwardButtonText]] + </paper-button> + </template> + <script src="button_bar.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/button_bar.js b/chrome/browser/resources/chromeos/multidevice_setup/button_bar.js new file mode 100644 index 0000000..85d76c56 --- /dev/null +++ b/chrome/browser/resources/chromeos/multidevice_setup/button_bar.js
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * DOM Element containing (page-dependent) navigation buttons for the + * MultiDevice Setup WebUI. + */ +Polymer({ + is: 'button-bar', + + properties: { + /** + * Translated text to display on the forward-naviation button. + * + * Undefined if the visible page has no forward-navigation button. + * + * @type {string|undefined} + */ + forwardButtonText: String, + + /** + * Translated text to display on the backward-naviation button. + * + * Undefined if the visible page has no backward-navigation button. + * + * @type {string|undefined} + */ + backwardButtonText: String, + }, + + /** @private */ + onForwardButtonTapped_: function() { + this.fire('forward-navigation-requested'); + }, + + /** @private */ + onBackwardButtonTapped_: function() { + this.fire('backward-navigation-requested'); + }, +});
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.html b/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.html index 931808b..1a749867 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.html
@@ -1,3 +1,4 @@ <link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <script src="button_navigation_behavior.js"></script>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.js b/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.js index 3d56bf9..85b5ac2 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/button_navigation_behavior.js
@@ -3,12 +3,67 @@ // found in the LICENSE file. /** @polymerBehavior */ -const ButtonNavigationBehavior = { +const ButtonNavigationBehaviorImpl = { properties: { - /** @type {string|undefined} */ - forwardButtonText: String, + /** + * ID for forward button label, which must be translated for display. + * + * Undefined if the visible page has no forward-navigation button. + * + * @type {string|undefined} + */ + forwardButtonTextId: String, - /** @type {string|undefined} */ - backwardButtonText: String, + /** + * ID for backward button label, which must be translated for display. + * + * Undefined if the visible page has no backward-navigation button. + * + * @type {string|undefined} + */ + backwardButtonTextId: String, + + /** + * Translated text to display on the forward-naviation button. + * + * Undefined if the visible page has no forward-navigation button. + * + * @type {string|undefined} + */ + forwardButtonText: { + type: String, + computed: 'computeButtonText_(forwardButtonTextId)', + }, + + /** + * Translated text to display on the backward-naviation button. + * + * Undefined if the visible page has no backward-navigation button. + * + * @type {string|undefined} + */ + backwardButtonText: { + type: String, + computed: 'computeButtonText_(backwardButtonTextId)', + }, + }, + + /** + * @param {string} buttonTextId Key for the localized string to appear on a + * button. + * @return {string|undefined} The localized string corresponding to the key + * buttonTextId. Return value is undefined if buttonTextId is not a key + * for any localized string. Note: this includes the case in which + * buttonTextId is undefined. + * @private + */ + computeButtonText_(buttonTextId) { + return this.i18nExists(buttonTextId) ? this.i18n(buttonTextId) : undefined; }, }; + +/** @polymerBehavior */ +const ButtonNavigationBehavior = [ + I18nBehavior, + ButtonNavigationBehaviorImpl, +];
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp b/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp index af3b93cc..4fa64d95 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp
@@ -1,43 +1,62 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +#Copyright 2018 The Chromium Authors.All rights reserved. +#Use of this source code is governed by a BSD - style license that can be +#found in the LICENSE file. { - 'targets': [ + 'targets' : [ { - 'target_name': 'button_navigation_behavior', - 'dependencies': [], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'target_name' : 'button_bar', + 'dependencies' : [], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'multidevice_setup', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + 'target_name' : 'button_navigation_behavior', + 'dependencies' : [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - 'button_navigation_behavior', - 'setup_failed_page', - 'setup_succeeded_page', - 'start_setup_page', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'setup_failed_page', - 'dependencies': ['button_navigation_behavior'], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'target_name' : 'multidevice_setup', + 'dependencies' : [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + 'button_bar', + 'start_setup_page', + 'setup_succeeded_page', + 'setup_failed_page', + ], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'setup_succeeded_page', - 'dependencies': ['button_navigation_behavior'], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'target_name' : 'setup_failed_page', + 'dependencies' : [ + 'button_navigation_behavior', + ], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { - 'target_name': 'start_setup_page', - 'dependencies': ['button_navigation_behavior'], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'target_name' : 'setup_succeeded_page', + 'dependencies' : [ + 'button_navigation_behavior', + ], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + + { + 'target_name' : 'start_setup_page', + 'dependencies' : [ + 'button_navigation_behavior', + ], + 'includes' : + ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, ], }
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/i18n_setup.html b/chrome/browser/resources/chromeos/multidevice_setup/i18n_setup.html new file mode 100644 index 0000000..b1bc3de --- /dev/null +++ b/chrome/browser/resources/chromeos/multidevice_setup/i18n_setup.html
@@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/html/load_time_data.html"> + +<script src="strings.js"></script>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.html b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.html index c12690dd..2a0752b7 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html"> +<link rel="import" href="button_bar.html"> <link rel="import" href="button_navigation_behavior.html"> <link rel="import" href="setting_up_page.html"> <link rel="import" href="setup_failed_page.html"> @@ -10,14 +11,19 @@ <dom-module id="multidevice-setup"> <template> - <iron-pages id="pages" attr-for-selected="is" - selected="[[visiblePageName_]]" selected-item="{{visiblePage_}}"> + <iron-pages + id="pages" + attr-for-selected="is" + selected="[[visiblePageName_]]" + selected-item="{{visiblePage_}}"> <setup-failed-page></setup-failed-page> <setup-succeeded-page></setup-succeeded-page> <start-setup-page></start-setup-page> </iron-pages> - <div>Forward Button: [[visiblePage_.forwardButtonText]]</div> - <div>Backward Button: [[visiblePage_.backwardButtonText]]</div> + <button-bar + forward-button-text="[[visiblePage_.forwardButtonText]]" + backward-button-text="[[visiblePage_.backwardButtonText]]"> + </button-bar> </template> <script src="multidevice_setup.js"></script> </dom-module>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.js b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.js index f4f40a07..a7265e6 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup.js
@@ -2,67 +2,105 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @polymer */ -Polymer({ - is: 'multidevice-setup', +cr.define('multidevice_setup', function() { + /** @enum {string} */ + const PageName = { + FAILURE: 'setup-failed-page', + SUCCESS: 'setup-succeeded-page', + START: 'start-setup-page', + }; - properties: { - /** - * Array of objects representing all available MultiDevice hosts. Each - * object contains the name of the device type (e.g. "Pixel XL") and its - * Device ID. - * - * @private - * @type {Array<{name: string, id: string}>} - */ - devices_: Array, + const MultiDeviceSetup = Polymer({ + is: 'multidevice-setup', - /** - * Element name of the currently visible page. - * - * @private - * @type {string} - */ - visiblePageName_: { - type: String, - value: 'start-setup-page', + properties: { + /** + * Array of objects representing all available MultiDevice hosts. Each + * object contains the name of the device type (e.g. "Pixel XL") and its + * Device ID. + * + * @private {Array<{name: string, id: string}>} + */ + devices_: Array, + + /** + * Element name of the currently visible page. + * + * @private {!PageName} + */ + visiblePageName_: { + type: String, + value: PageName.START, + }, + + /** + * DOM Element corresponding to the visible page. + * + * @private {!StartSetupPageElement|!SetupSucceededPageElement| + * !SetupFailedPageElement} + */ + visiblePage_: { + type: Object, + // Note: This notification is for testing purposes. + notify: true, + }, + + /** + * Device ID for the currently selected host device. + * + * Undefined if the no list of potential hosts has been received from mojo + * service. + * + * @private {string|undefined} + */ + selectedDeviceId_: String, }, - /** - * DOM Element corresponding to the visible page. - * - * @private - * @type {!SetupFailedPageElement|!SetupSucceededPageElement| - * !StartSetupPageElement} - */ - visiblePage_: Object, + listeners: { + 'forward-navigation-requested': 'onForwardNavigationRequested_', + 'backward-navigation-requested': 'onBackwardNavigationRequested_', + }, - /** - * Device ID for the currently selected host device. - * - * Undefined if the no list of potential hosts has been received from - * CryptAuth. - * - * @private - * @type {string|undefined} - */ - selectedDeviceId_: String, - }, + // Instance methods - listeners: { - 'forward-navigation-requested': 'onForwardNavigationRequested_', - 'backward-navigation-requested': 'onBackwardNavigationRequested_', - }, + closeUi_: function() { + // TODO(jordynass): Implement closing UI. + console.log('Closing WebUI'); + // This method is just for testing that the method was called + this.fire('ui-closed'); + }, - // Event handling callbacks + // Event handling callbacks - /** @private */ - onForwardNavigationRequested_: function() { - // TODO(jordynass): Put in page specific logic as each page is implemented. - }, + /** @private */ + onForwardNavigationRequested_: function() { + switch (this.visiblePageName_) { + case PageName.FAILURE: + this.visiblePageName_ = PageName.START; + break; + case PageName.SUCCESS: + this.closeUi_(); + break; + case PageName.START: + // TODO(jordynass): Once mojo API is complete, this should call + // SetBetterTogetherHost(selectedDeviceId) + console.log('Calling SetBetterTogetherHost(selectedDeviceId)'); + } + }, - /** @private */ - onBackwardNavigationRequested_: function() { - // TODO(jordynass): Put in page specific logic as each page is implemented. - }, + /** @private */ + onBackwardNavigationRequested_: function() { + switch (this.visiblePageName_) { + case PageName.FAILURE: + this.closeUi_(); + break; + case PageName.START: + this.closeUi_(); + } + }, + }); + + return { + MultiDeviceSetup: MultiDeviceSetup, + }; });
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd index aeeb1307..a10e30a 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd +++ b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd
@@ -12,12 +12,21 @@ </outputs> <release seq="1"> <structures> + <structure name="IDR_MULTIDEVICE_SETUP_BUTTON_BAR_HTML" + file="button_bar.html" + type="chrome_html" /> + <structure name="IDR_MULTIDEVICE_SETUP_BUTTON_BAR_JS" + file="button_bar.js" + type="chrome_html" /> <structure name="IDR_MULTIDEVICE_SETUP_BUTTON_NAVIGATION_BEHAVIOR_HTML" file="button_navigation_behavior.html" type="chrome_html" /> <structure name="IDR_MULTIDEVICE_SETUP_BUTTON_NAVIGATION_BEHAVIOR_JS" file="button_navigation_behavior.js" type="chrome_html" /> + <structure name="IDR_MULTIDEVICE_SETUP_I18N_SETUP_HTML" + file="i18n_setup.html" + type="chrome_html" /> <structure name="IDR_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_HTML" file="multidevice_setup_dialog.html" flattenhtml="true"
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.html b/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.html index 210c172..f8ecec6 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.html
@@ -5,7 +5,7 @@ <dom-module id="setup-failed-page"> <template> - Setup Failed Placeholder Text + --------------Setup Failed Placeholder Text-------------- </template> <script src="setup_failed_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.js b/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.js index 6eb5b503..1c88f612 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/setup_failed_page.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @polymer */ Polymer({ is: 'setup-failed-page', @@ -10,17 +9,17 @@ /** * Overriden from ButtonNavigationBehavior */ - forwardButtonText: { + forwardButtonTextId: { type: String, - value: 'Try again', + value: 'tryAgain', }, /** * Overriden from ButtonNavigationBehavior */ - backwardButtonText: { + backwardButtonTextId: { type: String, - value: 'Cancel', + value: 'cancel', }, },
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.html b/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.html index 34fac6f6e..d45962c 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.html
@@ -5,7 +5,7 @@ <dom-module id="setup-succeeded-page"> <template> - Setup Succeeded Placeholder Text + --------------Setup Succeeded Placeholder Text-------------- </template> <script src="setup_succeeded_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.js b/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.js index 039b105..b116d70 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/setup_succeeded_page.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @polymer */ Polymer({ is: 'setup-succeeded-page', @@ -10,9 +9,9 @@ /** * Overriden from ButtonNavigationBehavior */ - forwardButtonText: { + forwardButtonTextId: { type: String, - value: 'Done', + value: 'done', }, },
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.html b/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.html index e6135ff..9aab421 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.html
@@ -5,7 +5,7 @@ <dom-module id="start-setup-page"> <template> - Start Setup Placeholder Text + --------------Start Setup Placeholder Text-------------- </template> <script src="start_setup_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.js b/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.js index ed6de3c..1d199a8 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/start_setup_page.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @polymer */ Polymer({ is: 'start-setup-page', @@ -10,17 +9,17 @@ /** * Overriden from ButtonNavigationBehavior */ - forwardButtonText: { + forwardButtonTextId: { type: String, - value: 'Accept', + value: 'accept', }, /** * Overriden from ButtonNavigationBehavior */ - backwardButtonText: { + backwardButtonTextId: { type: String, - value: 'Cancel', + value: 'cancel', }, },
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd index fccd3d7..e5765f69 100644 --- a/chrome/browser/resources/component_extension_resources.grd +++ b/chrome/browser/resources/component_extension_resources.grd
@@ -88,6 +88,7 @@ <include name="IDR_FIRST_RUN_DIALOG_ICON_256" file="chromeos/first_run/app/icon/256.png" type="BINDATA" /> <include name="IDR_ARC_SUPPORT_BACKGROUND_JS" file="chromeos/arc_support/background.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_ARC_SUPPORT_MAIN_CSS" file="chromeos/arc_support/main.css" type="BINDATA" /> + <include name="IDR_ARC_SUPPORT_OVERLAY_CSS" file="chromeos/arc_support/overlay.css" type="BINDATA" /> <include name="IDR_ARC_SUPPORT_PLAYSTORE_CSS" file="chromeos/arc_support/playstore.css" type="BINDATA" /> <include name="IDR_ARC_SUPPORT_PLAYSTORE_JS" file="chromeos/arc_support/playstore.js" type="BINDATA" /> <include name="IDR_ARC_SUPPORT_PLAYSTORE_LOGO" file="chromeos/arc_support/icon/playstore.svg" type="BINDATA" />
diff --git a/chrome/browser/resources/extensions/OWNERS b/chrome/browser/resources/extensions/OWNERS deleted file mode 100644 index 9f96570..0000000 --- a/chrome/browser/resources/extensions/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -finnur@chromium.org -rdevlin.cronin@chromium.org - -# TEAM: extensions-dev@chromium.org -# COMPONENT: Platform>Extensions
diff --git a/chrome/browser/resources/extensions/apps_developer_tools_promo_48.png b/chrome/browser/resources/extensions/apps_developer_tools_promo_48.png deleted file mode 100644 index 462bc9a..0000000 --- a/chrome/browser/resources/extensions/apps_developer_tools_promo_48.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html b/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html deleted file mode 100644 index d6137cf..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html +++ /dev/null
@@ -1,19 +0,0 @@ -<div id="kiosk-disable-bailout-confirm-overlay" class="page"> - <div class="close-button"></div> - <div class="content-area"> - <p id="kiosk-disable-bailout-warning-bold"> - $i18n{kioskDisableBailoutShortcutWarningBold} - </p> - <p>$i18n{kioskDisableBailoutShortcutWarning}</p> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="kiosk-disable-bailout-cancel-button"> - $i18n{kioskDisableBailoutShortcutCancel} - </button> - <button id="kiosk-disable-bailout-confirm-button"> - $i18n{kioskDisableBailoutShortcutConfirm} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js b/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js deleted file mode 100644 index 89c628b3..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - /** - * A confirmation overlay for disabling kiosk app bailout shortcut. - * @constructor - */ - function KioskDisableBailoutConfirm() { - } - - cr.addSingletonGetter(KioskDisableBailoutConfirm); - - KioskDisableBailoutConfirm.prototype = { - /** - * Initialize the page. - */ - initialize: function() { - var overlay = $('kiosk-disable-bailout-confirm-overlay'); - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleCancel); - - var el = $('kiosk-disable-bailout-shortcut'); - el.addEventListener('change', this.handleDisableBailoutShortcutChange_); - - $('kiosk-disable-bailout-confirm-button').onclick = function(e) { - extensions.ExtensionSettings.showOverlay($('kiosk-apps-page')); - chrome.send('setDisableBailoutShortcut', [true]); - }; - $('kiosk-disable-bailout-cancel-button').onclick = this.handleCancel; - }, - - /** Handles overlay being canceled. */ - handleCancel: function() { - extensions.ExtensionSettings.showOverlay($('kiosk-apps-page')); - $('kiosk-disable-bailout-shortcut').checked = false; - }, - - /** - * Custom change handler for the disable bailout shortcut checkbox. - * It blocks the underlying pref being changed and brings up confirmation - * alert to user. - * @private - */ - handleDisableBailoutShortcutChange_: function() { - // Just set the pref if user un-checks the box. - if (!$('kiosk-disable-bailout-shortcut').checked) { - chrome.send('setDisableBailoutShortcut', [false]); - return false; - } - - // Otherwise, show the confirmation overlay. - extensions.ExtensionSettings.showOverlay($( - 'kiosk-disable-bailout-confirm-overlay')); - return true; - } - }; - - // Export - return { - KioskDisableBailoutConfirm: KioskDisableBailoutConfirm - }; -}); -
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js b/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js deleted file mode 100644 index d9278409..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * The type of the app data object. The definition is based on - * chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc: - * PopulateAppDict() - * @typedef {{id: string, - * name: string, - * iconURL: string, - * autoLaunch: boolean, - * isLoading: boolean}} - */ -var AppDict; - -cr.define('extensions', function() { - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * Creates a list for showing kiosk apps. - * @constructor - * @extends {cr.ui.List} - */ - var KioskAppList = cr.ui.define('list'); - - KioskAppList.prototype = { - __proto__: List.prototype, - - /** - * True if auto launch feature can be configured. - * @type {?boolean} - */ - autoLaunchEnabled_: false, - - /** @override */ - createItem: function(app) { - var item = new KioskAppListItem(); - item.data = app; - item.autoLaunchEnabled = this.autoLaunchEnabled_; - return item; - }, - - /** - * Sets auto launch enabled flag. - * @param {boolean} enabled True if auto launch should be enabled. - */ - setAutoLaunchEnabled: function(enabled) { - this.autoLaunchEnabled_ = enabled; - }, - - /** - * Loads the given list of apps. - * @param {!Array<!Object>} apps An array of app info objects. - */ - setApps: function(apps) { - this.dataModel = new ArrayDataModel(apps); - }, - - /** - * Updates the given app. - * @param {!AppDict} app An app info object. - */ - updateApp: function(app) { - for (var i = 0; i < this.items.length; ++i) { - if (this.items[i].data.id == app.id) { - this.items[i].data = app; - break; - } - } - } - }; - - /** - * Creates a list item for a kiosk app. - * @constructor - * @extends {cr.ui.ListItem} - */ - var KioskAppListItem = cr.ui.define(function() { - var el = $('kiosk-app-list-item-template').cloneNode(true); - el.removeAttribute('id'); - el.hidden = false; - return el; - }); - - KioskAppListItem.prototype = { - __proto__: ListItem.prototype, - - /** - * Data object to hold app info. - * @type {Object} - * @private - */ - data_: null, - - get data() { - assert(this.data_); - return this.data_; - }, - - set data(data) { - this.data_ = data; - this.redraw(); - }, - - set autoLaunchEnabled(enabled) { - this.querySelector('.enable-auto-launch-button').hidden = !enabled; - this.querySelector('.disable-auto-launch-button').hidden = !enabled; - }, - - /** - * Getter for the icon element. - * @type {Element} - */ - get icon() { - return this.querySelector('.kiosk-app-icon'); - }, - - /** - * Getter for the name element. - * @type {Element} - */ - get name() { - return this.querySelector('.kiosk-app-name'); - }, - - /** - * Getter for the status text element. - * @type {Element} - */ - get status() { - return this.querySelector('.kiosk-app-status'); - }, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - - var sendMessageWithId = function(msg) { - return function() { - chrome.send(msg, [this.data.id]); - }.bind(this); - }.bind(this); - - this.querySelector('.enable-auto-launch-button').onclick = - sendMessageWithId('enableKioskAutoLaunch'); - this.querySelector('.disable-auto-launch-button').onclick = - sendMessageWithId('disableKioskAutoLaunch'); - this.querySelector('.row-delete-button').onclick = - sendMessageWithId('removeKioskApp'); - }, - - /** - * Updates UI from app info data. - */ - redraw: function() { - this.icon.classList.toggle('spinner', this.data.isLoading); - this.icon.style.backgroundImage = 'url(' + this.data.iconURL + ')'; - - this.name.textContent = this.data.name || this.data.id; - this.status.textContent = this.data.autoLaunch ? - loadTimeData.getString('autoLaunch') : ''; - - this.autoLaunch = this.data.autoLaunch; - } - }; - - /** - * True if the app represented by this item will auto launch. - */ - cr.defineProperty(KioskAppListItem, 'autoLaunch', cr.PropertyKind.BOOL_ATTR); - - // Export - return { - KioskAppList: KioskAppList - }; -});
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_apps.css b/chrome/browser/resources/extensions/chromeos/kiosk_apps.css deleted file mode 100644 index e16c782..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_apps.css +++ /dev/null
@@ -1,155 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#kiosk-apps-page .checkbox { - display: block; -} - -#kiosk-app-list { - border: 1px solid lightgrey; - height: 200px; - margin-bottom: 5px; -} - -#kiosk-app-list > * { - -webkit-box-align: center; - box-sizing: border-box; - display: -webkit-box; - height: 32px; -} - -/* TODO(xiyuan): The .row-delete-button rules probably should live somewhere - * else and be shared with options.css */ -list .row-delete-button { - background-color: transparent; - background-image: -webkit-image-set( - url(../../../../../ui/resources/default_100_percent/close_2.png) 1x, - url(../../../../../ui/resources/default_200_percent/close_2.png) 2x); - border: none; - display: block; - height: 16px; - opacity: 1; - transition: 150ms opacity; - width: 16px; -} - -list > *:not(:hover):not([selected]):not([lead]) .row-delete-button, -list:not([has-element-focus]) > *:not(:hover):not([selected]) - .row-delete-button, -list[disabled] .row-delete-button, -list .row-delete-button[disabled] { - opacity: 0; - pointer-events: none; -} - -list .row-delete-button:hover { - background-image: -webkit-image-set( - url(../../../../../ui/resources/default_100_percent/close_2_hover.png) - 1x, - url(../../../../../ui/resources/default_200_percent/close_2_hover.png) - 2x); -} - -list .row-delete-button:active { - background-image: -webkit-image-set( - url(../../../../../ui/resources/default_100_percent/close_2_pressed.png) - 1x, - url(../../../../../ui/resources/default_200_percent/close_2_pressed.png) - 2x); -} - -.controlled-setting-with-label > input:disabled + span label { - color: #999; -} - -#kiosk-app-id-edit-row { - -webkit-justify-content: space-between; - display: -webkit-flex; - width: 510px; -} - -#kiosk-app-id-edit, -#kiosk-app-add { - display: block; -} - -#kiosk-app-id-edit { - -webkit-flex-grow: 1; - -webkit-margin-end: 10px; -} - -#kiosk-apps-error-banner { - background-color: rgb(223, 165, 165); - margin: 2px 0; - opacity: 0; - padding: 5px; - transition: opacity 150ms; - visibility: hidden; - white-space: nowrap; - width: 100%; -} - -#kiosk-apps-error-banner.visible { - opacity: 1; - visibility: visible; -} - -.kiosk-app-list-item { - white-space: nowrap; -} - -.kiosk-app-list-item .space-filler { - -webkit-box-flex: 1; -} - -.kiosk-app-icon, -.kiosk-app-name, -.kiosk-app-status { - display: inline-block; - vertical-align: middle; -} - -.kiosk-app-icon { - background-size: 100%; - height: 16px; - width: 16px; -} - -.kiosk-app-icon.spinner { - background-image: url(chrome://resources/images/throbber_small.svg) - !important; -} - -.kiosk-app-name, -.kiosk-app-status { - overflow: hidden; - text-overflow: ellipsis; -} - -.kiosk-app-name { - max-width: 250px; -} - -.kiosk-app-status { - -webkit-margin-start: 8px; - max-width: 120px; -} - -.disable-auto-launch-button, -.enable-auto-launch-button { - display: none; -} - -.kiosk-app-list-item[auto-launch]:hover .disable-auto-launch-button, -.kiosk-app-list-item:not([auto-launch]):hover .enable-auto-launch-button { - display: inline-block; -} - -#kiosk-disable-bailout-confirm-overlay { - width: 250px -} - -#kiosk-disable-bailout-warning-bold { - font-weight: bold; -}
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_apps.html b/chrome/browser/resources/extensions/chromeos/kiosk_apps.html deleted file mode 100644 index 0056e78..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_apps.html +++ /dev/null
@@ -1,53 +0,0 @@ -<div id="kiosk-apps-page" class="page"> - <div class="close-button"></div> - <h1>$i18n{kioskOverlayTitle}</h1> - <div class="content-area"> - <div class="option"> - <list id="kiosk-app-list"></list> - <div id="kiosk-apps-error-banner"> - <span class="kiosk-app-name"></span> - <span class="kiosk-app-status">$i18n{invalidApp}</span> - </div> - <label for="kiosk-app-id-edit"> - <span>$i18n{addKioskApp}</span> - </label> - <div id="kiosk-app-id-edit-row"> - <input id="kiosk-app-id-edit" type="text" - i18n-values="placeholder:kioskAppIdEditHint"> - <button id="kiosk-app-add">$i18n{add}</button> - </div> - <div class="checkbox"> - <span class="controlled-setting-with-label"> - <input id="kiosk-disable-bailout-shortcut" type="checkbox"> - <span> - <label for="kiosk-disable-bailout-shortcut"> - $i18n{kioskDiableBailoutShortcutLabel} - </label> - </span> - </span> - </div> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="kiosk-options-overlay-confirm">$i18n{done}</button> - </div> - </div> - - <div id="kiosk-app-list-item-template" class="kiosk-app-list-item" hidden> - <div class="content"> - <span class="kiosk-app-icon"></span> - <span class="kiosk-app-name"></span> - <span class="kiosk-app-status"></span> - </div> - <div class="space-filler"></div> - <button class="enable-auto-launch-button"> - $i18n{enableAutoLaunchButton} - </button> - <button class="disable-auto-launch-button"> - $i18n{disableAutoLaunchButton} - </button> - <button class="raw-button custom-appearance row-delete-button"> - </button> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/chromeos/kiosk_apps.js b/chrome/browser/resources/extensions/chromeos/kiosk_apps.js deleted file mode 100644 index 3052f55..0000000 --- a/chrome/browser/resources/extensions/chromeos/kiosk_apps.js +++ /dev/null
@@ -1,164 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - /** - * Encapsulated handling of ChromeOS kiosk apps options page. - * @constructor - */ - function KioskAppsOverlay() { - } - - cr.addSingletonGetter(KioskAppsOverlay); - - KioskAppsOverlay.prototype = { - /** - * Clear error timer id. - * @type {?number} - */ - clearErrorTimer_: null, - - /** @private {WebUIListenerTracker} */ - listenerTracker_: null, - - /** - * Initialize the page. - */ - initialize: function() { - this.listenerTracker_ = new WebUIListenerTracker(); - - cr.sendWithPromise('initializeKioskAppSettings') - .then(KioskAppsOverlay.enableKiosk); - - extensions.KioskAppList.decorate($('kiosk-app-list')); - - var overlay = $('kiosk-apps-page'); - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); - - $('kiosk-options-overlay-confirm').onclick = - this.handleDismiss_.bind(this); - $('kiosk-app-id-edit').addEventListener('keypress', - this.handleAppIdInputKeyPressed_.bind(this)); - $('kiosk-app-add').onclick = this.handleAddButtonClick_.bind(this); - }, - - /* - * Invoked when the page is shown. - */ - didShowPage: function() { - this.listenerTracker_.add( - 'kiosk-app-settings-changed', KioskAppsOverlay.setSettings); - this.listenerTracker_.add( - 'kiosk-app-updated', KioskAppsOverlay.updateApp); - this.listenerTracker_.add('kiosk-app-error', KioskAppsOverlay.showError); - - cr.sendWithPromise('getKioskAppSettings') - .then(KioskAppsOverlay.setSettings); - $('kiosk-app-id-edit').focus(); - }, - - /** - * Shows error for given app name/id and schedules it to cleared. - * @param {!string} appName App name/id to show in error banner. - */ - showError: function(appName) { - var errorBanner = $('kiosk-apps-error-banner'); - var appNameElement = errorBanner.querySelector('.kiosk-app-name'); - appNameElement.textContent = appName; - errorBanner.classList.add('visible'); - - if (this.clearErrorTimer_) - window.clearTimeout(this.clearErrorTimer_); - - // Sets a timer to clear out error banner after 5 seconds. - this.clearErrorTimer_ = window.setTimeout(function() { - errorBanner.classList.remove('visible'); - this.clearErrorTimer_ = null; - }.bind(this), 5000); - }, - - /** - * Handles keypressed event in the app id input element. - * @private - */ - handleAppIdInputKeyPressed_: function(e) { - if (e.key == 'Enter' && e.target.value) - this.handleAddButtonClick_(); - }, - - /** - * Handles click event on the add button. - * @private - */ - handleAddButtonClick_: function() { - var appId = $('kiosk-app-id-edit').value; - if (!appId) - return; - - chrome.send('addKioskApp', [appId]); - $('kiosk-app-id-edit').value = ''; - }, - - /** - * Handles the overlay being dismissed. - * @private - */ - handleDismiss_: function() { - this.handleAddButtonClick_(); - extensions.ExtensionSettings.showOverlay(null); - this.listenerTracker_.removeAll(); - } - }; - - /** - * Sets apps to be displayed in kiosk-app-list. - * @param {!Object<{apps: !Array<AppDict>, disableBailout: boolean, - * hasAutoLaunchApp: boolean}>} settings An object containing an array of - * app info objects and disable bailout shortcut flag. - */ - KioskAppsOverlay.setSettings = function(settings) { - /** @type {extensions.KioskAppList} */ ($('kiosk-app-list')) - .setApps(settings.apps); - $('kiosk-disable-bailout-shortcut').checked = settings.disableBailout; - $('kiosk-disable-bailout-shortcut').disabled = !settings.hasAutoLaunchApp; - }; - - /** - * Update an app in kiosk-app-list. - * @param {!AppDict} app App info to be updated. - */ - KioskAppsOverlay.updateApp = function(app) { - /** @type {extensions.KioskAppList} */ ($('kiosk-app-list')).updateApp(app); - }; - - /** - * Shows error for given app name/id. - * @param {!string} appName App name/id to show in error banner. - */ - KioskAppsOverlay.showError = function(appName) { - KioskAppsOverlay.getInstance().showError(appName); - }; - - /** - * Enables consumer kiosk. - * @param {!{kioskEnabled: boolean, autoLaunchEnabled: boolean}} params - */ - KioskAppsOverlay.enableKiosk = function(params) { - $('add-kiosk-app').hidden = !params.kioskEnabled; - $('kiosk-disable-bailout-shortcut').parentNode.hidden = - !params.autoLaunchEnabled; - /** @type {extensions.KioskAppList} */ ($('kiosk-app-list')) - .setAutoLaunchEnabled(params.autoLaunchEnabled); - }; - - // Export - return { - KioskAppsOverlay: KioskAppsOverlay - }; -}); - -// <include src="kiosk_app_list.js"> -// <include src="kiosk_app_disable_bailout_confirm.js">
diff --git a/chrome/browser/resources/extensions/compiled_resources2.gyp b/chrome/browser/resources/extensions/compiled_resources2.gyp deleted file mode 100644 index 060505c..0000000 --- a/chrome/browser/resources/extensions/compiled_resources2.gyp +++ /dev/null
@@ -1,66 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -{ - 'targets': [ - { - 'target_name': 'extensions', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:webui_listener_tracker', - ], - 'variables': { - 'script_args': ['--custom_sources'], - 'source_files': [ - '<(DEPTH)/ui/webui/resources/js/promise_resolver.js', - '<(DEPTH)/ui/webui/resources/js/load_time_data.js', - '<(DEPTH)/ui/webui/resources/js/parse_html_subset.js', - '<(DEPTH)/ui/webui/resources/js/cr.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/array_data_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_outline_manager.js', - 'extension_loader.js', - '<(DEPTH)/ui/webui/resources/js/util.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_manager.js', - 'extension_focus_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_item.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_row.js', - 'extension_options_overlay.js', - '<(DEPTH)/third_party/closure_compiler/externs/management.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_controller.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/alert_overlay.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_grid.js', - 'chromeos/kiosk_apps.js', - '<(DEPTH)/ui/webui/resources/js/assert.js', - 'extension_commands_overlay.js', - 'extensions.js', - 'extension_list.js', - 'chromeos/kiosk_app_disable_bailout_confirm.js', - 'focus_row.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble_button.js', - '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', - '<(DEPTH)/third_party/jstemplate/util.js', - 'extension_error.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui.js', - '<(DEPTH)/ui/webui/resources/js/event_tracker.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/overlay.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/drag_wrapper.js', - 'extension_code.js', - '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', - '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', - 'extension_command_list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/controlled_indicator.js', - 'extension_error_overlay.js', - '../md_extensions/drag_and_drop_handler.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_model.js', - '<(DEPTH)/third_party/jstemplate/jstemplate.js', - 'chromeos/kiosk_app_list.js', - '<(DEPTH)/third_party/closure_compiler/externs/developer_private.js', - '../md_extensions/shortcut_util.js', - 'pack_extension_overlay.js', - ], - }, - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - } - ] -}
diff --git a/chrome/browser/resources/extensions/extension_code.js b/chrome/browser/resources/extensions/extension_code.js deleted file mode 100644 index fd99783..0000000 --- a/chrome/browser/resources/extensions/extension_code.js +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @typedef {{afterHighlight: string, - * beforeHighlight: string, - * highlight: string, - * message: string}} - */ -var ExtensionHighlight; - -cr.define('extensions', function() { - 'use strict'; - - /** - * ExtensionCode is an element which displays code in a styled div, and is - * designed to highlight errors. - * @constructor - * @extends {HTMLDivElement} - */ - function ExtensionCode(div) { - div.__proto__ = ExtensionCode.prototype; - return div; - } - - ExtensionCode.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * Populate the content area of the code div with the given code. This will - * highlight the erroneous section (if any). - * @param {?ExtensionHighlight} code The 'highlight' strings represent the - * three portions of the file's content to display - the portion which - * is most relevant and should be emphasized (highlight), and the parts - * both before and after this portion. The title is the error message, - * which will be the mouseover hint for the highlighted region. These - * may be empty. - * @param {string} emptyMessage The message to display if the code - * object is empty (e.g., 'could not load code'). - */ - populate: function(code, emptyMessage) { - // Clear any remnant content, so we don't have multiple code listed. - this.clear(); - - // If there's no code, then display an appropriate message. - if (!code || - (!code.highlight && !code.beforeHighlight && !code.afterHighlight)) { - var span = document.createElement('span'); - span.classList.add('extension-code-empty'); - span.textContent = emptyMessage; - this.appendChild(span); - return; - } - - var sourceDiv = document.createElement('div'); - sourceDiv.classList.add('extension-code-source'); - this.appendChild(sourceDiv); - - var lineCount = 0; - var createSpan = function(source, isHighlighted) { - lineCount += source.split('\n').length - 1; - var span = document.createElement('span'); - span.className = isHighlighted ? 'extension-code-highlighted-source' : - 'extension-code-normal-source'; - span.textContent = source; - return span; - }; - - if (code.beforeHighlight) - sourceDiv.appendChild(createSpan(code.beforeHighlight, false)); - - if (code.highlight) { - var highlightSpan = createSpan(code.highlight, true); - highlightSpan.title = code.message; - sourceDiv.appendChild(highlightSpan); - } - - if (code.afterHighlight) - sourceDiv.appendChild(createSpan(code.afterHighlight, false)); - - // Make the line numbers. This should be the number of line breaks + 1 - // (the last line doesn't break, but should still be numbered). - var content = ''; - for (var i = 1; i < lineCount + 1; ++i) - content += i + '\n'; - var span = document.createElement('span'); - span.textContent = content; - - var linesDiv = document.createElement('div'); - linesDiv.classList.add('extension-code-line-numbers'); - linesDiv.appendChild(span); - this.insertBefore(linesDiv, this.firstChild); - }, - - /** - * Clears the content of the element. - */ - clear: function() { - while (this.firstChild) - this.removeChild(this.firstChild); - }, - - /** - * Scrolls to the error, if there is one. This cannot be called when the - * div is hidden. - */ - scrollToError: function() { - var errorSpan = this.querySelector('.extension-code-highlighted-source'); - if (errorSpan) - this.scrollTop = errorSpan.offsetTop - this.clientHeight / 2; - } - }; - - // Export - return { - ExtensionCode: ExtensionCode - }; -});
diff --git a/chrome/browser/resources/extensions/extension_command_list.js b/chrome/browser/resources/extensions/extension_command_list.js deleted file mode 100644 index 1aa48e3..0000000 --- a/chrome/browser/resources/extensions/extension_command_list.js +++ /dev/null
@@ -1,425 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// <include src="../md_extensions/shortcut_util.js"> - -cr.define('extensions', function() { - 'use strict'; - - /** - * Creates a new list of extension commands. - * @param {HTMLDivElement} div - * @constructor - * @extends {HTMLDivElement} - */ - function ExtensionCommandList(div) { - div.__proto__ = ExtensionCommandList.prototype; - return div; - } - - ExtensionCommandList.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * While capturing, this records the current (last) keyboard event generated - * by the user. Will be |null| after capture and during capture when no - * keyboard event has been generated. - * @type {KeyboardEvent}. - * @private - */ - currentKeyEvent_: null, - - /** - * While capturing, this keeps track of the previous selection so we can - * revert back to if no valid assignment is made during capture. - * @type {string}. - * @private - */ - oldValue_: '', - - /** - * While capturing, this keeps track of which element the user asked to - * change. - * @type {HTMLElement}. - * @private - */ - capturingElement_: null, - - /** - * Updates the extensions data for the overlay. - * @param {!Array<chrome.developerPrivate.ExtensionInfo>} data The extension - * data. - */ - setData: function(data) { - /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */ - this.data_ = data; - - this.textContent = ''; - - // Iterate over the extension data and add each item to the list. - this.data_.forEach(this.createNodeForExtension_.bind(this)); - }, - - /** - * Synthesizes and initializes an HTML element for the extension command - * metadata given in |extension|. - * @param {chrome.developerPrivate.ExtensionInfo} extension A dictionary of - * extension metadata. - * @private - */ - createNodeForExtension_: function(extension) { - if (extension.commands.length == 0 || - extension.state == chrome.developerPrivate.ExtensionState.DISABLED) - return; - - var template = $('template-collection-extension-commands').querySelector( - '.extension-command-list-extension-item-wrapper'); - var node = template.cloneNode(true); - - var title = node.querySelector('.extension-title'); - title.textContent = extension.name; - - this.appendChild(node); - - // Iterate over the commands data within the extension and add each item - // to the list. - extension.commands.forEach( - this.createNodeForCommand_.bind(this, extension.id)); - }, - - /** - * Synthesizes and initializes an HTML element for the extension command - * metadata given in |command|. - * @param {string} extensionId The associated extension's id. - * @param {chrome.developerPrivate.Command} command A dictionary of - * extension command metadata. - * @private - */ - createNodeForCommand_: function(extensionId, command) { - var template = $('template-collection-extension-commands').querySelector( - '.extension-command-list-command-item-wrapper'); - var node = template.cloneNode(true); - node.id = this.createElementId_('command', extensionId, command.name); - - var description = node.querySelector('.command-description'); - description.textContent = command.description; - - var shortcutNode = node.querySelector('.command-shortcut-text'); - shortcutNode.addEventListener('mouseup', - this.startCapture_.bind(this)); - shortcutNode.addEventListener('focus', this.handleFocus_.bind(this)); - shortcutNode.addEventListener('blur', this.handleBlur_.bind(this)); - shortcutNode.addEventListener('keydown', this.handleKeyDown_.bind(this)); - shortcutNode.addEventListener('keyup', this.handleKeyUp_.bind(this)); - if (!command.isActive) { - shortcutNode.textContent = - loadTimeData.getString('extensionCommandsInactive'); - - var commandShortcut = node.querySelector('.command-shortcut'); - commandShortcut.classList.add('inactive-keybinding'); - } else { - shortcutNode.textContent = command.keybinding; - } - - var commandClear = node.querySelector('.command-clear'); - commandClear.id = this.createElementId_( - 'clear', extensionId, command.name); - commandClear.title = loadTimeData.getString('extensionCommandsDelete'); - commandClear.addEventListener('click', this.handleClear_.bind(this)); - - var select = node.querySelector('.command-scope'); - select.id = this.createElementId_( - 'setCommandScope', extensionId, command.name); - select.hidden = false; - // Add the 'In Chrome' option. - var option = document.createElement('option'); - option.textContent = loadTimeData.getString('extensionCommandsRegular'); - select.appendChild(option); - if (command.isExtensionAction || !command.isActive) { - // Extension actions cannot be global, so we might as well disable the - // combo box, to signify that, and if the command is inactive, it - // doesn't make sense to allow the user to adjust the scope. - select.disabled = true; - } else { - // Add the 'Global' option. - option = document.createElement('option'); - option.textContent = loadTimeData.getString('extensionCommandsGlobal'); - select.appendChild(option); - select.selectedIndex = - command.scope == chrome.developerPrivate.CommandScope.GLOBAL ? - 1 : 0; - - select.addEventListener( - 'change', this.handleSetCommandScope_.bind(this)); - } - - this.appendChild(node); - }, - - /** - * Starts keystroke capture to determine which key to use for a particular - * extension command. - * @param {Event} event The keyboard event to consider. - * @private - */ - startCapture_: function(event) { - if (this.capturingElement_) - return; // Already capturing. - - chrome.developerPrivate.setShortcutHandlingSuspended(true); - - var shortcutNode = event.target; - this.oldValue_ = shortcutNode.textContent; - shortcutNode.textContent = - loadTimeData.getString('extensionCommandsStartTyping'); - shortcutNode.parentElement.classList.add('capturing'); - - var commandClear = - shortcutNode.parentElement.querySelector('.command-clear'); - commandClear.hidden = true; - - this.capturingElement_ = /** @type {HTMLElement} */(event.target); - }, - - /** - * Ends keystroke capture and either restores the old value or (if valid - * value) sets the new value as active.. - * @param {Event} event The keyboard event to consider. - * @private - */ - endCapture_: function(event) { - if (!this.capturingElement_) - return; // Not capturing. - - chrome.developerPrivate.setShortcutHandlingSuspended(false); - - var shortcutNode = this.capturingElement_; - var commandShortcut = shortcutNode.parentElement; - - commandShortcut.classList.remove('capturing'); - commandShortcut.classList.remove('contains-chars'); - - // When the capture ends, the user may have not given a complete and valid - // input (or even no input at all). Only a valid key event followed by a - // valid key combination will cause a shortcut selection to be activated. - // If no valid selection was made, however, revert back to what the - // textbox had before to indicate that the shortcut registration was - // canceled. - if (!this.currentKeyEvent_ || - !extensions.isValidKeyCode(this.currentKeyEvent_.keyCode)) - shortcutNode.textContent = this.oldValue_; - - var commandClear = commandShortcut.querySelector('.command-clear'); - if (this.oldValue_ == '') { - commandShortcut.classList.remove('clearable'); - commandClear.hidden = true; - } else { - commandShortcut.classList.add('clearable'); - commandClear.hidden = false; - } - - this.oldValue_ = ''; - this.capturingElement_ = null; - this.currentKeyEvent_ = null; - }, - - /** - * Handles focus event and adds visual indication for active shortcut. - * @param {Event} event to consider. - * @private - */ - handleFocus_: function(event) { - var commandShortcut = event.target.parentElement; - commandShortcut.classList.add('focused'); - }, - - /** - * Handles lost focus event and removes visual indication of active shortcut - * also stops capturing on focus lost. - * @param {Event} event to consider. - * @private - */ - handleBlur_: function(event) { - this.endCapture_(event); - var commandShortcut = event.target.parentElement; - commandShortcut.classList.remove('focused'); - }, - - /** - * The KeyDown handler. - * @param {Event} event The keyboard event to consider. - * @private - */ - handleKeyDown_: function(event) { - event = /** @type {KeyboardEvent} */(event); - if (event.keyCode == extensions.Key.Escape) { - if (!this.capturingElement_) { - // If we're not currently capturing, allow escape to propagate (so it - // can close the overflow). - return; - } - // Otherwise, escape cancels capturing. - this.endCapture_(event); - var parsed = this.parseElementId_('clear', - event.target.parentElement.querySelector('.command-clear').id); - chrome.developerPrivate.updateExtensionCommand({ - extensionId: parsed.extensionId, - commandName: parsed.commandName, - keybinding: '' - }); - event.preventDefault(); - event.stopPropagation(); - return; - } - if (event.keyCode == extensions.Key.Tab) { - // Allow tab propagation for keyboard navigation. - return; - } - - if (!this.capturingElement_) - this.startCapture_(event); - - this.handleKey_(event); - }, - - /** - * The KeyUp handler. - * @param {Event} event The keyboard event to consider. - * @private - */ - handleKeyUp_: function(event) { - event = /** @type {KeyboardEvent} */(event); - if (event.keyCode == extensions.Key.Tab || - event.keyCode == extensions.Key.Escape) { - // We need to allow tab propagation for keyboard navigation, and escapes - // are fully handled in handleKeyDown. - return; - } - - // We want to make it easy to change from Ctrl+Shift+ to just Ctrl+ by - // releasing Shift, but we also don't want it to be easy to lose for - // example Ctrl+Shift+F to Ctrl+ just because you didn't release Ctrl - // as fast as the other two keys. Therefore, we process KeyUp until you - // have a valid combination and then stop processing it (meaning that once - // you have a valid combination, we won't change it until the next - // KeyDown message arrives). - if (!this.currentKeyEvent_ || - !extensions.isValidKeyCode(this.currentKeyEvent_.keyCode)) { - if (!event.ctrlKey && !event.altKey || - ((cr.isMac || cr.isChromeOS) && !event.metaKey)) { - // If neither Ctrl nor Alt is pressed then it is not a valid shortcut. - // That means we're back at the starting point so we should restart - // capture. - this.endCapture_(event); - this.startCapture_(event); - } else { - this.handleKey_(event); - } - } - }, - - /** - * A general key handler (used for both KeyDown and KeyUp). - * @param {KeyboardEvent} event The keyboard event to consider. - * @private - */ - handleKey_: function(event) { - // While capturing, we prevent all events from bubbling, to prevent - // shortcuts lacking the right modifier (F3 for example) from activating - // and ending capture prematurely. - event.preventDefault(); - event.stopPropagation(); - - if (!extensions.hasValidModifiers(event)) - return; - - var shortcutNode = this.capturingElement_; - var keystroke = extensions.keystrokeToString(event); - shortcutNode.textContent = keystroke; - event.target.classList.add('contains-chars'); - this.currentKeyEvent_ = event; - - if (extensions.isValidKeyCode(event.keyCode)) { - var node = event.target; - while (node && !node.id) - node = node.parentElement; - - this.oldValue_ = keystroke; // Forget what the old value was. - var parsed = this.parseElementId_('command', node.id); - - // Ending the capture must occur before calling - // setExtensionCommandShortcut to ensure the shortcut is set. - this.endCapture_(event); - chrome.developerPrivate.updateExtensionCommand( - {extensionId: parsed.extensionId, - commandName: parsed.commandName, - keybinding: keystroke}); - } - }, - - /** - * A handler for the delete command button. - * @param {Event} event The mouse event to consider. - * @private - */ - handleClear_: function(event) { - var parsed = this.parseElementId_('clear', event.target.id); - chrome.developerPrivate.updateExtensionCommand( - {extensionId: parsed.extensionId, - commandName: parsed.commandName, - keybinding: ''}); - }, - - /** - * A handler for the setting the scope of the command. - * @param {Event} event The mouse event to consider. - * @private - */ - handleSetCommandScope_: function(event) { - var parsed = this.parseElementId_('setCommandScope', event.target.id); - var element = - $('setCommandScope-' + parsed.extensionId + '-' + parsed.commandName); - var scope = element.selectedIndex == 1 ? - chrome.developerPrivate.CommandScope.GLOBAL : - chrome.developerPrivate.CommandScope.CHROME; - chrome.developerPrivate.updateExtensionCommand( - {extensionId: parsed.extensionId, - commandName: parsed.commandName, - scope: scope}); - }, - - /** - * A utility function to create a unique element id based on a namespace, - * extension id and a command name. - * @param {string} namespace The namespace to prepend the id with. - * @param {string} extensionId The extension ID to use in the id. - * @param {string} commandName The command name to append the id with. - * @private - */ - createElementId_: function(namespace, extensionId, commandName) { - return namespace + '-' + extensionId + '-' + commandName; - }, - - /** - * A utility function to parse a unique element id based on a namespace, - * extension id and a command name. - * @param {string} namespace The namespace to prepend the id with. - * @param {string} id The id to parse. - * @return {{extensionId: string, commandName: string}} The parsed id. - * @private - */ - parseElementId_: function(namespace, id) { - var kExtensionIdLength = 32; - return { - extensionId: id.substring(namespace.length + 1, - namespace.length + 1 + kExtensionIdLength), - commandName: id.substring(namespace.length + 1 + kExtensionIdLength + 1) - }; - }, - }; - - return { - ExtensionCommandList: ExtensionCommandList - }; -});
diff --git a/chrome/browser/resources/extensions/extension_commands_overlay.css b/chrome/browser/resources/extensions/extension_commands_overlay.css deleted file mode 100644 index 407a256..0000000 --- a/chrome/browser/resources/extensions/extension_commands_overlay.css +++ /dev/null
@@ -1,80 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.extension-command-list-command-item-wrapper { - margin-left: 12px; -} - -.command-title { - display: inline-block; - margin-top: 1em; -} - -.command-container { - -webkit-box-orient: horizontal; - display: -webkit-box; - width: 450px; -} - -.command-description { - -webkit-box-flex: 1; - display: -webkit-box; - margin-top: 0.5em; - min-height: 2em; -} - -.command-shortcut-container { - display: -webkit-box; - margin-top: 0.25em; - min-height: 2em; -} - -.command-shortcut { - border: solid 1px #BFBFBF; - border-radius: 2px; - color: rgb(48, 57, 66); - display: inline-block; - height: 1.4em; - min-width: 12.5em; - padding: 3px 0 1px 4px; -} - -.command-shortcut-text { - display: inline-block; - height: 1.4em; - min-width: 11em; - outline: none; -} - -.focused { - border: solid 1px rgb(140, 147, 255); -} - -.clearable { - background: white; -} - -.command-clear { - float: right; - margin-top: 1px; -} - -.command-scope { - margin-left: 0.25em; - margin-top: 0.24em; -} - -.capturing { - background: rgb(243, 244, 255); - border: solid 1px rgb(140, 147, 255); - color: #999; -} - -.contains-chars { - color: rgb(48, 57, 66); -} - -.inactive-keybinding { - color: #999; -}
diff --git a/chrome/browser/resources/extensions/extension_commands_overlay.html b/chrome/browser/resources/extensions/extension_commands_overlay.html deleted file mode 100644 index ad6c248..0000000 --- a/chrome/browser/resources/extensions/extension_commands_overlay.html +++ /dev/null
@@ -1,55 +0,0 @@ -<!-- - * Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be found - * in the LICENSE file. ---> -<div id="extension-commands-overlay" class="page"> - <div class="close-button"></div> - <h1>$i18n{extensionCommandsOverlay}</h1> - <div class="content-area"> - <div id="extension-command-list" - class="empty-extension-commands-list"></div> - <div id="no-commands" hidden> - <span id="no-extensions-commands-message"> - $i18n{extensionCommandsEmpty} - </span> - </div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="extension-commands-dismiss">$i18n{ok}</button> - </div> - </div> - </div> -</div> - -<div id="template-collection-extension-commands" hidden> - <div class="extension-command-list-extension-item-wrapper"> - <div class="extension-command-list-extension-item"> - <div class="extension-command-extension-details"> - <div> - <span class="extension-title command-title"></span> - <div class="command-details"></div> - </div> - </div> - </div> - </div> - - <div class="extension-command-list-command-item-wrapper"> - <div class="extension-command-list-command-item"> - <div class="extension-command-details"> - <div class="command-container"> - <span class="command-description"></span> - <span class="command-shortcut-container" - ><span class="command-shortcut clearable" - ><img class="command-clear" - src="chrome://theme/IDR_EXTENSION_COMMAND_CLOSE" - ><span class="command-shortcut-text" tabindex="0" - ></span></span></span> - <select class="command-scope" hidden></select> - </div> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/extension_commands_overlay.js b/chrome/browser/resources/extensions/extension_commands_overlay.js deleted file mode 100644 index 443440b2..0000000 --- a/chrome/browser/resources/extensions/extension_commands_overlay.js +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// <include src="extension_command_list.js"> - -cr.define('extensions', function() { - 'use strict'; - - // The Extension Commands list object that will be used to show the commands - // on the page. - var ExtensionCommandList = extensions.ExtensionCommandList; - - /** - * ExtensionCommandsOverlay class - * Encapsulated handling of the 'Extension Commands' overlay page. - * @constructor - */ - function ExtensionCommandsOverlay() { - } - - cr.addSingletonGetter(ExtensionCommandsOverlay); - - ExtensionCommandsOverlay.prototype = { - /** - * Initialize the page. - */ - initializePage: function() { - var overlay = $('overlay'); - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); - - this.extensionCommandList_ = new ExtensionCommandList( - /**@type {HTMLDivElement} */($('extension-command-list'))); - - $('extension-commands-dismiss').addEventListener('click', function() { - cr.dispatchSimpleEvent(overlay, 'cancelOverlay'); - }); - - // The ExtensionList will update us with its data, so we don't need to - // handle that here. - }, - - /** - * Handles a click on the dismiss button. - * @param {Event} e The click event. - */ - handleDismiss_: function(e) { - extensions.ExtensionSettings.showOverlay(null); - }, - }; - - /** - * Called by the dom_ui_ to re-populate the page with data representing - * the current state of extension commands. - * @param {!Array<chrome.developerPrivate.ExtensionInfo>} extensionsData - */ - ExtensionCommandsOverlay.updateExtensionsData = function(extensionsData) { - var overlay = ExtensionCommandsOverlay.getInstance(); - overlay.extensionCommandList_.setData(extensionsData); - - var hasAnyCommands = false; - for (var i = 0; i < extensionsData.length; ++i) { - if (extensionsData[i].commands.length > 0) { - hasAnyCommands = true; - break; - } - } - - // Make sure the config link is visible, since there are commands to show - // and potentially configure. - document.querySelector('.extension-commands-config').hidden = - !hasAnyCommands; - - $('no-commands').hidden = hasAnyCommands; - overlay.extensionCommandList_.classList.toggle( - 'empty-extension-commands-list', !hasAnyCommands); - }; - - // Export - return { - ExtensionCommandsOverlay: ExtensionCommandsOverlay - }; -});
diff --git a/chrome/browser/resources/extensions/extension_error.css b/chrome/browser/resources/extensions/extension_error.css deleted file mode 100644 index 79ee0ab3..0000000 --- a/chrome/browser/resources/extensions/extension_error.css +++ /dev/null
@@ -1,111 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.extension-error-list-heading { - align-content: flex-start; - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 3px; -} - -.extension-error-list-heading span { - font-weight: bold; -} - -.extension-error-list a { - cursor: pointer; -} - -.extension-error-list-contents { - -webkit-padding-start: 0; - cursor: pointer; - list-style-type: none; - margin-bottom: 0; - margin-top: 0; -} - -#no-errors-span { - -webkit-margin-start: 10px; -} - -.extension-error-list-contents.scrollable { - overflow-y: auto; -} - -.extension-error-list-contents .extension-error-metadata:hover { - background-color: #eee; -} - -.extension-error-list-contents - .extension-error-metadata.extension-error-active { - background-color: rgba(0, 100, 255, 0.1); -} - -.extension-error-metadata { - -webkit-padding-end: 1px; - -webkit-padding-start: 3px; - display: flex; - flex-direction: row; -} - -.extension-error-icon { - -webkit-margin-end: 3px; - height: 15px; - width: 15px; -} - -.extension-error-message { - -webkit-margin-end: 15px; - flex: 1; - margin-bottom: 0; - margin-top: 0; - overflow: hidden; -} - -.extension-error-metadata { - align-items: center; - display: flex; -} - -.extension-error-metadata > .error-delete-button { - -webkit-appearance: none; - background: url(chrome://theme/IDR_CLOSE_DIALOG) center no-repeat; - border: none; - height: 14px; - opacity: 0.6; - width: 14px; -} - -.extension-error-metadata > .error-delete-button:hover { - opacity: 0.8; -} - -.extension-error-metadata > .error-delete-button:active { - opacity: 1.0; -} - -.extension-error-severity-info .extension-error-message { - color: #333; -} -.extension-error-severity-info .extension-error-icon, -.extension-error-info-icon { - content: url(extension_error_severity_info.png); -} - -.extension-error-severity-warning .extension-error-message { - color: rgba(250, 145, 0, 255); -} -.extension-error-severity-warning .extension-error-icon, -.extension-error-warning-icon { - content: url(extension_error_severity_warning.png); -} - -.extension-error-severity-fatal .extension-error-message { - color: rgba(200, 50, 50, 255); -} -.extension-error-severity-fatal .extension-error-icon, -.extension-error-fatal-icon { - content: url(extension_error_severity_fatal.png); -}
diff --git a/chrome/browser/resources/extensions/extension_error.html b/chrome/browser/resources/extensions/extension_error.html deleted file mode 100644 index ad294bb..0000000 --- a/chrome/browser/resources/extensions/extension_error.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!-- -Copyright 2013 The Chromium Authors. All rights reserved. -Use of this source code is governed by a BSD-style license that can be found -in the LICENSE file. ---> -<div id="template-collection-extension-error" hidden> - <div class="extension-error-list"> - <div class="extension-error-list-heading"> - <span>$i18n{extensionErrorHeading}</span> - <a id="extension-error-list-clear" is="action-link"> - $i18n{extensionErrorClearAll} - </a> - </div> - <ul class="extension-error-list-contents"></ul> - <span id="no-errors-span" hidden>$i18n{extensionErrorNoErrors}</span> - </div> - <li class="extension-error-metadata"> - <p class="extension-error-message" tabindex="0"></p> - <button class="custom-appearance error-delete-button"></button> - </li> -</div>
diff --git a/chrome/browser/resources/extensions/extension_error.js b/chrome/browser/resources/extensions/extension_error.js deleted file mode 100644 index 6d619c29..0000000 --- a/chrome/browser/resources/extensions/extension_error.js +++ /dev/null
@@ -1,376 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - 'use strict'; - - /** - * Clone a template within the extension error template collection. - * @param {string} templateName The class name of the template to clone. - * @return {HTMLElement} The clone of the template. - */ - function cloneTemplate(templateName) { - return /** @type {HTMLElement} */($('template-collection-extension-error'). - querySelector('.' + templateName).cloneNode(true)); - } - - /** - * Checks that an Extension ID follows the proper format (i.e., is 32 - * characters long, is lowercase, and contains letters in the range [a, p]). - * @param {string} id The Extension ID to test. - * @return {boolean} Whether or not the ID is valid. - */ - function idIsValid(id) { - return /^[a-p]{32}$/.test(id); - } - - /** - * @param {!Array<(ManifestError|RuntimeError)>} errors - * @param {number} id - * @return {number} The index of the error with |id|, or -1 if not found. - */ - function findErrorById(errors, id) { - for (var i = 0; i < errors.length; ++i) { - if (errors[i].id == id) - return i; - } - return -1; - } - - /** - * Creates a new ExtensionError HTMLElement; this is used to show a - * notification to the user when an error is caused by an extension. - * @param {(RuntimeError|ManifestError)} error The error the element should - * represent. - * @constructor - * @extends {HTMLElement} - */ - function ExtensionError(error) { - var div = cloneTemplate('extension-error-metadata'); - div.__proto__ = ExtensionError.prototype; - div.decorate(error); - return div; - } - - ExtensionError.prototype = { - __proto__: HTMLElement.prototype, - - /** - * @param {(RuntimeError|ManifestError)} error The error the element should - * represent. - * @private - */ - decorate: function(error) { - /** - * The backing error. - * @type {(ManifestError|RuntimeError)} - */ - this.error = error; - var iconAltTextKey = 'extensionLogLevelWarn'; - - // Add an additional class for the severity level. - if (error.type == chrome.developerPrivate.ErrorType.RUNTIME) { - switch (error.severity) { - case chrome.developerPrivate.ErrorLevel.LOG: - this.classList.add('extension-error-severity-info'); - iconAltTextKey = 'extensionLogLevelInfo'; - break; - case chrome.developerPrivate.ErrorLevel.WARN: - this.classList.add('extension-error-severity-warning'); - break; - case chrome.developerPrivate.ErrorLevel.ERROR: - this.classList.add('extension-error-severity-fatal'); - iconAltTextKey = 'extensionLogLevelError'; - break; - default: - assertNotReached(); - } - } else { - // We classify manifest errors as "warnings". - this.classList.add('extension-error-severity-warning'); - } - - var iconNode = document.createElement('img'); - iconNode.className = 'extension-error-icon'; - iconNode.alt = loadTimeData.getString(iconAltTextKey); - this.insertBefore(iconNode, this.firstChild); - - var messageSpan = this.querySelector('.extension-error-message'); - messageSpan.textContent = error.message; - - var deleteButton = this.querySelector('.error-delete-button'); - deleteButton.addEventListener('click', function(e) { - this.dispatchEvent( - new CustomEvent('deleteExtensionError', - {bubbles: true, detail: this.error})); - }.bind(this)); - - this.addEventListener('click', function(e) { - if (e.target != deleteButton) - this.requestActive_(); - }.bind(this)); - - this.addEventListener('keydown', function(e) { - if (e.key == 'Enter' && e.target != deleteButton) - this.requestActive_(); - }); - }, - - /** - * Bubble up an event to request to become active. - * @private - */ - requestActive_: function() { - this.dispatchEvent( - new CustomEvent('highlightExtensionError', - {bubbles: true, detail: this.error})); - }, - }; - - /** - * A variable length list of runtime or manifest errors for a given extension. - * @param {Array<(RuntimeError|ManifestError)>} errors The list of extension - * errors with which to populate the list. - * @param {string} extensionId The id of the extension. - * @constructor - * @extends {HTMLDivElement} - */ - function ExtensionErrorList(errors, extensionId) { - var div = cloneTemplate('extension-error-list'); - div.__proto__ = ExtensionErrorList.prototype; - div.extensionId_ = extensionId; - div.decorate(errors); - return div; - } - - /** - * @param {!Element} root - * @param {?Element} boundary - * @constructor - * @extends {cr.ui.FocusRow} - */ - ExtensionErrorList.FocusRow = function(root, boundary) { - cr.ui.FocusRow.call(this, root, boundary); - - this.addItem('message', '.extension-error-message'); - this.addItem('delete', '.error-delete-button'); - }; - - ExtensionErrorList.FocusRow.prototype = { - __proto__: cr.ui.FocusRow.prototype, - }; - - ExtensionErrorList.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * Initializes the extension error list. - * @param {Array<(RuntimeError|ManifestError)>} errors The list of errors. - */ - decorate: function(errors) { - /** @private {!Array<(ManifestError|RuntimeError)>} */ - this.errors_ = []; - - /** @private {!cr.ui.FocusGrid} */ - this.focusGrid_ = new cr.ui.FocusGrid(); - - /** @private {Element} */ - this.listContents_ = this.querySelector('.extension-error-list-contents'); - - errors.forEach(this.addError_, this); - - this.focusGrid_.ensureRowActive(); - - this.addEventListener('highlightExtensionError', function(e) { - this.setActiveErrorNode_(e.target); - }); - this.addEventListener('deleteExtensionError', function(e) { - this.removeError_(e.detail); - }); - - this.querySelector('#extension-error-list-clear').addEventListener( - 'click', function(e) { - this.clear(true); - }.bind(this)); - - /** - * The callback for the extension changed event. - * @private {function(chrome.developerPrivate.EventData):void} - */ - this.onItemStateChangedListener_ = function(data) { - var type = chrome.developerPrivate.EventType; - if ((data.event_type == type.ERRORS_REMOVED || - data.event_type == type.ERROR_ADDED) && - data.extensionInfo.id == this.extensionId_) { - var newErrors = data.extensionInfo.runtimeErrors.concat( - data.extensionInfo.manifestErrors); - this.updateErrors_(newErrors); - } - }.bind(this); - - chrome.developerPrivate.onItemStateChanged.addListener( - this.onItemStateChangedListener_); - - /** - * The active error element in the list. - * @private {?} - */ - this.activeError_ = null; - - this.setActiveError(0); - }, - - /** - * Adds an error to the list. - * @param {(RuntimeError|ManifestError)} error The error to add. - * @private - */ - addError_: function(error) { - this.querySelector('#no-errors-span').hidden = true; - this.errors_.push(error); - - var extensionError = new ExtensionError(error); - this.listContents_.appendChild(extensionError); - - this.focusGrid_.addRow( - new ExtensionErrorList.FocusRow(extensionError, this.listContents_)); - }, - - /** - * Removes an error from the list. - * @param {(RuntimeError|ManifestError)} error The error to remove. - * @private - */ - removeError_: function(error) { - var index = 0; - for (; index < this.errors_.length; ++index) { - if (this.errors_[index].id == error.id) - break; - } - assert(index != this.errors_.length); - var errorList = this.querySelector('.extension-error-list-contents'); - - var wasActive = - this.activeError_ && this.activeError_.error.id == error.id; - - this.errors_.splice(index, 1); - var listElement = errorList.children[index]; - - var focusRow = this.focusGrid_.getRowForRoot(listElement); - this.focusGrid_.removeRow(focusRow); - this.focusGrid_.ensureRowActive(); - focusRow.destroy(); - - // TODO(dbeam): in a world where this UI is actually used, we should - // probably move the focus before removing |listElement|. - listElement.parentNode.removeChild(listElement); - - if (wasActive) { - index = Math.min(index, this.errors_.length - 1); - this.setActiveError(index); // Gracefully handles the -1 case. - } - - chrome.developerPrivate.deleteExtensionErrors({ - extensionId: error.extensionId, - errorIds: [error.id] - }); - - if (this.errors_.length == 0) - this.querySelector('#no-errors-span').hidden = false; - }, - - /** - * Updates the list of errors. - * @param {!Array<(ManifestError|RuntimeError)>} newErrors The new list of - * errors. - * @private - */ - updateErrors_: function(newErrors) { - this.errors_.forEach(function(error) { - if (findErrorById(newErrors, error.id) == -1) - this.removeError_(error); - }, this); - newErrors.forEach(function(error) { - var index = findErrorById(this.errors_, error.id); - if (index == -1) - this.addError_(error); - else - this.errors_[index] = error; // Update the existing reference. - }, this); - }, - - /** - * Called when the list is being removed. - */ - onRemoved: function() { - chrome.developerPrivate.onItemStateChanged.removeListener( - this.onItemStateChangedListener_); - this.clear(false); - }, - - /** - * Sets the active error in the list. - * @param {number} index The index to set to be active. - */ - setActiveError: function(index) { - var errorList = this.querySelector('.extension-error-list-contents'); - var item = errorList.children[index]; - this.setActiveErrorNode_( - item ? item.querySelector('.extension-error-metadata') : null); - var node = null; - if (index >= 0 && index < errorList.children.length) { - node = errorList.children[index].querySelector( - '.extension-error-metadata'); - } - this.setActiveErrorNode_(node); - }, - - /** - * Clears the list of all errors. - * @param {boolean} deleteErrors Whether or not the errors should be deleted - * on the backend. - */ - clear: function(deleteErrors) { - if (this.errors_.length == 0) - return; - - if (deleteErrors) { - var ids = this.errors_.map(function(error) { return error.id; }); - chrome.developerPrivate.deleteExtensionErrors({ - extensionId: this.extensionId_, - errorIds: ids - }); - } - - this.setActiveErrorNode_(null); - this.errors_.length = 0; - var errorList = this.querySelector('.extension-error-list-contents'); - while (errorList.firstChild) - errorList.removeChild(errorList.firstChild); - }, - - /** - * Sets the active error in the list. - * @param {?} node The error to make active. - * @private - */ - setActiveErrorNode_: function(node) { - if (this.activeError_) - this.activeError_.classList.remove('extension-error-active'); - - if (node) - node.classList.add('extension-error-active'); - - this.activeError_ = node; - - this.dispatchEvent( - new CustomEvent('activeExtensionErrorChanged', - {bubbles: true, detail: node ? node.error : null})); - }, - }; - - return { - ExtensionErrorList: ExtensionErrorList - }; -});
diff --git a/chrome/browser/resources/extensions/extension_error_overlay.css b/chrome/browser/resources/extensions/extension_error_overlay.css deleted file mode 100644 index 9100707..0000000 --- a/chrome/browser/resources/extensions/extension_error_overlay.css +++ /dev/null
@@ -1,72 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#extension-error-overlay { - max-width: 100%; -} - -#extension-error-overlay .content-area { - display: flex; - flex-direction: column; -} - -#extension-error-overlay .extension-error-list { - border: 1px solid #ccc; - margin-bottom: 3px; - min-height: 48px; - overflow-y: auto; -} - -.extension-error-overlay-runtime-content { - flex: none; -} - -#extension-error-overlay .extension-code-highlighted-source { - background-color: rgba(255, 195, 200, 255); -} - -#extension-error-overlay-code { - font-size: 1.2em; - margin-bottom: 10px; -} - -#extension-error-overlay .extension-code-source { - color: #555; -} - -.extension-error-overlay-context { - font-size: 1.1em; - margin-bottom: 10px; -} - -.extension-error-overlay-stack-trace-list { - list-style-type: none; - padding: 0; -} - -.extension-error-overlay-stack-trace summary { - cursor: pointer; - font-size: 1.1em; - outline: none; -} - -.extension-error-overlay-stack-trace summary::-webkit-details-marker { - font-size: 1em; -} - -.extension-error-overlay-stack-trace-list li { - -webkit-padding-start: 10px; - background-color: white; - cursor: pointer; - padding-bottom: 6px; - padding-top: 6px; -} - -.extension-error-overlay-stack-trace-list li:hover { - background-color: #eee; -} - -.extension-error-overlay-stack-trace-list li.extension-error-active { - background-color: rgba(0, 100, 255, 0.1); -}
diff --git a/chrome/browser/resources/extensions/extension_error_overlay.html b/chrome/browser/resources/extensions/extension_error_overlay.html deleted file mode 100644 index 2becd7ce..0000000 --- a/chrome/browser/resources/extensions/extension_error_overlay.html +++ /dev/null
@@ -1,39 +0,0 @@ -<!-- -Copyright 2013 The Chromium Authors. All rights reserved. -Use of this source code is governed by a BSD-style license that can be found -in the LICENSE file. ---> - -<div id="template-collection-extension-error-overlay" hidden> - <div class="extension-error-overlay-runtime-content"> - <div class="extension-error-overlay-context"> - <span>$i18n{extensionErrorOverlayContextUrl}</span> - <span class="extension-error-overlay-context-url"></span> - </div> - <details class="extension-error-overlay-stack-trace"> - <summary>$i18n{extensionErrorOverlayStackTrace}</summary> - <ul class="extension-error-overlay-stack-trace-list"></ul> - </details> - </div> -</div> - -<div id="extension-error-overlay" class="page"> - <div class="close-button"></div> - <h1 class="extension-error-overlay-title"></h1> - <div class="content-area"> - <div class="extension-error-list"></div> - <div id="extension-error-overlay-code" class="extension-code"></div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="extension-error-overlay-dismiss"> - $i18n{extensionErrorOverlayDone} - </button> - <button id="extension-error-overlay-devtools-button" hidden> - $i18n{extensionErrorOverlayLaunchDevtools} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/extension_error_overlay.js b/chrome/browser/resources/extensions/extension_error_overlay.js deleted file mode 100644 index c8d6948b..0000000 --- a/chrome/browser/resources/extensions/extension_error_overlay.js +++ /dev/null
@@ -1,502 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -/** @typedef {chrome.developerPrivate.RuntimeError} */ -var RuntimeError; -/** @typedef {chrome.developerPrivate.ManifestError} */ -var ManifestError; - -cr.define('extensions', function() { - 'use strict'; - - /** - * Clear all the content of a given element. - * @param {HTMLElement} element The element to be cleared. - */ - function clearElement(element) { - while (element.firstChild) - element.removeChild(element.firstChild); - } - - /** - * Get the url relative to the main extension url. If the url is - * unassociated with the extension, this will be the full url. - * @param {string} url The url to make relative. - * @param {string} extensionUrl The url for the extension resources, in the - * form "chrome-etxension://<extension_id>/". - * @return {string} The url relative to the host. - */ - function getRelativeUrl(url, extensionUrl) { - return url.substring(0, extensionUrl.length) == extensionUrl ? - url.substring(extensionUrl.length) : url; - } - - /** - * The RuntimeErrorContent manages all content specifically associated with - * runtime errors; this includes stack frames and the context url. - * @constructor - * @extends {HTMLDivElement} - */ - function RuntimeErrorContent() { - var contentArea = $('template-collection-extension-error-overlay'). - querySelector('.extension-error-overlay-runtime-content'). - cloneNode(true); - contentArea.__proto__ = RuntimeErrorContent.prototype; - /** @type {RuntimeErrorContent} */ (contentArea).init(); - return contentArea; - } - - /** - * The name of the "active" class specific to extension errors (so as to - * not conflict with other rules). - * @type {string} - * @const - */ - RuntimeErrorContent.ACTIVE_CLASS_NAME = 'extension-error-active'; - - /** - * Determine whether or not we should display the url to the user. We don't - * want to include any of our own code in stack traces. - * @param {string} url The url in question. - * @return {boolean} True if the url should be displayed, and false - * otherwise (i.e., if it is an internal script). - */ - RuntimeErrorContent.shouldDisplayForUrl = function(url) { - // All our internal scripts are in the 'extensions::' namespace. - return !/^extensions::/.test(url); - }; - - RuntimeErrorContent.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * The underlying error whose details are being displayed. - * @type {?(RuntimeError|ManifestError)} - * @private - */ - error_: null, - - /** - * The URL associated with this extension, i.e. chrome-extension://<id>/. - * @type {?string} - * @private - */ - extensionUrl_: null, - - /** - * The node of the stack trace which is currently active. - * @type {?HTMLElement} - * @private - */ - currentFrameNode_: null, - - /** - * Initialize the RuntimeErrorContent for the first time. - */ - init: function() { - /** - * The stack trace element in the overlay. - * @type {HTMLElement} - * @private - */ - this.stackTrace_ = /** @type {HTMLElement} */( - this.querySelector('.extension-error-overlay-stack-trace-list')); - assert(this.stackTrace_); - - /** - * The context URL element in the overlay. - * @type {HTMLElement} - * @private - */ - this.contextUrl_ = /** @type {HTMLElement} */( - this.querySelector('.extension-error-overlay-context-url')); - assert(this.contextUrl_); - }, - - /** - * Sets the error for the content. - * @param {(RuntimeError|ManifestError)} error The error whose content - * should be displayed. - * @param {string} extensionUrl The URL associated with this extension. - */ - setError: function(error, extensionUrl) { - this.clearError(); - - this.error_ = error; - this.extensionUrl_ = extensionUrl; - this.contextUrl_.textContent = error.contextUrl ? - getRelativeUrl(error.contextUrl, this.extensionUrl_) : - loadTimeData.getString('extensionErrorOverlayContextUnknown'); - this.initStackTrace_(); - }, - - /** - * Wipe content associated with a specific error. - */ - clearError: function() { - this.error_ = null; - this.extensionUrl_ = null; - this.currentFrameNode_ = null; - clearElement(this.stackTrace_); - this.stackTrace_.hidden = true; - }, - - /** - * Makes |frame| active and deactivates the previously active frame (if - * there was one). - * @param {HTMLElement} frameNode The frame to activate. - * @private - */ - setActiveFrame_: function(frameNode) { - if (this.currentFrameNode_) { - this.currentFrameNode_.classList.remove( - RuntimeErrorContent.ACTIVE_CLASS_NAME); - } - - this.currentFrameNode_ = frameNode; - this.currentFrameNode_.classList.add( - RuntimeErrorContent.ACTIVE_CLASS_NAME); - }, - - /** - * Initialize the stack trace element of the overlay. - * @private - */ - initStackTrace_: function() { - for (var i = 0; i < this.error_.stackTrace.length; ++i) { - var frame = this.error_.stackTrace[i]; - // Don't include any internal calls (e.g., schemaBindings) in the - // stack trace. - if (!RuntimeErrorContent.shouldDisplayForUrl(frame.url)) - continue; - - var frameNode = document.createElement('li'); - // Attach the index of the frame to which this node refers (since we - // may skip some, this isn't a 1-to-1 match). - frameNode.indexIntoTrace = i; - - // The description is a human-readable summation of the frame, in the - // form "<relative_url>:<line_number> (function)", e.g. - // "myfile.js:25 (myFunction)". - var description = getRelativeUrl(frame.url, - assert(this.extensionUrl_)) + ':' + frame.lineNumber; - if (frame.functionName) { - var functionName = frame.functionName == '(anonymous function)' ? - loadTimeData.getString('extensionErrorOverlayAnonymousFunction') : - frame.functionName; - description += ' (' + functionName + ')'; - } - frameNode.textContent = description; - - // When the user clicks on a frame in the stack trace, we should - // highlight that overlay in the list, display the appropriate source - // code with the line highlighted, and link the "Open DevTools" button - // with that frame. - frameNode.addEventListener('click', function(frame, frameNode, e) { - this.setActiveFrame_(frameNode); - - // Request the file source with the section highlighted. - extensions.ExtensionErrorOverlay.getInstance().requestFileSource( - {extensionId: this.error_.extensionId, - message: this.error_.message, - pathSuffix: getRelativeUrl(frame.url, - assert(this.extensionUrl_)), - lineNumber: frame.lineNumber}); - }.bind(this, frame, frameNode)); - - this.stackTrace_.appendChild(frameNode); - } - - // Set the current stack frame to the first stack frame and show the - // trace, if one exists. (We can't just check error.stackTrace, because - // it's possible the trace was purely internal, and we don't show - // internal frames.) - if (this.stackTrace_.children.length > 0) { - this.stackTrace_.hidden = false; - this.setActiveFrame_(assertInstanceof(this.stackTrace_.firstChild, - HTMLElement)); - } - }, - - /** - * Open the developer tools for the active stack frame. - */ - openDevtools: function() { - var stackFrame = - this.error_.stackTrace[this.currentFrameNode_.indexIntoTrace]; - - chrome.developerPrivate.openDevTools( - {renderProcessId: this.error_.renderProcessId || -1, - renderViewId: this.error_.renderViewId || -1, - url: stackFrame.url, - lineNumber: stackFrame.lineNumber || 0, - columnNumber: stackFrame.columnNumber || 0}); - } - }; - - /** - * The ExtensionErrorOverlay will show the contents of a file which pertains - * to the ExtensionError; this is either the manifest file (for manifest - * errors) or a source file (for runtime errors). If possible, the portion - * of the file which caused the error will be highlighted. - * @constructor - */ - function ExtensionErrorOverlay() { - /** - * The content section for runtime errors; this is re-used for all - * runtime errors and attached/detached from the overlay as needed. - * @type {RuntimeErrorContent} - * @private - */ - this.runtimeErrorContent_ = new RuntimeErrorContent(); - } - - /** - * The manifest filename. - * @type {string} - * @const - * @private - */ - ExtensionErrorOverlay.MANIFEST_FILENAME_ = 'manifest.json'; - - /** - * Determine whether or not chrome can load the source for a given file; this - * can only be done if the file belongs to the extension. - * @param {string} file The file to load. - * @param {string} extensionUrl The url for the extension, in the form - * chrome-extension://<extension-id>/. - * @return {boolean} True if the file can be loaded, false otherwise. - * @private - */ - ExtensionErrorOverlay.canLoadFileSource = function(file, extensionUrl) { - return file.substr(0, extensionUrl.length) == extensionUrl || - file.toLowerCase() == ExtensionErrorOverlay.MANIFEST_FILENAME_; - }; - - cr.addSingletonGetter(ExtensionErrorOverlay); - - ExtensionErrorOverlay.prototype = { - /** - * The underlying error whose details are being displayed. - * @type {?(RuntimeError|ManifestError)} - * @private - */ - selectedError_: null, - - /** - * Initialize the page. - * @param {function(HTMLDivElement)} showOverlay The function to show or - * hide the ExtensionErrorOverlay; this should take a single parameter - * which is either the overlay Div if the overlay should be displayed, - * or null if the overlay should be hidden. - */ - initializePage: function(showOverlay) { - var overlay = $('overlay'); - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); - - $('extension-error-overlay-dismiss').addEventListener('click', - function() { - cr.dispatchSimpleEvent(overlay, 'cancelOverlay'); - }); - - /** - * The element of the full overlay. - * @type {HTMLDivElement} - * @private - */ - this.overlayDiv_ = /** @type {HTMLDivElement} */( - $('extension-error-overlay')); - - /** - * The portion of the overlay which shows the code relating to the error - * and the corresponding line numbers. - * @type {extensions.ExtensionCode} - * @private - */ - this.codeDiv_ = - new extensions.ExtensionCode($('extension-error-overlay-code')); - - /** - * The function to show or hide the ExtensionErrorOverlay. - * @param {boolean} isVisible Whether the overlay should be visible. - */ - this.setVisible = function(isVisible) { - showOverlay(isVisible ? this.overlayDiv_ : null); - if (isVisible) - this.codeDiv_.scrollToError(); - }; - - /** - * The button to open the developer tools (only available for runtime - * errors). - * @type {HTMLButtonElement} - * @private - */ - this.openDevtoolsButton_ = /** @type {HTMLButtonElement} */( - $('extension-error-overlay-devtools-button')); - this.openDevtoolsButton_.addEventListener('click', function() { - this.runtimeErrorContent_.openDevtools(); - }.bind(this)); - }, - - /** - * Handles a click on the dismiss ("OK" or close) buttons. - * @param {Event} e The click event. - * @private - */ - handleDismiss_: function(e) { - this.setVisible(false); - - // There's a chance that the overlay receives multiple dismiss events; in - // this case, handle it gracefully and return (since all necessary work - // will already have been done). - if (!this.selectedError_) - return; - - // Remove all previous content. - this.codeDiv_.clear(); - - /** @type {extensions.ExtensionErrorList} */ ( - this.overlayDiv_.querySelector('.extension-error-list')) - .onRemoved(); - - this.clearRuntimeContent_(); - - this.selectedError_ = null; - }, - - /** - * Clears the current content. - * @private - */ - clearRuntimeContent_: function() { - if (this.runtimeErrorContent_.parentNode) { - this.runtimeErrorContent_.parentNode.removeChild( - this.runtimeErrorContent_); - this.runtimeErrorContent_.clearError(); - } - this.openDevtoolsButton_.hidden = true; - }, - - /** - * Sets the active error for the overlay. - * @param {?(ManifestError|RuntimeError)} error The error to make active. - * @private - */ - setActiveError_: function(error) { - this.selectedError_ = error; - - // If there is no error (this can happen if, e.g., the user deleted all - // the errors), then clear the content. - if (!error) { - this.codeDiv_.populate( - null, loadTimeData.getString('extensionErrorNoErrorsCodeMessage')); - this.clearRuntimeContent_(); - return; - } - - var extensionUrl = 'chrome-extension://' + error.extensionId + '/'; - // Set or hide runtime content. - if (error.type == chrome.developerPrivate.ErrorType.RUNTIME) { - this.runtimeErrorContent_.setError(error, extensionUrl); - this.overlayDiv_.querySelector('.content-area').insertBefore( - this.runtimeErrorContent_, - this.codeDiv_.nextSibling); - this.openDevtoolsButton_.hidden = false; - this.openDevtoolsButton_.disabled = !error.canInspect; - } else { - this.clearRuntimeContent_(); - } - - // Read the file source to populate the code section, or set it to null if - // the file is unreadable. - if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl)) { - // Use pathname instead of relativeUrl. - var requestFileSourceArgs = {extensionId: error.extensionId, - message: error.message}; - switch (error.type) { - case chrome.developerPrivate.ErrorType.MANIFEST: - requestFileSourceArgs.pathSuffix = error.source; - requestFileSourceArgs.manifestKey = error.manifestKey; - requestFileSourceArgs.manifestSpecific = error.manifestSpecific; - break; - case chrome.developerPrivate.ErrorType.RUNTIME: - // slice(1) because pathname starts with a /. - var pathname = new URL(error.source).pathname.slice(1); - requestFileSourceArgs.pathSuffix = pathname; - requestFileSourceArgs.lineNumber = - error.stackTrace && error.stackTrace[0] ? - error.stackTrace[0].lineNumber : 0; - break; - default: - assertNotReached(); - } - this.requestFileSource(requestFileSourceArgs); - } else { - this.onFileSourceResponse_(null); - } - }, - - /** - * Associate an error with the overlay. This will set the error for the - * overlay, and, if possible, will populate the code section of the overlay - * with the relevant file, load the stack trace, and generate links for - * opening devtools (the latter two only happen for runtime errors). - * @param {Array<(RuntimeError|ManifestError)>} errors The error to show in - * the overlay. - * @param {string} extensionId The id of the extension. - * @param {string} extensionName The name of the extension. - */ - setErrorsAndShowOverlay: function(errors, extensionId, extensionName) { - document.querySelector( - '#extension-error-overlay .extension-error-overlay-title'). - textContent = extensionName; - var errorsDiv = this.overlayDiv_.querySelector('.extension-error-list'); - var extensionErrors = - new extensions.ExtensionErrorList(errors, extensionId); - errorsDiv.parentNode.replaceChild(extensionErrors, errorsDiv); - extensionErrors.addEventListener('activeExtensionErrorChanged', - function(e) { - this.setActiveError_(e.detail); - }.bind(this)); - - if (errors.length > 0) - this.setActiveError_(errors[0]); - this.setVisible(true); - }, - - /** - * Requests a file's source. - * @param {chrome.developerPrivate.RequestFileSourceProperties} args The - * arguments for the call. - */ - requestFileSource: function(args) { - chrome.developerPrivate.requestFileSource( - args, this.onFileSourceResponse_.bind(this)); - }, - - /** - * Set the code to be displayed in the code portion of the overlay. - * @see ExtensionErrorOverlay.requestFileSourceResponse(). - * @param {?chrome.developerPrivate.RequestFileSourceResponse} response The - * response from the request file source call, which will be shown as - * code. If |response| is null, then a "Could not display code" message - * will be displayed instead. - */ - onFileSourceResponse_: function(response) { - this.codeDiv_.populate( - response, // ExtensionCode can handle a null response. - loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); - this.setVisible(true); - }, - }; - - // Export - return { - ExtensionErrorOverlay: ExtensionErrorOverlay - }; -});
diff --git a/chrome/browser/resources/extensions/extension_error_severity_fatal.png b/chrome/browser/resources/extensions/extension_error_severity_fatal.png deleted file mode 100644 index b53dc2c..0000000 --- a/chrome/browser/resources/extensions/extension_error_severity_fatal.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/extensions/extension_error_severity_info.png b/chrome/browser/resources/extensions/extension_error_severity_info.png deleted file mode 100644 index 9aba928..0000000 --- a/chrome/browser/resources/extensions/extension_error_severity_info.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/extensions/extension_error_severity_warning.png b/chrome/browser/resources/extensions/extension_error_severity_warning.png deleted file mode 100644 index d2e3434..0000000 --- a/chrome/browser/resources/extensions/extension_error_severity_warning.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/extensions/extension_focus_manager.js b/chrome/browser/resources/extensions/extension_focus_manager.js deleted file mode 100644 index 377744ca..0000000 --- a/chrome/browser/resources/extensions/extension_focus_manager.js +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - /** - * @constructor - * @extends {cr.ui.FocusManager} - */ - function ExtensionFocusManager() {} - - cr.addSingletonGetter(ExtensionFocusManager); - - ExtensionFocusManager.prototype = { - __proto__: cr.ui.FocusManager.prototype, - - /** @override */ - getFocusParent: function() { - var overlay = extensions.ExtensionSettings.getCurrentOverlay(); - return overlay || $('extension-settings'); - }, - }; - - return { - ExtensionFocusManager: ExtensionFocusManager, - }; -});
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js deleted file mode 100644 index 5a2e396e..0000000 --- a/chrome/browser/resources/extensions/extension_list.js +++ /dev/null
@@ -1,1066 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// <include src="extension_error.js"> - -cr.define('extensions', function() { - 'use strict'; - - var ExtensionType = chrome.developerPrivate.ExtensionType; - - /** - * @param {string} name The name of the template to clone. - * @return {!Element} The freshly cloned template. - */ - function cloneTemplate(name) { - var node = $('templates').querySelector('.' + name).cloneNode(true); - return assertInstanceof(node, Element); - } - - /** - * @extends {HTMLElement} - * @constructor - */ - function ExtensionWrapper() { - var wrapper = cloneTemplate('extension-list-item-wrapper'); - wrapper.__proto__ = ExtensionWrapper.prototype; - wrapper.initialize(); - return wrapper; - } - - ExtensionWrapper.prototype = { - __proto__: HTMLElement.prototype, - - initialize: function() { - var boundary = $('extension-settings-list'); - /** @private {!extensions.FocusRow} */ - this.focusRow_ = new extensions.FocusRow(this, boundary); - }, - - /** @return {!cr.ui.FocusRow} */ - getFocusRow: function() { - return this.focusRow_; - }, - - /** - * Add an item to the focus row and listen for |eventType| events. - * @param {string} focusType A tag used to identify equivalent elements when - * changing focus between rows. - * @param {string} query A query to select the element to set up. - * @param {string=} opt_eventType The type of event to listen to. - * @param {function(Event)=} opt_handler The function that should be called - * by the event. - * @private - */ - setupColumn: function(focusType, query, opt_eventType, opt_handler) { - assert(this.focusRow_.addItem(focusType, query)); - if (opt_eventType) { - assert(opt_handler); - this.querySelector(query).addEventListener(opt_eventType, opt_handler); - } - }, - }; - - var ExtensionCommandsOverlay = extensions.ExtensionCommandsOverlay; - - /** - * Compares two extensions for the order they should appear in the list. - * @param {chrome.developerPrivate.ExtensionInfo} a The first extension. - * @param {chrome.developerPrivate.ExtensionInfo} b The second extension. - * returns {number} -1 if A comes before B, 1 if A comes after B, 0 if equal. - */ - function compareExtensions(a, b) { - function compare(x, y) { - return x < y ? -1 : (x > y ? 1 : 0); - } - function compareLocation(x, y) { - if (x.location == y.location) - return 0; - if (x.location == chrome.developerPrivate.Location.UNPACKED) - return -1; - if (y.location == chrome.developerPrivate.Location.UNPACKED) - return 1; - return 0; - } - return compareLocation(a, b) || - compare(a.name.toLowerCase(), b.name.toLowerCase()) || - compare(a.id, b.id); - } - - /** @interface */ - function ExtensionListDelegate() {} - - ExtensionListDelegate.prototype = { - /** - * Called when the number of extensions in the list has changed. - */ - onExtensionCountChanged: assertNotReached, - }; - - /** - * Creates a new list of extensions. - * @param {extensions.ExtensionListDelegate} delegate - * @constructor - * @extends {HTMLDivElement} - */ - function ExtensionList(delegate) { - var div = document.createElement('div'); - div.__proto__ = ExtensionList.prototype; - div.initialize(delegate); - return div; - } - - ExtensionList.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * Indicates whether an embedded options page that was navigated to through - * the '?options=' URL query has been shown to the user. This is necessary - * to prevent showExtensionNodes_ from opening the options more than once. - * @type {boolean} - * @private - */ - optionsShown_: false, - - /** @private {!cr.ui.FocusGrid} */ - focusGrid_: new cr.ui.FocusGrid(), - - /** - * Indicates whether an uninstall dialog is being shown to prevent multiple - * dialogs from being displayed. - * @private {boolean} - */ - uninstallIsShowing_: false, - - /** - * Indicates whether a permissions prompt is showing. - * @private {boolean} - */ - permissionsPromptIsShowing_: false, - - /** - * Whether or not any initial navigation (like scrolling to an extension, - * or opening an options page) has occurred. - * @private {boolean} - */ - didInitialNavigation_: false, - - /** - * Whether or not incognito mode is available. - * @private {boolean} - */ - incognitoAvailable_: false, - - /** - * Whether or not the app info dialog is enabled. - * @private {boolean} - */ - enableAppInfoDialog_: false, - - /** - * Initializes the list. - * @param {!extensions.ExtensionListDelegate} delegate - */ - initialize: function(delegate) { - /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */ - this.extensions_ = []; - - /** @private {!extensions.ExtensionListDelegate} */ - this.delegate_ = delegate; - - this.resetLoadFinished(); - - chrome.developerPrivate.onItemStateChanged.addListener( - function(eventData) { - var EventType = chrome.developerPrivate.EventType; - switch (eventData.event_type) { - case EventType.VIEW_REGISTERED: - case EventType.VIEW_UNREGISTERED: - case EventType.INSTALLED: - case EventType.LOADED: - case EventType.UNLOADED: - case EventType.ERROR_ADDED: - case EventType.ERRORS_REMOVED: - case EventType.PREFS_CHANGED: - if (eventData.extensionInfo) { - this.updateOrCreateWrapper_(eventData.extensionInfo); - this.focusGrid_.ensureRowActive(); - } - break; - case EventType.UNINSTALLED: - var index = this.getIndexOfExtension_(eventData.item_id); - this.extensions_.splice(index, 1); - this.removeWrapper_(/**@type {!ExtensionWrapper} */ ( - getRequiredElement(eventData.item_id))); - break; - default: - assertNotReached(); - } - - if (eventData.event_type == EventType.UNLOADED) - this.hideEmbeddedExtensionOptions_(eventData.item_id); - - if (eventData.event_type == EventType.INSTALLED || - eventData.event_type == EventType.UNINSTALLED) { - this.delegate_.onExtensionCountChanged(); - } - - if (eventData.event_type == EventType.LOADED || - eventData.event_type == EventType.UNLOADED || - eventData.event_type == EventType.PREFS_CHANGED || - eventData.event_type == EventType.UNINSTALLED) { - // We update the commands overlay whenever an extension is added or - // removed (other updates wouldn't affect command-ly things). We - // need both UNLOADED and UNINSTALLED since the UNLOADED event results - // in an extension losing active keybindings, and UNINSTALLED can - // result in the "Keyboard shortcuts" link being removed. - ExtensionCommandsOverlay.updateExtensionsData(this.extensions_); - } - }.bind(this)); - }, - - /** - * Resets the |loadFinished| promise so that it can be used again; this - * is useful if the page updates and tests need to wait for it to finish. - */ - resetLoadFinished: function() { - /** - * |loadFinished| should be used for testing purposes and will be - * fulfilled when this list has finished loading the first time. - * @type {Promise} - * */ - this.loadFinished = new Promise(function(resolve, reject) { - /** @private {function(?)} */ - this.resolveLoadFinished_ = resolve; - }.bind(this)); - }, - - /** - * Updates the extensions on the page. - * @param {boolean} incognitoAvailable Whether or not incognito is allowed. - * @param {boolean} enableAppInfoDialog Whether or not the app info dialog - * is enabled. - * @return {Promise} A promise that is resolved once the extensions data is - * fully updated. - */ - updateExtensionsData: function(incognitoAvailable, enableAppInfoDialog) { - // If we start to need more information about the extension configuration, - // consider passing in the full object from the ExtensionSettings. - this.incognitoAvailable_ = incognitoAvailable; - this.enableAppInfoDialog_ = enableAppInfoDialog; - /** @private {Promise} */ - this.extensionsUpdated_ = new Promise(function(resolve, reject) { - chrome.developerPrivate.getExtensionsInfo( - {includeDisabled: true, includeTerminated: true}, - function(extensions) { - // Sort in order of unpacked vs. packed, followed by name, followed by - // id. - extensions.sort(compareExtensions); - this.extensions_ = extensions; - this.showExtensionNodes_(); - - // We keep the commands overlay's extension info in sync, so that we - // don't duplicate the same querying logic there. - ExtensionCommandsOverlay.updateExtensionsData(this.extensions_); - - resolve(); - - // |resolve| is async so it's necessary to use |then| here in order to - // do work after other |then|s have finished. This is important so - // elements are visible when these updates happen. - this.extensionsUpdated_.then(function() { - this.onUpdateFinished_(); - this.resolveLoadFinished_(); - }.bind(this)); - }.bind(this)); - }.bind(this)); - return this.extensionsUpdated_; - }, - - /** - * Updates elements that need to be visible in order to update properly. - * @private - */ - onUpdateFinished_: function() { - // Cannot focus or highlight a extension if there are none, and we should - // only scroll to a particular extension or open the options page once. - if (this.extensions_.length == 0 || this.didInitialNavigation_) - return; - - this.didInitialNavigation_ = true; - assert(!this.hidden); - assert(!this.parentElement.hidden); - - var idToHighlight = this.getIdQueryParam_(); - if (idToHighlight) { - var wrapper = /** @type {ExtensionWrapper} */ ($(idToHighlight)); - if (wrapper) { - this.scrollToWrapper_(idToHighlight); - - var focusRow = wrapper.getFocusRow(); - (focusRow.getFirstFocusable('enabled') || - focusRow.getFirstFocusable('remove-enterprise') || - focusRow.getFirstFocusable('website') || - focusRow.getFirstFocusable('details')).focus(); - } - } - - var idToOpenOptions = this.getOptionsQueryParam_(); - if (idToOpenOptions && $(idToOpenOptions)) - this.showEmbeddedExtensionOptions_(idToOpenOptions, true); - }, - - /** @return {number} The number of extensions being displayed. */ - getNumExtensions: function() { - return this.extensions_.length; - }, - - /** - * @param {string} id The id of the extension. - * @return {number} The index of the extension with the given id. - * @private - */ - getIndexOfExtension_: function(id) { - for (var i = 0; i < this.extensions_.length; ++i) { - if (this.extensions_[i].id == id) - return i; - } - return -1; - }, - - getIdQueryParam_: function() { - return parseQueryParams(document.location)['id']; - }, - - getOptionsQueryParam_: function() { - return parseQueryParams(document.location)['options']; - }, - - /** - * Creates or updates all extension items from scratch. - * @private - */ - showExtensionNodes_: function() { - // Any node that is not updated will be removed. - var seenIds = []; - - // Iterate over the extension data and add each item to the list. - this.extensions_.forEach(function(extension) { - seenIds.push(extension.id); - this.updateOrCreateWrapper_(extension); - }, this); - this.focusGrid_.ensureRowActive(); - - // Remove extensions that are no longer installed. - var wrappers = document.querySelectorAll( - '.extension-list-item-wrapper[id]'); - Array.prototype.forEach.call(wrappers, function(wrapper) { - if (seenIds.indexOf(wrapper.id) < 0) - this.removeWrapper_(wrapper); - }, this); - }, - - /** - * Removes the wrapper from the DOM and updates the focused element if - * needed. - * @param {!ExtensionWrapper} wrapper - * @private - */ - removeWrapper_: function(wrapper) { - // If focus is in the wrapper about to be removed, move it first. This - // happens when clicking the trash can to remove an extension. - if (wrapper.contains(document.activeElement)) { - var wrappers = /** @type {NodeList<ExtensionWrapper>}*/ ( - document.querySelectorAll('.extension-list-item-wrapper[id]')); - var index = Array.prototype.indexOf.call(wrappers, wrapper); - assert(index != -1); - var focusableWrapper = wrappers[index + 1] || wrappers[index - 1]; - if (focusableWrapper) { - var newFocusRow = focusableWrapper.getFocusRow(); - newFocusRow.getEquivalentElement(document.activeElement).focus(); - } - } - - var focusRow = wrapper.getFocusRow(); - this.focusGrid_.removeRow(focusRow); - this.focusGrid_.ensureRowActive(); - focusRow.destroy(); - - wrapper.parentNode.removeChild(wrapper); - }, - - /** - * Scrolls the page down to the extension node with the given id. - * @param {string} extensionId The id of the extension to scroll to. - * @private - */ - scrollToWrapper_: function(extensionId) { - // Scroll offset should be calculated slightly higher than the actual - // offset of the element being scrolled to, so that it ends up not all - // the way at the top. That way it is clear that there are more elements - // above the element being scrolled to. - var wrapper = $(extensionId); - var scrollFudge = 1.2; - var scrollTop = wrapper.offsetTop - scrollFudge * wrapper.clientHeight; - setScrollTopForDocument(document, scrollTop); - }, - - /** - * Synthesizes and initializes an HTML element for the extension metadata - * given in |extension|. - * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary - * of extension metadata. - * @param {?Element} nextWrapper The newly created wrapper will be inserted - * before |nextWrapper| if non-null (else it will be appended to the - * wrapper list). - * @private - */ - createWrapper_: function(extension, nextWrapper) { - var wrapper = new ExtensionWrapper; - wrapper.id = extension.id; - - // The 'Permissions' link. - wrapper.setupColumn('details', '.permissions-link', 'click', function(e) { - if (!this.permissionsPromptIsShowing_) { - chrome.developerPrivate.showPermissionsDialog(extension.id, - function() { - this.permissionsPromptIsShowing_ = false; - }.bind(this)); - this.permissionsPromptIsShowing_ = true; - } - e.preventDefault(); - }); - - wrapper.setupColumn('options', '.options-button', 'click', function(e) { - this.showEmbeddedExtensionOptions_(extension.id, false); - e.preventDefault(); - }.bind(this)); - - // The 'Options' button or link, depending on its behaviour. - // Set an href to get the correct mouse-over appearance (link, - // footer) - but the actual link opening is done through developerPrivate - // API with a preventDefault(). - wrapper.querySelector('.options-link').href = - extension.optionsPage ? extension.optionsPage.url : ''; - wrapper.setupColumn('options', '.options-link', 'click', function(e) { - chrome.developerPrivate.showOptions(extension.id); - e.preventDefault(); - }); - - // The 'View in Web Store/View Web Site' link. - wrapper.setupColumn('website', '.site-link'); - - // The 'Launch' link. - wrapper.setupColumn('launch', '.launch-link', 'click', function(e) { - chrome.management.launchApp(extension.id); - }); - - // The 'Reload' link. - wrapper.setupColumn('localReload', '.reload-link', 'click', function(e) { - chrome.developerPrivate.reload(extension.id, {failQuietly: true}); - }); - - wrapper.setupColumn('errors', '.errors-link', 'click', function(e) { - var extensionId = extension.id; - assert(this.extensions_.length > 0); - var newEx = this.extensions_.filter(function(e) { - return e.id == extensionId; - })[0]; - var errors = newEx.manifestErrors.concat(newEx.runtimeErrors); - extensions.ExtensionErrorOverlay.getInstance().setErrorsAndShowOverlay( - errors, extensionId, newEx.name); - }.bind(this)); - - wrapper.setupColumn('suspiciousLearnMore', - '.suspicious-install-message .learn-more-link'); - - // The path, if provided by unpacked extension. - wrapper.setupColumn('loadPath', '.load-path a:first-of-type', 'click', - function(e) { - chrome.developerPrivate.showPath(extension.id); - e.preventDefault(); - }); - - // The 'allow in incognito' checkbox. - wrapper.setupColumn('incognito', '.incognito-control input', 'change', - function(e) { - var butterBar = wrapper.querySelector('.butter-bar'); - var checked = e.target.checked; - butterBar.hidden = !checked || - extension.type == ExtensionType.HOSTED_APP; - chrome.developerPrivate.updateExtensionConfiguration({ - extensionId: extension.id, - incognitoAccess: e.target.checked - }); - }.bind(this)); - - // The 'collect errors' checkbox. This should only be visible if the - // error console is enabled - we can detect this by the existence of the - // |errorCollectionEnabled| property. - wrapper.setupColumn('collectErrors', '.error-collection-control input', - 'change', function(e) { - chrome.developerPrivate.updateExtensionConfiguration({ - extensionId: extension.id, - errorCollection: e.target.checked - }); - }); - - // The 'allow on all urls' checkbox. This should only be visible if - // active script restrictions are enabled. If they are not enabled, no - // extensions should want all urls. - wrapper.setupColumn('allUrls', '.all-urls-control input', 'click', - function(e) { - chrome.developerPrivate.updateExtensionConfiguration({ - extensionId: extension.id, - runOnAllUrls: e.target.checked - }); - }); - - // The 'allow file:// access' checkbox. - wrapper.setupColumn('localUrls', '.file-access-control input', 'click', - function(e) { - chrome.developerPrivate.updateExtensionConfiguration({ - extensionId: extension.id, - fileAccess: e.target.checked - }); - }); - - // The 'Reload' terminated link. - wrapper.setupColumn('terminatedReload', '.terminated-reload-link', - 'click', function(e) { - chrome.developerPrivate.reload(extension.id, {failQuietly: true}); - }); - - // The 'Repair' corrupted link. - wrapper.setupColumn('repair', '.corrupted-repair-button', 'click', - function(e) { - chrome.developerPrivate.repairExtension(extension.id); - }); - - // The 'Enabled' checkbox. - wrapper.setupColumn('enabled', '.enable-checkbox input', 'click', - function(e) { - var checked = e.target.checked; - // TODO(devlin): What should we do if this fails? Ideally we want to - // show some kind of error or feedback to the user if this fails. - chrome.management.setEnabled(extension.id, checked); - - // This may seem counter-intuitive (to not set/clear the checkmark) - // but this page will be updated asynchronously if the extension - // becomes enabled/disabled. It also might not become enabled or - // disabled, because the user might e.g. get prompted when enabling - // and choose not to. - e.preventDefault(); - }); - - // 'Remove' button. - var trash = cloneTemplate('trash'); - trash.title = loadTimeData.getString('extensionUninstall'); - - wrapper.querySelector('.enable-controls').appendChild(trash); - - wrapper.setupColumn('remove-enterprise', '.trash', 'click', function(e) { - trash.classList.add('open'); - trash.classList.toggle('mouse-clicked', e.detail > 0); - if (this.uninstallIsShowing_) - return; - this.uninstallIsShowing_ = true; - chrome.management.uninstall(extension.id, - {showConfirmDialog: true}, - function() { - // TODO(devlin): What should we do if the uninstall fails? - this.uninstallIsShowing_ = false; - - if (trash.classList.contains('mouse-clicked')) - trash.blur(); - - if (chrome.runtime.lastError) { - // The uninstall failed (e.g. a cancel). Allow the trash to close. - trash.classList.remove('open'); - } else { - // Leave the trash open if the uninstall succeded. Otherwise it can - // half-close right before it's removed when the DOM is modified. - } - }.bind(this)); - }.bind(this)); - - // Maintain the order that nodes should be in when creating as well as - // when adding only one new wrapper. - this.insertBefore(wrapper, nextWrapper); - this.updateWrapper_(extension, wrapper); - - var nextRow = this.focusGrid_.getRowForRoot(nextWrapper); // May be null. - this.focusGrid_.addRowBefore(wrapper.getFocusRow(), nextRow); - }, - - /** - * Updates an HTML element for the extension metadata given in |extension|. - * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary of - * extension metadata. - * @param {!ExtensionWrapper} wrapper The extension wrapper element to - * update. - * @private - */ - updateWrapper_: function(extension, wrapper) { - var isActive = - extension.state == chrome.developerPrivate.ExtensionState.ENABLED; - wrapper.classList.toggle('inactive-extension', !isActive); - wrapper.classList.remove('controlled', 'may-not-remove'); - - if (extension.controlledInfo) { - wrapper.classList.add('controlled'); - } else if (!extension.userMayModify || - extension.mustRemainInstalled || - extension.dependentExtensions.length > 0) { - wrapper.classList.add('may-not-remove'); - } - - var item = wrapper.querySelector('.extension-list-item'); - item.style.backgroundImage = 'url(' + extension.iconUrl + ')'; - - this.setText_(wrapper, '.extension-title', extension.name); - this.setText_(wrapper, '.extension-version', extension.version); - this.setText_(wrapper, '.location-text', extension.locationText || ''); - this.setText_(wrapper, '.blacklist-text', extension.blacklistText || ''); - this.setText_(wrapper, '.extension-description', extension.description); - - // The 'allow in incognito' checkbox. - this.updateVisibility_(wrapper, '.incognito-control', - isActive && this.incognitoAvailable_, - function(item) { - var incognito = item.querySelector('input'); - incognito.disabled = !extension.incognitoAccess.isEnabled; - incognito.checked = extension.incognitoAccess.isActive; - }); - var showButterBar = isActive && - extension.incognitoAccess.isActive && - extension.type != ExtensionType.HOSTED_APP; - // The 'allow in incognito' butter bar. - this.updateVisibility_(wrapper, '.butter-bar', showButterBar); - - // The 'collect errors' checkbox. This should only be visible if the - // error console is enabled - we can detect this by the existence of the - // |errorCollectionEnabled| property. - this.updateVisibility_( - wrapper, '.error-collection-control', - isActive && extension.errorCollection.isEnabled, - function(item) { - item.querySelector('input').checked = - extension.errorCollection.isActive; - }); - - // The 'allow on all urls' checkbox. This should only be visible if - // active script restrictions are enabled. If they are not enabled, no - // extensions should want all urls. - this.updateVisibility_( - wrapper, '.all-urls-control', - isActive && extension.runOnAllUrls.isEnabled, - function(item) { - item.querySelector('input').checked = extension.runOnAllUrls.isActive; - }); - - // The 'allow file:// access' checkbox. - this.updateVisibility_(wrapper, '.file-access-control', - isActive && extension.fileAccess.isEnabled, - function(item) { - item.querySelector('input').checked = extension.fileAccess.isActive; - }); - - // The 'Options' button or link, depending on its behaviour. - var optionsEnabled = isActive && !!extension.optionsPage; - this.updateVisibility_(wrapper, '.options-link', optionsEnabled && - extension.optionsPage.openInTab); - this.updateVisibility_(wrapper, '.options-button', optionsEnabled && - !extension.optionsPage.openInTab); - - // The 'View in Web Store/View Web Site' link. - var siteLinkEnabled = !!extension.homePage.url && - !this.enableAppInfoDialog_; - this.updateVisibility_(wrapper, '.site-link', siteLinkEnabled, - function(item) { - item.href = extension.homePage.url; - item.textContent = loadTimeData.getString( - extension.homePage.specified ? 'extensionSettingsVisitWebsite' : - 'extensionSettingsVisitWebStore'); - }); - - var isUnpacked = - extension.location == chrome.developerPrivate.Location.UNPACKED; - // The 'Reload' link. - this.updateVisibility_(wrapper, '.reload-link', isActive && isUnpacked); - - // The 'Launch' link. - this.updateVisibility_( - wrapper, '.launch-link', - isUnpacked && extension.type == ExtensionType.PLATFORM_APP && - isActive); - - // The 'Errors' link. - var hasErrors = extension.runtimeErrors.length > 0 || - extension.manifestErrors.length > 0; - this.updateVisibility_(wrapper, '.errors-link', hasErrors, - function(item) { - var Level = chrome.developerPrivate.ErrorLevel; - - var map = {}; - map[Level.LOG] = {weight: 0, name: 'extension-error-info-icon'}; - map[Level.WARN] = {weight: 1, name: 'extension-error-warning-icon'}; - map[Level.ERROR] = {weight: 2, name: 'extension-error-fatal-icon'}; - - // Find the highest severity of all the errors; manifest errors all have - // a 'warning' level severity. - var highestSeverity = extension.runtimeErrors.reduce( - function(prev, error) { - return map[error.severity].weight > map[prev].weight ? - error.severity : prev; - }, extension.manifestErrors.length ? Level.WARN : Level.LOG); - - // Adjust the class on the icon. - var icon = item.querySelector('.extension-error-icon'); - // TODO(hcarmona): Populate alt text with a proper description since - // this icon conveys the severity of the error. (info, warning, fatal). - icon.alt = ''; - icon.className = 'extension-error-icon'; // Remove other classes. - icon.classList.add(map[highestSeverity].name); - }); - - // The 'Reload' terminated link. - var isTerminated = - extension.state == chrome.developerPrivate.ExtensionState.TERMINATED; - this.updateVisibility_(wrapper, '.terminated-reload-link', isTerminated); - - // The 'Repair' corrupted link. - var canRepair = !isTerminated && - extension.disableReasons.corruptInstall && - extension.location == - chrome.developerPrivate.Location.FROM_STORE; - this.updateVisibility_(wrapper, '.corrupted-repair-button', canRepair); - - // The 'Enabled' checkbox. - var isOK = !isTerminated && !canRepair; - this.updateVisibility_(wrapper, '.enable-checkbox', isOK, function(item) { - var enableCheckboxDisabled = - !extension.userMayModify || - extension.disableReasons.suspiciousInstall || - extension.disableReasons.corruptInstall || - extension.disableReasons.updateRequired || - extension.dependentExtensions.length > 0 || - extension.state == - chrome.developerPrivate.ExtensionState.BLACKLISTED; - item.querySelector('input').disabled = enableCheckboxDisabled; - item.querySelector('input').checked = isActive; - }); - - // Indicator for extensions controlled by policy. - var controlNode = wrapper.querySelector('.enable-controls'); - var indicator = - controlNode.querySelector('.controlled-extension-indicator'); - var needsIndicator = isOK && extension.controlledInfo; - - if (needsIndicator && !indicator) { - indicator = new cr.ui.ControlledIndicator(); - indicator.classList.add('controlled-extension-indicator'); - var ControllerType = chrome.developerPrivate.ControllerType; - var controlledByStr = ''; - switch (extension.controlledInfo.type) { - case ControllerType.POLICY: - controlledByStr = 'policy'; - break; - case ControllerType.CHILD_CUSTODIAN: - controlledByStr = 'child-custodian'; - break; - case ControllerType.SUPERVISED_USER_CUSTODIAN: - controlledByStr = 'supervised-user-custodian'; - break; - } - indicator.setAttribute('controlled-by', controlledByStr); - var text = extension.controlledInfo.text; - indicator.setAttribute('text' + controlledByStr, text); - indicator.image.setAttribute('aria-label', text); - controlNode.appendChild(indicator); - wrapper.setupColumn('remove-enterprise', '[controlled-by] div'); - } else if (!needsIndicator && indicator) { - controlNode.removeChild(indicator); - } - - // Developer mode //////////////////////////////////////////////////////// - - // First we have the id. - var idLabel = wrapper.querySelector('.extension-id'); - idLabel.textContent = ' ' + extension.id; - - // Then the path, if provided by unpacked extension. - this.updateVisibility_(wrapper, '.load-path', isUnpacked, - function(item) { - item.querySelector('a:first-of-type').textContent = - ' ' + extension.prettifiedPath; - }); - - // Then the 'managed, cannot uninstall/disable' message. - // We would like to hide managed installed message since this - // extension is disabled. - var isRequired = - !extension.userMayModify || extension.mustRemainInstalled; - this.updateVisibility_(wrapper, '.managed-message', isRequired && - !extension.disableReasons.updateRequired); - - // Then the 'This isn't from the webstore, looks suspicious' message. - var isSuspicious = extension.disableReasons.suspiciousInstall; - this.updateVisibility_(wrapper, '.suspicious-install-message', - !isRequired && isSuspicious); - - // Then the 'This is a corrupt extension' message. - this.updateVisibility_(wrapper, '.corrupt-install-message', !isRequired && - extension.disableReasons.corruptInstall); - - // Then the 'An update required by enterprise policy' message. Note that - // a force-installed extension might be disabled due to being outdated - // as well. - this.updateVisibility_(wrapper, '.update-required-message', - extension.disableReasons.updateRequired); - - // The 'following extensions depend on this extension' list. - var hasDependents = extension.dependentExtensions.length > 0; - wrapper.classList.toggle('developer-extras', hasDependents); - this.updateVisibility_(wrapper, '.dependent-extensions-message', - hasDependents, function(item) { - var dependentList = item.querySelector('ul'); - dependentList.textContent = ''; - extension.dependentExtensions.forEach(function(dependentExtension) { - var depNode = cloneTemplate('dependent-list-item'); - depNode.querySelector('.dep-extension-title').textContent = - dependentExtension.name; - depNode.querySelector('.dep-extension-id').textContent = - dependentExtension.id; - dependentList.appendChild(depNode); - }, this); - }.bind(this)); - - // The active views. - this.updateVisibility_(wrapper, '.active-views', - extension.views.length > 0, function(item) { - var link = item.querySelector('a'); - - // Link needs to be an only child before the list is updated. - while (link.nextElementSibling) - item.removeChild(link.nextElementSibling); - - // Link needs to be cleaned up if it was used before. - link.textContent = ''; - if (link.clickHandler) - link.removeEventListener('click', link.clickHandler); - - extension.views.forEach(function(view, i) { - if (view.type == chrome.developerPrivate.ViewType.EXTENSION_DIALOG || - view.type == chrome.developerPrivate.ViewType.EXTENSION_POPUP) { - return; - } - var displayName; - if (view.url.startsWith('chrome-extension://')) { - var pathOffset = 'chrome-extension://'.length + 32 + 1; - displayName = view.url.substring(pathOffset); - if (displayName == '_generated_background_page.html') - displayName = loadTimeData.getString('backgroundPage'); - } else { - displayName = view.url; - } - var label = displayName + - (view.incognito ? - ' ' + loadTimeData.getString('viewIncognito') : '') + - (view.renderProcessId == -1 ? - ' ' + loadTimeData.getString('viewInactive') : '') + - (view.isIframe ? - ' ' + loadTimeData.getString('viewIframe') : ''); - link.textContent = label; - link.clickHandler = function(e) { - chrome.developerPrivate.openDevTools({ - extensionId: extension.id, - renderProcessId: view.renderProcessId, - renderViewId: view.renderViewId, - incognito: view.incognito - }); - }; - link.addEventListener('click', link.clickHandler); - - if (i < extension.views.length - 1) { - link = link.cloneNode(true); - item.appendChild(link); - } - - wrapper.setupColumn('activeView', '.active-views a:last-of-type'); - }); - }); - - // The extension warnings (describing runtime issues). - this.updateVisibility_(wrapper, '.extension-warnings', - extension.runtimeWarnings.length > 0, - function(item) { - var warningList = item.querySelector('ul'); - warningList.textContent = ''; - extension.runtimeWarnings.forEach(function(warning) { - var li = document.createElement('li'); - warningList.appendChild(li).innerText = warning; - }); - }); - - // Install warnings. - this.updateVisibility_(wrapper, '.install-warnings', - extension.installWarnings.length > 0, - function(item) { - var installWarningList = item.querySelector('ul'); - installWarningList.textContent = ''; - if (extension.installWarnings) { - extension.installWarnings.forEach(function(warning) { - var li = document.createElement('li'); - li.innerText = warning; - installWarningList.appendChild(li); - }); - } - }); - - if (location.hash.substr(1) == extension.id) { - // Scroll beneath the fixed header so that the extension is not - // obscured. - var topScroll = wrapper.offsetTop - $('page-header').offsetHeight; - var pad = parseInt(window.getComputedStyle(wrapper).marginTop, 10); - if (!isNaN(pad)) - topScroll -= pad / 2; - setScrollTopForDocument(document, topScroll); - } - }, - - /** - * Updates an element's textContent. - * @param {Node} node Ancestor of the element specified by |query|. - * @param {string} query A query to select an element in |node|. - * @param {string} textContent - * @private - */ - setText_: function(node, query, textContent) { - node.querySelector(query).textContent = textContent; - }, - - /** - * Updates an element's visibility and calls |shownCallback| if it is - * visible. - * @param {Node} node Ancestor of the element specified by |query|. - * @param {string} query A query to select an element in |node|. - * @param {boolean} visible Whether the element should be visible or not. - * @param {function(Element)=} opt_shownCallback Callback if the element is - * visible. The element passed in will be the element specified by - * |query|. - * @private - */ - updateVisibility_: function(node, query, visible, opt_shownCallback) { - var element = assertInstanceof(node.querySelector(query), Element); - element.hidden = !visible; - if (visible && opt_shownCallback) - opt_shownCallback(element); - }, - - /** - * Opens the extension options overlay for the extension with the given id. - * @param {string} extensionId The id of extension whose options page should - * be displayed. - * @param {boolean} scroll Whether the page should scroll to the extension - * @private - */ - showEmbeddedExtensionOptions_: function(extensionId, scroll) { - if (this.optionsShown_) - return; - - // Get the extension from the given id. - var extension = this.extensions_.filter(function(extension) { - return extension.state == - chrome.developerPrivate.ExtensionState.ENABLED && - extension.id == extensionId; - })[0]; - - if (!extension) - return; - - if (scroll) - this.scrollToWrapper_(extensionId); - - // Add the options query string. Corner case: the 'options' query string - // will clobber the 'id' query string if the options link is clicked when - // 'id' is in the URL, or if both query strings are in the URL. - window.history.replaceState({}, '', '/?options=' + extensionId); - - var overlay = extensions.ExtensionOptionsOverlay.getInstance(); - var shownCallback = function() { - // This overlay doesn't get focused automatically as <extensionoptions> - // is created after the overlay is shown. - if (cr.ui.FocusOutlineManager.forDocument(document).visible) - overlay.setInitialFocus(); - }; - overlay.setExtensionAndShow(extensionId, extension.name, - extension.iconUrl, shownCallback); - this.optionsShown_ = true; - - var self = this; - $('overlay').addEventListener('cancelOverlay', function f() { - self.optionsShown_ = false; - $('overlay').removeEventListener('cancelOverlay', f); - - // Remove the options query string. - window.history.replaceState({}, '', '/'); - }); - - // TODO(dbeam): why do we need to focus <extensionoptions> before and - // after its showing animation? Makes very little sense to me. - overlay.setInitialFocus(); - }, - - /** - * Hides the extension options overlay for the extension with id - * |extensionId|. If there is an overlay showing for a different extension, - * nothing happens. - * @param {string} extensionId ID of the extension to hide. - * @private - */ - hideEmbeddedExtensionOptions_: function(extensionId) { - if (!this.optionsShown_) - return; - - var overlay = extensions.ExtensionOptionsOverlay.getInstance(); - if (overlay.getExtensionId() == extensionId) - overlay.close(); - }, - - /** - * Updates or creates a wrapper for |extension|. - * @param {!chrome.developerPrivate.ExtensionInfo} extension The information - * about the extension to update. - * @private - */ - updateOrCreateWrapper_: function(extension) { - var currIndex = this.getIndexOfExtension_(extension.id); - if (currIndex != -1) { - // If there is a current version of the extension, update it with the - // new version. - this.extensions_[currIndex] = extension; - } else { - // If the extension isn't found, push it back and sort. Technically, we - // could optimize by inserting it at the right location, but since this - // only happens on extension install, it's not worth it. - this.extensions_.push(extension); - this.extensions_.sort(compareExtensions); - } - - var wrapper = /**@type {ExtensionWrapper} */ ($(extension.id)); - if (wrapper) { - this.updateWrapper_(extension, wrapper); - } else { - var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1]; - this.createWrapper_(extension, nextExt ? $(nextExt.id) : null); - } - } - }; - - return { - ExtensionList: ExtensionList, - ExtensionListDelegate: ExtensionListDelegate - }; -});
diff --git a/chrome/browser/resources/extensions/extension_load_error.css b/chrome/browser/resources/extensions/extension_load_error.css deleted file mode 100644 index 620eed10..0000000 --- a/chrome/browser/resources/extensions/extension_load_error.css +++ /dev/null
@@ -1,50 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#extension-load-error { - -webkit-margin-end: 20px; - -webkit-padding-end: 3px; - -webkit-padding-start: 10px; - background-color: rgba(255, 249, 221, 1); - border-radius: 7px; - display: flex; - flex-direction: column; - font-size: 1.1em; - margin-top: 10px; - padding-bottom: 10px; -} - -#extension-load-error h2 { - font-size: 14px; - font-weight: bold; -} - -#extension-load-error-message { - margin-top: 5px; -} - -#extension-load-error-manifest { - background-color: rgba(255, 250, 240, 1); - margin-bottom: 10px; - margin-top: 10px; - max-height: 100px; -} - -#extension-load-error-manifest .extension-code-highlighted-source { - background-color: pink; -} - -#extension-load-error-controls { - align-self: flex-end; -} - -#extension-load-error-additional > span { - font-size: 12px; - font-weight: bold; -} - -#extension-load-error-additional > li { - margin-bottom: 0; - margin-top: 3px; -}
diff --git a/chrome/browser/resources/extensions/extension_load_error.html b/chrome/browser/resources/extensions/extension_load_error.html deleted file mode 100644 index 8823bfb..0000000 --- a/chrome/browser/resources/extensions/extension_load_error.html +++ /dev/null
@@ -1,27 +0,0 @@ -<!doctype html> -<!-- -Copyright 2014 The Chromium Authors. All rights reserved. -Use of this source code is governed by a BSD-style license that can be found -in the LICENSE file. ---> -<div id="extension-load-error" hidden> - <h2>$i18n{extensionLoadErrorHeading}</h2> - <div id="extension-load-error-message"> - <span>$i18n{extensionLoadErrorMessage}</span> - <span id="extension-load-error-path"></span> - </div> - <span id="extension-load-error-reason"></span> - <div id="extension-load-error-manifest" class="extension-code"></div> - <div id="extension-load-error-controls"> - <button id="extension-load-error-retry-button"> - $i18n{extensionLoadErrorRetry} - </button> - <button id="extension-load-error-give-up-button"> - $i18n{extensionLoadErrorGiveUp} - </button> - </div> - <div id="extension-load-error-additional" hidden> - <span>$i18n{extensionLoadAdditionalFailures}</span> - <ul></ul> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/extension_loader.js b/chrome/browser/resources/extensions/extension_loader.js deleted file mode 100644 index 5c03d50..0000000 --- a/chrome/browser/resources/extensions/extension_loader.js +++ /dev/null
@@ -1,234 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - 'use strict'; - - /** - * Construct an ExtensionLoadError around the given |div|. - * @param {HTMLDivElement} div The HTML div for the extension load error. - * @constructor - * @extends {HTMLDivElement} - */ - function ExtensionLoadError(div) { - div.__proto__ = ExtensionLoadError.prototype; - /** @type {ExtensionLoadError} */ (div).init(); - return div; - } - - /** - * Construct a Failure. - * @param {string} filePath The path to the unpacked extension. - * @param {string} error The reason the extension failed to load. - * @param {ExtensionHighlight} manifest Three 'highlight' strings in - * |manifest| represent three portions of the file's content to display - - * the portion which is most relevant and should be emphasized - * (highlight), and the parts both before and after this portion. These - * may be empty. - * @param {HTMLLIElement} listElement The HTML element used for displaying the - * failure path for the additional failures UI. - * @constructor - * @extends {HTMLDivElement} - */ - function Failure(filePath, error, manifest, listElement) { - this.path = filePath; - this.error = error; - this.manifest = manifest; - this.listElement = listElement; - } - - ExtensionLoadError.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * Initialize the ExtensionLoadError div. - */ - init: function() { - /** - * The element which displays the path of the extension. - * @type {HTMLElement} - * @private - */ - this.path_ = /** @type {HTMLElement} */( - this.querySelector('#extension-load-error-path')); - - /** - * The element which displays the reason the extension failed to load. - * @type {HTMLElement} - * @private - */ - this.reason_ = /** @type {HTMLElement} */( - this.querySelector('#extension-load-error-reason')); - - /** - * The element which displays the manifest code. - * @type {extensions.ExtensionCode} - * @private - */ - this.manifest_ = new extensions.ExtensionCode( - this.querySelector('#extension-load-error-manifest')); - - /** - * The element which displays information about additional errors. - * @type {HTMLElement} - * @private - */ - this.additional_ = /** @type {HTMLUListElement} */( - this.querySelector('#extension-load-error-additional')); - this.additional_.list = this.additional_.getElementsByTagName('ul')[0]; - - /** - * An array of Failures for keeping track of multiple active failures. - * @type {Array<Failure>} - * @private - */ - this.failures_ = []; - - this.querySelector('#extension-load-error-retry-button').addEventListener( - 'click', function(e) { - chrome.send('extensionLoaderRetry'); - this.remove_(); - }.bind(this)); - - this.querySelector('#extension-load-error-give-up-button'). - addEventListener('click', function(e) { - chrome.send('extensionLoaderIgnoreFailure'); - this.remove_(); - }.bind(this)); - - chrome.send('extensionLoaderDisplayFailures'); - }, - - /** - * Add a failure to failures_ array. If there is already a displayed - * failure, display the additional failures element. - * @param {Array<Object>} failures Array of failures containing paths, - * errors, and manifests. - * @private - */ - add_: function(failures) { - // If a failure is already being displayed, unhide the last item. - if (this.failures_.length > 0) - this.failures_[this.failures_.length - 1].listElement.hidden = false; - failures.forEach(function(failure) { - var listItem = /** @type {HTMLLIElement} */( - document.createElement('li')); - listItem.textContent = failure.path; - this.additional_.list.appendChild(listItem); - this.failures_.push(new Failure(failure.path, - failure.error, - failure.manifest, - listItem)); - }.bind(this)); - // Hide the last item because the UI is displaying its information. - this.failures_[this.failures_.length - 1].listElement.hidden = true; - this.show_(); - }, - - /** - * Remove a failure from |failures_| array. If this was the last failure, - * hide the error UI. If this was the last additional failure, hide - * the additional failures UI. - * @private - */ - remove_: function() { - this.additional_.list.removeChild( - this.failures_[this.failures_.length - 1].listElement); - this.failures_.pop(); - if (this.failures_.length > 0) { - this.failures_[this.failures_.length - 1].listElement.hidden = true; - this.show_(); - } else { - this.hidden = true; - } - }, - - /** - * Display the load error to the user. The last failure gets its manifest - * and error displayed, while additional failures have their path names - * displayed in the additional failures element. - * @private - */ - show_: function() { - assert(this.failures_.length >= 1); - var failure = this.failures_[this.failures_.length - 1]; - this.path_.textContent = failure.path; - this.reason_.textContent = failure.error; - - failure.manifest.message = failure.error; - this.manifest_.populate( - failure.manifest, - loadTimeData.getString('extensionLoadCouldNotLoadManifest')); - this.hidden = false; - this.manifest_.scrollToError(); - - this.additional_.hidden = this.failures_.length == 1; - } - }; - - /** - * The ExtensionLoader is the class in charge of loading unpacked extensions. - * @constructor - */ - function ExtensionLoader() { - /** - * The ExtensionLoadError to show any errors from loading an unpacked - * extension. - * @type {ExtensionLoadError} - * @private - */ - this.loadError_ = new ExtensionLoadError( - /** @type {HTMLDivElement} */($('extension-load-error'))); - } - - cr.addSingletonGetter(ExtensionLoader); - - ExtensionLoader.prototype = { - /** - * Whether or not we are currently loading an unpacked extension. - * @private {boolean} - */ - isLoading_: false, - - /** - * Begin the sequence of loading an unpacked extension. If an error is - * encountered, this object will get notified via notifyFailed(). - */ - loadUnpacked: function() { - if (this.isLoading_) // Only one running load at a time. - return; - this.isLoading_ = true; - chrome.developerPrivate.loadUnpacked({failQuietly: true}, function() { - // Check lastError to avoid the log, but don't do anything with it - - // error-handling is done on the C++ side. - var lastError = chrome.runtime.lastError; - this.isLoading_ = false; - }.bind(this)); - }, - - /** - * Notify the ExtensionLoader that loading an unpacked extension failed. - * Add the failure to failures_ and show the ExtensionLoadError. - * @param {Array<Object>} failures Array of failures containing paths, - * errors, and manifests. - */ - notifyFailed: function(failures) { - this.loadError_.add_(failures); - }, - }; - - /** - * A static forwarding function for ExtensionLoader.notifyFailed. - * @param {Array<Object>} failures Array of failures containing paths, - * errors, and manifests. - * @see ExtensionLoader.notifyFailed - */ - ExtensionLoader.notifyLoadFailed = function(failures) { - ExtensionLoader.getInstance().notifyFailed(failures); - }; - - return { - ExtensionLoader: ExtensionLoader - }; -});
diff --git a/chrome/browser/resources/extensions/extension_options_overlay.css b/chrome/browser/resources/extensions/extension_options_overlay.css deleted file mode 100644 index 5492611..0000000 --- a/chrome/browser/resources/extensions/extension_options_overlay.css +++ /dev/null
@@ -1,28 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#extension-options-overlay { - overflow: hidden; -} - -#extension-options-overlay-header { - align-items: center; - border-bottom: solid lightgray 1px; - display: flex; - position: relative; -} - -#extension-options-overlay-icon { - padding: 8px; -} - -#extension-options-overlay-icon { - height: 32px; - width: 32px; -} - -#extension-options-overlay-title { - /* Cancel left padding to line up with the icon. */ - padding-left: 0; -}
diff --git a/chrome/browser/resources/extensions/extension_options_overlay.html b/chrome/browser/resources/extensions/extension_options_overlay.html deleted file mode 100644 index e5ee0b9..0000000 --- a/chrome/browser/resources/extensions/extension_options_overlay.html +++ /dev/null
@@ -1,13 +0,0 @@ -<!-- -Copyright 2014 The Chromium Authors. All rights reserved. -Use of this source code is governed by a BSD-style license that can be found -in the LICENSE file. ---> -<div id="extension-options-overlay" class="page"> - <div class="close-button"></div> - <div id="extension-options-overlay-header"> - <img id="extension-options-overlay-icon" aria-hidden="true"> - <h1 id="extension-options-overlay-title"></h1> - </div> - <div id="extension-options-overlay-guest"></div> -</div>
diff --git a/chrome/browser/resources/extensions/extension_options_overlay.js b/chrome/browser/resources/extensions/extension_options_overlay.js deleted file mode 100644 index 73aac3e..0000000 --- a/chrome/browser/resources/extensions/extension_options_overlay.js +++ /dev/null
@@ -1,257 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Returns the width of a scrollbar in logical pixels. -function getScrollbarWidth() { - // Create nested divs with scrollbars. - var outer = document.createElement('div'); - outer.style.width = '100px'; - outer.style.overflow = 'scroll'; - outer.style.visibility = 'hidden'; - document.body.appendChild(outer); - var inner = document.createElement('div'); - inner.style.width = '101px'; - outer.appendChild(inner); - - // The outer div's |clientWidth| and |offsetWidth| differ only by the width of - // the vertical scrollbar. - var scrollbarWidth = outer.offsetWidth - outer.clientWidth; - outer.parentNode.removeChild(outer); - return scrollbarWidth; -} - -cr.define('extensions', function() { - 'use strict'; - - /** - * The ExtensionOptionsOverlay will show an extension's options page using - * an <extensionoptions> element. - * @constructor - */ - function ExtensionOptionsOverlay() {} - - cr.addSingletonGetter(ExtensionOptionsOverlay); - - ExtensionOptionsOverlay.prototype = { - /** - * The function that shows the given element in the overlay. - * @type {?function(HTMLDivElement)} Function that receives the element to - * show in the overlay. - * @private - */ - showOverlay_: null, - - /** - * The id of the extension that this options page display. - * @type {string} - * @private - */ - extensionId_: '', - - /** - * Initialize the page. - * @param {function(HTMLDivElement)} showOverlay The function to show or - * hide the ExtensionOptionsOverlay; this should take a single parameter - * which is either the overlay Div if the overlay should be displayed, - * or null if the overlay should be hidden. - */ - initializePage: function(showOverlay) { - var overlay = $('overlay'); - - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); - - this.showOverlay_ = showOverlay; - }, - - setInitialFocus: function() { - this.getExtensionOptions_().focus(); - }, - - /** - * @return {?Element} - * @private - */ - getExtensionOptions_: function() { - return $('extension-options-overlay-guest').querySelector( - 'extensionoptions'); - }, - - /** - * Handles a click on the close button. - * @param {Event} event The click event. - * @private - */ - handleDismiss_: function(event) { - this.setVisible_(false); - var extensionoptions = this.getExtensionOptions_(); - if (extensionoptions) - $('extension-options-overlay-guest').removeChild(extensionoptions); - - $('extension-options-overlay-icon').removeAttribute('src'); - }, - - /** - * Associate an extension with the overlay and display it. - * @param {string} extensionId The id of the extension whose options page - * should be displayed in the overlay. - * @param {string} extensionName The name of the extension, which is used - * as the header of the overlay. - * @param {string} extensionIcon The URL of the extension's icon. - * @param {function():void} shownCallback A function called when - * showing completes. - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression after adding - * chrome/renderer/resources/extensions/extension_options.js - * to dependencies. - */ - setExtensionAndShow: function(extensionId, - extensionName, - extensionIcon, - shownCallback) { - var overlay = $('extension-options-overlay'); - var overlayHeader = $('extension-options-overlay-header'); - var overlayGuest = $('extension-options-overlay-guest'); - var overlayStyle = window.getComputedStyle(overlay); - - $('extension-options-overlay-title').textContent = extensionName; - $('extension-options-overlay-icon').src = extensionIcon; - - this.setVisible_(true); - - var extensionoptions = new window.ExtensionOptions(); - extensionoptions.extension = extensionId; - this.extensionId_ = extensionId; - - // The <extensionoptions> content's size needs to be restricted to the - // bounds of the overlay window. The overlay gives a minWidth and - // maxHeight, but the maxHeight does not include our header height (title - // and close button), so we need to subtract that to get the maxHeight - // for the extension options. - var maxHeight = parseInt(overlayStyle.maxHeight, 10) - - overlayHeader.offsetHeight; - var minWidth = parseInt(overlayStyle.minWidth, 10); - - extensionoptions.onclose = function() { - cr.dispatchSimpleEvent($('overlay'), 'cancelOverlay'); - }.bind(this); - - // Track the current animation (used to grow/shrink the overlay content), - // if any. Preferred size changes can fire more rapidly than the - // animation speed, and multiple animations running at the same time has - // undesirable effects. - var animation = null; - - /** - * Resize the overlay if the <extensionoptions> changes preferred size. - * @param {{width: number, height: number}} evt - */ - extensionoptions.onpreferredsizechanged = function(evt) { - var oldOverlayWidth = parseInt(overlayStyle.width, 10); - var oldOverlayHeight = parseInt(overlayStyle.height, 10); - var newOverlayWidth = evt.width; - // |evt.height| is just the new overlay guest height, and does not - // include the overlay header height, so it needs to be added. - var newOverlayHeight = evt.height + overlayHeader.offsetHeight; - - // Make room for the vertical scrollbar, if there is one. - if (newOverlayHeight > maxHeight) { - newOverlayWidth += getScrollbarWidth(); - } - - // Enforce |minWidth| and |maxHeight|. - newOverlayWidth = Math.max(newOverlayWidth, minWidth); - newOverlayHeight = Math.min(newOverlayHeight, maxHeight); - - // animationTime is the amount of time in ms that will be used to resize - // the overlay. It is calculated by multiplying the pythagorean distance - // between old and the new size (in px) with a constant speed of - // 0.25 ms/px. - var loading = document.documentElement.classList.contains('loading'); - var animationTime = loading ? 0 : - 0.25 * Math.sqrt(Math.pow(newOverlayWidth - oldOverlayWidth, 2) + - Math.pow(newOverlayHeight - oldOverlayHeight, 2)); - - if (animation) - animation.cancel(); - - // The header height must be added to the (old and new) preferred - // heights to get the full overlay heights. - animation = overlay.animate([ - {width: oldOverlayWidth + 'px', height: oldOverlayHeight + 'px'}, - {width: newOverlayWidth + 'px', height: newOverlayHeight + 'px'} - ], { - duration: animationTime, - delay: 0 - }); - - animation.onfinish = function(e) { - animation = null; - - // The <extensionoptions> element is ready to place back in the - // overlay. Make sure that it's sized to take up the full width/height - // of the overlay. - overlayGuest.style.position = ''; - overlayGuest.style.left = ''; - overlayGuest.style.width = newOverlayWidth + 'px'; - // |newOverlayHeight| includes the header height, so it needs to be - // subtracted to get the new guest height. - overlayGuest.style.height = - (newOverlayHeight - overlayHeader.offsetHeight) + 'px'; - - if (shownCallback) { - shownCallback(); - shownCallback = null; - } - }; - }.bind(this); - - // Move the <extensionoptions> off screen until the overlay is ready. - overlayGuest.style.position = 'fixed'; - overlayGuest.style.left = window.outerWidth + 'px'; - // Begin rendering at the default dimensions. This is also necessary to - // cancel any width/height set on a previous render. - // TODO(kalman): This causes a visual jag where the overlay guest shows - // up briefly. It would be better to render this off-screen first, then - // swap it in place. See crbug.com/408274. - // This may also solve crbug.com/431001 (width is 0 on initial render). - overlayGuest.style.width = ''; - overlayGuest.style.height = ''; - - overlayGuest.appendChild(extensionoptions); - }, - - /** - * Dispatches a 'cancelOverlay' event on the $('overlay') element. - */ - close: function() { - cr.dispatchSimpleEvent($('overlay'), 'cancelOverlay'); - }, - - /** - * Returns extension id that this options page set. - * @return {string} - */ - getExtensionId: function() { - return this.extensionId_; - }, - - /** - * Toggles the visibility of the ExtensionOptionsOverlay. - * @param {boolean} isVisible Whether the overlay should be visible. - * @private - */ - setVisible_: function(isVisible) { - this.showOverlay_(isVisible ? - /** @type {HTMLDivElement} */($('extension-options-overlay')) : - null); - } - }; - - // Export - return { - ExtensionOptionsOverlay: ExtensionOptionsOverlay - }; -});
diff --git a/chrome/browser/resources/extensions/extensions.css b/chrome/browser/resources/extensions/extensions.css deleted file mode 100644 index fd9e4699..0000000 --- a/chrome/browser/resources/extensions/extensions.css +++ /dev/null
@@ -1,443 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -html.loading * { - transition-duration: 0ms !important; -} - -html:not(.focus-outline-visible) -:enabled:focus:-webkit-any(input[type='checkbox'], input[type='radio']) { - /* Cancel border-color for :focus specified in widgets.css. */ - border-color: rgba(0, 0, 0, 0.25); -} - -.no-scroll { - overflow-y: hidden; -} - -#extension-settings.showing-banner { - margin-top: 45px; -} - -/* Developer mode */ - -#dev-controls { - -webkit-margin-end: 0; - height: 0; - overflow: hidden; -} - -#dev-controls.animated { - transition: height 150ms; -} - -.dev-mode #dev-controls { - border-bottom: 1px solid #eee; -} - -#dev-controls > * { - padding: 8px 3px; -} - -#dev-controls .button-container { - -webkit-padding-end: 12px; - -webkit-padding-start: 12px; - display: flex; - flex-wrap: wrap; -} - -#dev-controls button { - white-space: nowrap; -} - -#dev-controls .button-container button:not(:last-of-type) { - -webkit-margin-end: 5px; -} - -#dev-controls-spacer { - flex: 1; -} - -.extension-code { - border: 1px solid #ccc; - display: flex; - font-family: monospace; - overflow: auto; - white-space: pre; -} - -.extension-code > * { - padding: 3px; -} - -.extension-code-line-numbers { - align-self: flex-start; - background-color: rgba(240, 240, 240, 1); - border-right: 1px solid #ccc; - color: rgba(128, 128, 128, 1); - flex-shrink: 0; - text-align: right; -} - -.extension-code-empty { - background-color: #eee; - display: inline-block; - line-height: 100px; /* Vertically centers text and serves as min-height. */ - text-align: center; - width: 100%; -} - -.extension-details > .developer-extras > div, -.extension-details > .permanent-warnings > div { - margin: 5px 0; -} - -.dependent-extensions-message, -.suspicious-install-message { - line-height: 150%; -} - -#page-header { - -webkit-padding-start: 23px; - left: 0; -} - -[dir='rtl'] #page-header { - right: 0; -} - -#page-header > .page-banner > .page-banner-gradient { - -webkit-margin-end: 0; -} - -#header-controls { - /* Reserve enough space to match .location-text + .trash */ - min-width: 130px; - right: 16px; -} - -html[dir='rtl'] #header-controls { - left: 16px; - right: auto; -} - -#page-header > h1::after { - -webkit-margin-end: 0; -} - -#extension-settings #page-header { - /* These values match the .page values. */ - -webkit-margin-end: 24px; - min-width: 576px; -} - -/* Contents */ - -#extension-settings { - max-width: 738px; -} - -#no-extensions-message { - font-weight: bold; -} - -#no-extensions { - margin-top: 3em; -} - -#suggest-gallery { - -webkit-padding-start: 10px; -} - -#footer-section { - background: url(chrome://theme/IDR_WEBSTORE_ICON_32) no-repeat left center; - background-size: 32px 32px; - font-size: 1.25em; - margin: 24px 12px 12px 12px; -} - -html[dir=rtl] #footer-section { - background: url(chrome://theme/IDR_WEBSTORE_ICON_32) no-repeat right center; -} - -#footer-section > a { - -webkit-margin-start: 42px; - line-height: 32px; -} - -.extension-list-item-wrapper { - margin: 12px 0; - padding: 12px; -} - -.extension-list-item { - background-repeat: no-repeat; - background-size: 48px 48px; - display: -webkit-box; - min-height: 48px; -} - -.extension-list-item a { - -webkit-margin-start: 0.5em; - display: inline-block; -} - -html[dir='rtl'] .extension-list-item { - background-position-x: 100%; -} - -.extension-title { - -webkit-padding-end: 20px; - color: rgb(48, 57, 66); - display: inline; - font-size: 14px; - font-weight: 500; - user-select: text; -} - -.inactive-extension .extension-title { - color: inherit; -} - -.extension-version { - -webkit-padding-end: 7px; - font-size: 13px; - font-weight: 400; -} - -.extension-description, -.corrupt-install-message { - -webkit-padding-end: 5px; - font-size: 13px; - margin: 5px 0; - white-space: normal; -} - -.corrupt-install-message { - color: rgb(196, 42, 23); -} - -.action-links { - margin-bottom: 0.5em; -} - -.action-links a { - -webkit-margin-end: 1em; - -webkit-margin-start: 0; -} - -.action-links .errors-link { - align-items: center; - display: inline-flex; - vertical-align: bottom; -} - -.extension-details { - -webkit-box-flex: 1; - -webkit-padding-end: 7px; - -webkit-padding-start: 60px; - padding-top: 6px; -} - -.extension-description, -.extension-version, -.extension-list-item-wrapper.inactive-extension .extension-details, -.location-text, -.blacklist-text, -.enable-checkbox input:disabled + .enable-checkbox-text { - color: rgb(115, 119, 122); -} - -.enable-controls { - /* Matches right: position of dev controls toggle. */ - -webkit-margin-end: 0; - position: relative; -} - -.enable-controls > .controlled-setting-indicator { - width: 23px; -} - -.enable-controls > .controlled-setting-indicator > div { - left: 11px; - right: 11px; -} - -/* We use x[is='action-link'] here so that we get higher specifity than the - * action link rules without resorting to the Dark Side (!IMPORTANT). */ -.terminated-reload-link[is='action-link'], -.corrupted-repair-button[is='action-link'] { - /* Matches width of trash. */ - -webkit-margin-end: 30px; -} - -.checkbox { - display: inline-block; -} - -.enabled-text { - font-weight: bold; -} - -.extension-list-item-wrapper.inactive-extension .enabled-text, -.extension-list-item-wrapper:not(.inactive-extension) .enable-text, -.extension-list-item-wrapper.inactive-extension .optional-controls, -.extension-list-item-wrapper.inactive-extension .butter-bar { - display: none; -} - -.optional-controls .checkbox { - -webkit-margin-end: 12px; -} - -.load-path > span { - word-wrap: break-word; -} - -.terminated-reload-link, -.corrupted-repair-button { - display: inline-block; - padding-top: 7px; -} - -.install-warnings a { - -webkit-margin-start: 0; -} - -.butter-bar, -.install-warnings, -.extension-warnings { - border-radius: 3px; - line-height: 150%; - margin: 8px 0; - padding: 8px 12px; -} - -.butter-bar { - background: rgb(255, 242, 153); -} - -.install-warnings, -.extension-warnings { - background: pink; -} - -.install-warnings ul, -.extension-warnings ul { - margin: 0; -} - -.error-collection-control { - -webkit-margin-start: 5px; -} - -#extension-settings:not(.dev-mode) .developer-extras, -#extension-settings:not(.dev-mode) .error-collection-control { - display: none; -} - -#font-measuring-div { - /* Remove from the flow and hide. */ - position: absolute; - visibility: hidden; -} - -.extension-commands-config { - float: right; -} - -html[dir=rtl] .extension-commands-config { - float: left; -} - -/* Overlays */ - -#overlay { - z-index: 5; -} - -#overlay .page:not(.showing) { - display: none; -} - -#drop-target-overlay { - color: rgb(48, 57, 66); - font-size: 18px; - text-align: center; -} - -#drop-target-overlay div { - margin: 1em; -} - -.location-text, -.blacklist-text { - display: block; - width: 100px; -} - -.enable-checkbox { - /* Reserve enough space to match .location-text */ - min-width: 100px; -} - -/* Trash */ - -#extension-settings .trash { - height: 22px; - opacity: 0.8; - position: relative; - right: -8px; - top: 6px; - transition: opacity 200ms; - vertical-align: top; -} - -html[dir='rtl'] #extension-settings .trash { - left: -8px; - right: auto; -} - -.extension-list-item:not(:hover) .trash:not(:focus) { - opacity: 0; -} - -.extension-list-item-wrapper.may-not-remove .trash { - visibility: hidden; -} - -/* In case the extension is policy controlled the trash icon must be hidden by - * setting display:none rather than only setting visibility:hidden to completely - * remove it from the layout and make space for the controlled indicator. - * TODO(cschuet): rather than hide always replace it with something meaningful. - */ -.extension-list-item-wrapper.controlled .trash { - display: none; -} - -/* Supervised users */ - -.page:not(.profile-is-supervised) .profile-is-supervised-banner, -.profile-is-supervised .more-extensions-link { - display: none; -} - -.profile-is-supervised-banner .page-banner-text { - background-image: url(../../../../ui/webui/resources/images/warning.svg); -} - -/* Sideload Wipeout */ - -.sideload-wipeout-learn-more { - text-decoration: none; -} - -.sideload-wipeout-banner .page-banner-text { - -webkit-padding-start: 8px; - background-image: none; -} - -.extension-highlight { - background-color: rgba(0, 0, 0, .05); -}
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html deleted file mode 100644 index 40d6ce3..0000000 --- a/chrome/browser/resources/extensions/extensions.html +++ /dev/null
@@ -1,283 +0,0 @@ -<!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> -<head> -<meta charset="utf-8"> -<title>$i18n{extensionSettings}</title> - -<link rel="stylesheet" href="extensions.css"> -<link rel="stylesheet" href="extension_commands_overlay.css"> -<link rel="stylesheet" href="extension_error.css"> -<link rel="stylesheet" href="extension_error_overlay.css"> -<link rel="stylesheet" href="extension_load_error.css"> -<link rel="stylesheet" href="extension_options_overlay.css"> -<link rel="stylesheet" href="pack_extension_overlay.css"> -<link rel="stylesheet" href="chrome://resources/css/alert_overlay.css"> -<link rel="stylesheet" href="chrome://resources/css/bubble.css"> -<link rel="stylesheet" href="chrome://resources/css/bubble_button.css"> -<link rel="stylesheet" href="chrome://resources/css/controlled_indicator.css"> -<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> -<link rel="stylesheet" href="chrome://resources/css/overlay.css"> -<link rel="stylesheet" href="chrome://resources/css/spinner.css"> -<link rel="stylesheet" href="chrome://resources/css/trash.css"> -<link rel="stylesheet" href="../uber_shared.css"> - -<script src="chrome://resources/js/action_link.js"></script> -<script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/event_tracker.js"></script> -<script src="chrome://resources/js/load_time_data.js"></script> -<script src="chrome://resources/js/util.js"></script> -<script src="chrome://resources/js/cr/ui.js"></script> -<script src="chrome://resources/js/cr/ui/alert_overlay.js"></script> -<script src="chrome://resources/js/cr/ui/bubble.js"></script> -<script src="chrome://resources/js/cr/ui/bubble_button.js"></script> -<script src="chrome://resources/js/cr/ui/controlled_indicator.js"></script> -<script src="chrome://resources/js/cr/ui/drag_wrapper.js"></script> -<script src="chrome://resources/js/cr/ui/focus_manager.js"></script> -<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script> -<script src="chrome://resources/js/cr/ui/node_utils.js"></script> -<script src="chrome://resources/js/cr/ui/overlay.js"></script> - -<if expr="chromeos"> -<link rel="stylesheet" href="chrome://resources/css/list.css"> -<link rel="stylesheet" href="chromeos/kiosk_apps.css"> -<script src="chrome://resources/js/cr/event_target.js"></script> -<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script> -<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"> -</script> -<script src="chrome://resources/js/cr/ui/list_item.js"></script> -<script src="chrome://resources/js/cr/ui/list.js"></script> -<script src="chrome://resources/js/promise_resolver.js"></script> -<script src="chrome://resources/js/webui_listener_tracker.js"></script> -</if> - -<script src="chrome://extensions/extensions.js"></script> -</head> - -<body> - -<div id="overlay" class="overlay" hidden> - <include src="extension_commands_overlay.html"> - <include src="extension_error_overlay.html"> - <include src="extension_options_overlay.html"> - <include src="pack_extension_overlay.html"> - <include src="../../../../ui/webui/resources/html/alert_overlay.html"> -<if expr="chromeos"> - <include src="chromeos/kiosk_apps.html"> - <include src="chromeos/kiosk_app_disable_bailout_confirm.html"> -</if> - <div id="drop-target-overlay" class="page"> - <div>$i18n{extensionSettingsInstallDropTarget}</div> - </div> -</div> - -<div class="page" id="extension-settings"> - <header id="page-header"> - <h1>$i18n{extensionSettings}</h1> - <div id="header-controls" class="header-extras"> - <div id="dev-toggle" class="checkbox"> - <label> - <input id="toggle-dev-on" type="checkbox"> - <span>$i18n{extensionSettingsDeveloperMode}</span> - <span id="dev-toggle-disabled-by-policy-indicator" - class="controlled-setting-indicator"></span> - </label> - </div> - </div> - <div class="page-banner profile-is-supervised-banner"> - <div class="page-banner-gradient"> - <span class="page-banner-text"> - $i18n{extensionSettingsSupervisedUser} - </span> - </div> - </div> - </header> - <div id="loading-spinner"> - <div class="inline-spinner"></div> - <span>$i18n{loading}</span> - </div> - <div id="dev-controls" hidden> - <div class="button-container"> - <button id="load-unpacked"> - $i18n{extensionSettingsLoadUnpackedButton} - </button> - <button id="pack-extension"> - $i18n{extensionSettingsPackButton} - </button> -<if expr="chromeos"> - <button id="add-kiosk-app" hidden>$i18n{addKioskAppButton}</button> -</if> - <div id="dev-controls-spacer"></div> - <button id="update-extensions-now"> - $i18n{extensionSettingsUpdateButton} - </button> - </div> - </div> - <include src="extension_load_error.html"> - <div id="extension-list-wrapper" hidden> - <div id="footer-section"> - <a target="_blank" class="more-extensions-link" - i18n-values="href:extensionSettingsGetMoreExtensionsUrl"> - $i18n{extensionSettingsGetMoreExtensions} - </a> - <a is="action-link" class="extension-commands-config" hidden> - $i18n{extensionSettingsCommandsLink} - </a> - </div> - </div> - <div id="no-extensions" hidden> - <span id="no-extensions-message">$i18n{extensionSettingsNoExtensions}</span> - <span id="suggest-gallery" class="more-extensions-link" - i18n-values=".innerHTML:extensionSettingsSuggestGallery"> - </span> - </div> -</div> - -<span id="font-measuring-div"></span> - -<div id="templates" hidden> - - <div class="extension-list-item-wrapper"> - <div class="extension-list-item"> - <div class="extension-details"> - <div> - <h2 class="extension-title"></h2> - <span class="extension-version"></span> - </div> - <p class="corrupt-install-message" - hidden>$i18n{extensionSettingsCorruptInstall}</p> - <p class="extension-description"></p> - <div class="action-links"> - <a is="action-link" class="permissions-link"> - $i18n{extensionSettingsPermissions} - </a> - <a is="action-link" class="options-button" hidden> - $i18n{extensionSettingsOptions} - </a> - <a class="options-link" hidden>$i18n{extensionSettingsOptions}</a> - <a class="site-link" target="_parent" hidden></a> - <a is="action-link" class="launch-link" hidden> - $i18n{extensionSettingsLaunch} - </a> - <a is="action-link" role="button" class="reload-link" hidden> - $i18n{extensionSettingsReloadUnpacked} - </a> - <a is="action-link" role="button" class="errors-link"> - <img class="extension-error-icon"> - <span>$i18n{extensionErrorHeading}</span> - </a> - </div> - <div class="permanent-warnings"> - <div class="extension-warnings" hidden> - <span>$i18n{extensionSettingsWarningsTitle}</span> - <ul></ul> - </div> - <div class="suspicious-install-message" hidden> - <span>$i18n{extensionSettingsSuspiciousInstall}</span> - <a target="_blank" class="learn-more-link" href="#" - i18n-values="href:extensionSettingsSuspiciousInstallHelpUrl"> - $i18n{extensionSettingsLearnMore} - </a> - </div> - </div> - <div class="dependent-extensions-message" hidden> - <span>$i18n{extensionSettingsDependentExtensions}</span> - <ul></ul> - </div> - <div class="developer-extras"> - <div> - <span>$i18n{extensionSettingsExtensionId}</span> - <span class="extension-id"></span> - </div> - <div class="load-path" hidden> - <span>$i18n{extensionSettingsExtensionPath}</span> - <a is="action-link"></a> - </div> - <div class="managed-message" hidden> - $i18n{extensionSettingsPolicyControlled} - </div> - <div class="update-required-message" hidden> - $i18n{extensionSettingsUpdateRequiredBePolicy} - </div> - <div class="active-views" hidden> - <span>$i18n{extensionSettingsInspectViews}</span> - <a is="action-link"></a> - </div> - <div class="install-warnings" hidden> - <span>$i18n{extensionSettingsInstallWarnings}</span> - <ul></ul> - </div> - </div> - <div class="optional-controls"> - <div class="checkbox"> - <label class="incognito-control"> - <input type="checkbox"> - <span>$i18n{extensionSettingsEnableIncognito}</span> - </label> - </div> - <div class="checkbox error-collection-control" hidden> - <label> - <input type="checkbox"> - <span>$i18n{extensionSettingsEnableErrorCollection}</span> - </label> - </div> - <div class="checkbox all-urls-control" hidden> - <label> - <input type="checkbox"> - <span>$i18n{extensionSettingsAllowOnAllUrls}</span> - </label> - </div> - <div class="checkbox file-access-control" hidden> - <label> - <input type="checkbox"> - <span>$i18n{extensionSettingsAllowFileAccess}</span> - </label> - </div> - </div> - <div class="butter-bar" - i18n-values=".innerHTML:extensionSettingsIncognitoWarning" hidden> - </div> - </div> - <div class="enable-controls"> - <a is="action-link" role="button" class="terminated-reload-link" hidden> - $i18n{extensionSettingsReloadTerminated} - </a> - <a is="action-link" role="button" class="corrupted-repair-button" - hidden> - $i18n{extensionSettingsRepairCorrupted} - </a> - <div class="checkbox enable-checkbox" hidden><label> - <input type="checkbox"> - <span class="enable-checkbox-text"> - <span class="enabled-text">$i18n{extensionSettingsEnabled}</span> - <span class="enable-text">$i18n{extensionSettingsEnable}</span> - </span> - </label> - <span class="location-text"></span> - <span class="blacklist-text"></span> - </div> - </div> - </div> - </div> - <li class="dependent-list-item"> - <span class="dep-extension-title"></span> - <ul> - <li> - <span>$i18n{extensionSettingsExtensionId}</span> - <span class="dep-extension-id"></span> - </li> - </ul> - </li> - - - <include src="../../../../ui/webui/resources/html/trash.html"> - <include src="extension_error.html"> - -</div> - -<script src="chrome://extensions/strings.js"></script> -<script src="chrome://resources/js/i18n_template.js"></script> - -</body> -</html>
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js deleted file mode 100644 index b3be062..0000000 --- a/chrome/browser/resources/extensions/extensions.js +++ /dev/null
@@ -1,461 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// <include src="../../../../ui/webui/resources/js/cr/ui/focus_row.js"> -// <include src="../../../../ui/webui/resources/js/cr/ui/focus_grid.js"> -// <include src="../md_extensions/drag_and_drop_handler.js"> -// <include src="extension_code.js"> -// <include src="extension_commands_overlay.js"> -// <include src="extension_error_overlay.js"> -// <include src="extension_focus_manager.js"> -// <include src="focus_row.js"> -// <include src="extension_list.js"> -// <include src="pack_extension_overlay.js"> -// <include src="extension_loader.js"> -// <include src="extension_options_overlay.js"> - -// <if expr="chromeos"> -// <include src="chromeos/kiosk_apps.js"> -// </if> - -cr.define('extensions', function() { - var ExtensionList = extensions.ExtensionList; - - /** - * ExtensionSettings class - * @class - * @constructor - * @implements {extensions.ExtensionListDelegate} - */ - function ExtensionSettings() {} - - cr.addSingletonGetter(ExtensionSettings); - - ExtensionSettings.prototype = { - /** - * The drag-drop wrapper for installing external Extensions, if available. - * null if external Extension installation is not available. - * @type {cr.ui.DragWrapper} - * @private - */ - dragWrapper_: null, - - /** - * True if drag-drop is both available and currently enabled - it can be - * temporarily disabled while overlays are showing. - * @type {boolean} - * @private - */ - dragEnabled_: false, - - /** - * True if the page has finished the initial load. - * @private {boolean} - */ - hasLoaded_: false, - - /** - * Perform initial setup. - */ - initialize: function() { - this.setLoading_(true); - cr.ui.FocusOutlineManager.forDocument(document); - measureCheckboxStrings(); - - var extensionList = new ExtensionList(this); - extensionList.id = 'extension-settings-list'; - var wrapper = $('extension-list-wrapper'); - wrapper.insertBefore(extensionList, wrapper.firstChild); - - // Get the initial profile state, and register to be notified of any - // future changes. - chrome.developerPrivate.getProfileConfiguration( - this.update_.bind(this)); - chrome.developerPrivate.onProfileStateChanged.addListener( - this.update_.bind(this)); - - var extensionLoader = extensions.ExtensionLoader.getInstance(); - - $('toggle-dev-on').addEventListener('change', function(e) { - this.updateDevControlsVisibility_(true); - chrome.developerPrivate.updateProfileConfiguration( - {inDeveloperMode: e.target.checked}); - var suffix = $('toggle-dev-on').checked ? 'Enabled' : 'Disabled'; - chrome.send('metricsHandler:recordAction', - ['Options_ToggleDeveloperMode_' + suffix]); - }.bind(this)); - - window.addEventListener('resize', function() { - this.updateDevControlsVisibility_(false); - }.bind(this)); - - // Set up the three dev mode buttons (load unpacked, pack and update). - $('load-unpacked').addEventListener('click', function(e) { - chrome.send('metricsHandler:recordAction', - ['Options_LoadUnpackedExtension']); - extensionLoader.loadUnpacked(); - }); - $('pack-extension').addEventListener('click', - this.handlePackExtension_.bind(this)); - $('update-extensions-now').addEventListener('click', - this.handleUpdateExtensionNow_.bind(this)); - - var dragTarget = document.documentElement; - /** @private {extensions.DragAndDropHandler} */ - this.dragWrapperHandler_ = - new extensions.DragAndDropHandler(true, false, dragTarget); - dragTarget.addEventListener('extension-drag-started', function() { - ExtensionSettings.showOverlay($('drop-target-overlay')); - }); - dragTarget.addEventListener('extension-drag-ended', function() { - var overlay = ExtensionSettings.getCurrentOverlay(); - if (overlay && overlay.id === 'drop-target-overlay') - ExtensionSettings.showOverlay(null); - }); - this.dragWrapper_ = - new cr.ui.DragWrapper(dragTarget, this.dragWrapperHandler_); - - extensions.PackExtensionOverlay.getInstance().initializePage(); - - // Hook up the configure commands link to the overlay. - var link = document.querySelector('.extension-commands-config'); - link.addEventListener('click', - this.handleExtensionCommandsConfig_.bind(this)); - - // Initialize the Commands overlay. - extensions.ExtensionCommandsOverlay.getInstance().initializePage(); - - extensions.ExtensionErrorOverlay.getInstance().initializePage( - extensions.ExtensionSettings.showOverlay); - - extensions.ExtensionOptionsOverlay.getInstance().initializePage( - extensions.ExtensionSettings.showOverlay); - - // Add user action logging for bottom links. - var moreExtensionLink = - document.getElementsByClassName('more-extensions-link'); - for (var i = 0; i < moreExtensionLink.length; i++) { - moreExtensionLink[i].addEventListener('click', function(e) { - chrome.send('metricsHandler:recordAction', - ['Options_GetMoreExtensions']); - }); - } - - // Initialize the kiosk overlay. - if (cr.isChromeOS) { - var kioskOverlay = extensions.KioskAppsOverlay.getInstance(); - kioskOverlay.initialize(); - - $('add-kiosk-app').addEventListener('click', function() { - ExtensionSettings.showOverlay($('kiosk-apps-page')); - kioskOverlay.didShowPage(); - }); - - extensions.KioskDisableBailoutConfirm.getInstance().initialize(); - } - - cr.ui.overlay.setupOverlay($('drop-target-overlay')); - cr.ui.overlay.globalInitialization(); - - extensions.ExtensionFocusManager.getInstance().initialize(); - - var path = document.location.pathname; - if (path.length > 1) { - // Skip starting slash and remove trailing slash (if any). - var overlayName = path.slice(1).replace(/\/$/, ''); - if (overlayName == 'configureCommands') - this.showExtensionCommandsConfigUi_(); - } - }, - - /** - * [Re]-Populates the page with data representing the current state of - * installed extensions. - * @param {chrome.developerPrivate.ProfileInfo} profileInfo - * @private - */ - update_: function(profileInfo) { - // We only set the page to be loading if we haven't already finished an - // initial load, because otherwise the updates are all incremental and - // don't need to display the interstitial spinner. - if (!this.hasLoaded_) - this.setLoading_(true); - - /** @const */ - var supervised = profileInfo.isSupervised; - var developerModeControlledByPolicy = - profileInfo.isDeveloperModeControlledByPolicy; - - var pageDiv = $('extension-settings'); - pageDiv.classList.toggle('profile-is-supervised', supervised); - pageDiv.classList.toggle('showing-banner', supervised); - - var devControlsCheckbox = $('toggle-dev-on'); - devControlsCheckbox.checked = profileInfo.inDeveloperMode; - devControlsCheckbox.disabled = - supervised || developerModeControlledByPolicy; - - // This is necessary e.g. if developer mode is now disabled by policy - // but extension developer tools were visible. - this.updateDevControlsVisibility_(false); - this.updateDevToggleControlledIndicator_(developerModeControlledByPolicy); - - $('load-unpacked').disabled = !profileInfo.canLoadUnpacked; - var extensionList = /** @type {extensions.ExtensionList} */ ( - $('extension-settings-list')); - extensionList.updateExtensionsData( - profileInfo.isIncognitoAvailable, - profileInfo.appInfoDialogEnabled).then(function() { - if (!this.hasLoaded_) { - this.hasLoaded_ = true; - this.setLoading_(false); - } - this.onExtensionCountChanged(); - }.bind(this)); - }, - - /** - * Shows or hides the 'controlled by policy' indicator on the dev-toggle - * checkbox. - * @param {boolean} devModeControlledByPolicy true if the indicator - * should be showing. - * @private - */ - updateDevToggleControlledIndicator_: function(devModeControlledByPolicy) { - var controlledIndicator = document.querySelector( - '#dev-toggle .controlled-setting-indicator'); - - if (!(controlledIndicator instanceof cr.ui.ControlledIndicator)) - cr.ui.ControlledIndicator.decorate(controlledIndicator); - - // We control the visibility of the ControlledIndicator by setting or - // removing the 'controlled-by' attribute (see controlled_indicator.css). - var isVisible = controlledIndicator.getAttribute('controlled-by'); - if (devModeControlledByPolicy && !isVisible) { - var controlledBy = 'policy'; - controlledIndicator.setAttribute( - 'controlled-by', controlledBy); - controlledIndicator.setAttribute( - 'text' + controlledBy, - loadTimeData.getString('extensionControlledSettingPolicy')); - } else if (!devModeControlledByPolicy && isVisible) { - // This hides the element - see above. - controlledIndicator.removeAttribute('controlled-by'); - } - }, - - /** - * Shows the loading spinner and hides elements that shouldn't be visible - * while loading. - * @param {boolean} isLoading - * @private - */ - setLoading_: function(isLoading) { - document.documentElement.classList.toggle('loading', isLoading); - $('loading-spinner').hidden = !isLoading; - $('dev-controls').hidden = isLoading; - this.updateDevControlsVisibility_(false); - - // The extension list is already hidden/shown elsewhere and shouldn't be - // updated here because it can be hidden if there are no extensions. - }, - - /** - * Handles the Pack Extension button. - * @param {Event} e Change event. - * @private - */ - handlePackExtension_: function(e) { - ExtensionSettings.showOverlay($('pack-extension-overlay')); - chrome.send('metricsHandler:recordAction', ['Options_PackExtension']); - }, - - /** - * Shows the Extension Commands configuration UI. - * @private - */ - showExtensionCommandsConfigUi_: function() { - ExtensionSettings.showOverlay($('extension-commands-overlay')); - chrome.send('metricsHandler:recordAction', - ['Options_ExtensionCommands']); - }, - - /** - * Handles the Configure (Extension) Commands link. - * @param {Event} e Change event. - * @private - */ - handleExtensionCommandsConfig_: function(e) { - this.showExtensionCommandsConfigUi_(); - }, - - /** - * Handles the Update Extension Now button. - * @param {Event} e Change event. - * @private - */ - handleUpdateExtensionNow_: function(e) { - chrome.developerPrivate.autoUpdate(); - chrome.send('metricsHandler:recordAction', - ['Options_UpdateExtensions']); - }, - - /** - * Updates the visibility of the developer controls based on whether the - * [x] Developer mode checkbox is checked. - * @param {boolean} animated Whether to animate any updates. - * @private - */ - updateDevControlsVisibility_: function(animated) { - var showDevControls = $('toggle-dev-on').checked; - $('extension-settings').classList.toggle('dev-mode', showDevControls); - - var devControls = $('dev-controls'); - devControls.classList.toggle('animated', animated); - - var buttons = devControls.querySelector('.button-container'); - Array.prototype.forEach.call(buttons.querySelectorAll('a, button'), - function(control) { - control.tabIndex = showDevControls ? 0 : -1; - }); - buttons.setAttribute('aria-hidden', !showDevControls); - - window.requestAnimationFrame(function() { - devControls.style.height = !showDevControls ? '' : - buttons.offsetHeight + 'px'; - - document.dispatchEvent(new Event('devControlsVisibilityUpdated')); - }.bind(this)); - }, - - /** @override */ - onExtensionCountChanged: function() { - /** @const */ - var hasExtensions = - /** @type {extensions.ExtensionList} */ ($('extension-settings-list')) - .getNumExtensions() != 0; - $('no-extensions').hidden = hasExtensions; - $('extension-list-wrapper').hidden = !hasExtensions; - }, - }; - - /** - * Returns the current overlay or null if one does not exist. - * @return {Element} The overlay element. - */ - ExtensionSettings.getCurrentOverlay = function() { - return document.querySelector('#overlay .page.showing'); - }; - - /** - * Sets the given overlay to show. If the overlay is already showing, this is - * a no-op; otherwise, hides any currently-showing overlay. - * @param {HTMLElement} node The overlay page to show. If null, all overlays - * are hidden. - */ - ExtensionSettings.showOverlay = function(node) { - var pageDiv = $('extension-settings'); - pageDiv.style.width = node ? window.getComputedStyle(pageDiv).width : ''; - document.body.classList.toggle('no-scroll', !!node); - - var currentlyShowingOverlay = ExtensionSettings.getCurrentOverlay(); - if (currentlyShowingOverlay) { - if (currentlyShowingOverlay == node) // Already displayed. - return; - currentlyShowingOverlay.classList.remove('showing'); - } - - if (node) { - var lastFocused; - - var focusOutlineManager = cr.ui.FocusOutlineManager.forDocument(document); - if (focusOutlineManager.visible) - lastFocused = document.activeElement; - - $('overlay').addEventListener('cancelOverlay', function f() { - if (lastFocused && focusOutlineManager.visible) - lastFocused.focus(); - - $('overlay').removeEventListener('cancelOverlay', f); - window.history.replaceState({}, '', '/'); - }); - node.classList.add('showing'); - } - - var pages = document.querySelectorAll('.page'); - for (var i = 0; i < pages.length; i++) { - var hidden = (node != pages[i]) ? 'true' : 'false'; - pages[i].setAttribute('aria-hidden', hidden); - } - - $('overlay').hidden = !node; - - if (node) - ExtensionSettings.focusOverlay(); - - // If drag-drop for external Extension installation is available, enable - // drag-drop when there is any overlay showing other than the usual overlay - // shown when drag-drop is started. - var settings = ExtensionSettings.getInstance(); - if (settings.dragWrapper_) { - assert(settings.dragWrapperHandler_).dragEnabled = - !node || node == $('drop-target-overlay'); - } - }; - - ExtensionSettings.focusOverlay = function() { - var currentlyShowingOverlay = ExtensionSettings.getCurrentOverlay(); - assert(currentlyShowingOverlay); - - if (cr.ui.FocusOutlineManager.forDocument(document).visible) - cr.ui.setInitialFocus(currentlyShowingOverlay); - - if (!currentlyShowingOverlay.contains(document.activeElement)) { - // Make sure focus isn't stuck behind the overlay. - document.activeElement.blur(); - } - }; - - /** - * Utility function to find the width of various UI strings and synchronize - * the width of relevant spans. This is crucial for making sure the - * Enable/Enabled checkboxes align, as well as the Developer Mode checkbox. - */ - function measureCheckboxStrings() { - var trashWidth = 30; - var measuringDiv = $('font-measuring-div'); - measuringDiv.textContent = - loadTimeData.getString('extensionSettingsEnabled'); - measuringDiv.className = 'enabled-text'; - var pxWidth = measuringDiv.clientWidth + trashWidth; - measuringDiv.textContent = - loadTimeData.getString('extensionSettingsEnable'); - measuringDiv.className = 'enable-text'; - pxWidth = Math.max(measuringDiv.clientWidth + trashWidth, pxWidth); - measuringDiv.textContent = - loadTimeData.getString('extensionSettingsDeveloperMode'); - measuringDiv.className = ''; - pxWidth = Math.max(measuringDiv.clientWidth, pxWidth); - - var style = document.createElement('style'); - style.type = 'text/css'; - style.textContent = - '.enable-checkbox-text {' + - ' min-width: ' + (pxWidth - trashWidth) + 'px;' + - '}' + - '#dev-toggle span {' + - ' min-width: ' + pxWidth + 'px;' + - '}'; - document.querySelector('head').appendChild(style); - } - - // Export - return { - ExtensionSettings: ExtensionSettings - }; -}); - -window.addEventListener('load', function(e) { - extensions.ExtensionSettings.getInstance().initialize(); -});
diff --git a/chrome/browser/resources/extensions/focus_row.js b/chrome/browser/resources/extensions/focus_row.js deleted file mode 100644 index 6022f39..0000000 --- a/chrome/browser/resources/extensions/focus_row.js +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - /** - * @param {!Element} root - * @param {?Element} boundary - * @constructor - * @extends {cr.ui.FocusRow} - */ - function FocusRow(root, boundary) { - cr.ui.FocusRow.call(this, root, boundary); - } - - FocusRow.prototype = { - __proto__: cr.ui.FocusRow.prototype, - - /** @override */ - makeActive: function(active) { - cr.ui.FocusRow.prototype.makeActive.call(this, active); - - // Only highlight if the row has focus. - this.root.classList.toggle('extension-highlight', - active && this.root.contains(document.activeElement)); - }, - }; - - return {FocusRow: FocusRow}; -});
diff --git a/chrome/browser/resources/extensions/pack_extension_overlay.css b/chrome/browser/resources/extensions/pack_extension_overlay.css deleted file mode 100644 index 74a4b19d..0000000 --- a/chrome/browser/resources/extensions/pack_extension_overlay.css +++ /dev/null
@@ -1,23 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.pack-extension-heading { - padding-bottom: 5px; - width: 520px; -} - -.pack-extension-text-boxes { - text-align: right; -} - -.pack-extension-text-area { - width: 260px; -} - -<if expr="toolkit_views"> -/* TODO(estade): apply this everywhere. */ -.button-strip { - -webkit-box-direction: reverse; -} -</if>
diff --git a/chrome/browser/resources/extensions/pack_extension_overlay.html b/chrome/browser/resources/extensions/pack_extension_overlay.html deleted file mode 100644 index 65572b5..0000000 --- a/chrome/browser/resources/extensions/pack_extension_overlay.html +++ /dev/null
@@ -1,33 +0,0 @@ -<div id="pack-extension-overlay" class="page"> - <div class="close-button"></div> - <h1>$i18n{packExtensionOverlay}</h1> - <div id="cbd-content-area" class="content-area"> - <div class="pack-extension-heading">$i18n{packExtensionHeading}</div> - <div class="pack-extension-text-boxes"> - <label for="extension-root-dir">$i18n{packExtensionRootDir}</label> - <input class="pack-extension-text-area" id="extension-root-dir" - type="text"> - <button id="browse-extension-dir"> - $i18n{packExtensionBrowseButton} - </button> - </div> - <div class="pack-extension-text-boxes"> - <label for="extension-private-key">$i18n{packExtensionPrivateKey}</label> - <input class="pack-extension-text-area" id="extension-private-key" - type="text"> - <button id="browse-private-key"> - $i18n{packExtensionBrowseButton} - </button> - </div> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="pack-extension-dismiss">$i18n{cancel}</button> - <button id="pack-extension-commit"> - $i18n{packExtensionCommit} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/extensions/pack_extension_overlay.js b/chrome/browser/resources/extensions/pack_extension_overlay.js deleted file mode 100644 index 63b20a4d..0000000 --- a/chrome/browser/resources/extensions/pack_extension_overlay.js +++ /dev/null
@@ -1,169 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('extensions', function() { - /** - * PackExtensionOverlay class - * Encapsulated handling of the 'Pack Extension' overlay page. - * @constructor - */ - function PackExtensionOverlay() { - } - - cr.addSingletonGetter(PackExtensionOverlay); - - PackExtensionOverlay.prototype = { - /** - * Initialize the page. - */ - initializePage: function() { - var overlay = $('overlay'); - cr.ui.overlay.setupOverlay(overlay); - cr.ui.overlay.globalInitialization(); - overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); - - $('pack-extension-dismiss').addEventListener('click', function() { - cr.dispatchSimpleEvent(overlay, 'cancelOverlay'); - }); - $('pack-extension-commit').addEventListener('click', - this.handleCommit_.bind(this)); - $('browse-extension-dir').addEventListener('click', - this.handleBrowseExtensionDir_.bind(this)); - $('browse-private-key').addEventListener('click', - this.handleBrowsePrivateKey_.bind(this)); - }, - - /** - * Handles a click on the dismiss button. - * @param {Event} e The click event. - */ - handleDismiss_: function(e) { - extensions.ExtensionSettings.showOverlay(null); - }, - - /** - * Handles a click on the pack button. - * @param {Event} e The click event. - */ - handleCommit_: function(e) { - var extensionPath = $('extension-root-dir').value; - var privateKeyPath = $('extension-private-key').value; - chrome.developerPrivate.packDirectory( - extensionPath, privateKeyPath, 0, this.onPackResponse_.bind(this)); - }, - - /** - * Utility function which asks the C++ to show a platform-specific file - * select dialog, and set the value property of |node| to the selected path. - * @param {chrome.developerPrivate.SelectType} selectType - * The type of selection to use. - * @param {chrome.developerPrivate.FileType} fileType - * The type of file to select. - * @param {HTMLInputElement} node The node to set the value of. - * @private - */ - showFileDialog_: function(selectType, fileType, node) { - chrome.developerPrivate.choosePath(selectType, fileType, function(path) { - // Last error is set if the user canceled the dialog. - if (!chrome.runtime.lastError && path) - node.value = path; - }); - }, - - /** - * Handles the showing of the extension directory browser. - * @param {Event} e Change event. - * @private - */ - handleBrowseExtensionDir_: function(e) { - this.showFileDialog_( - chrome.developerPrivate.SelectType.FOLDER, - chrome.developerPrivate.FileType.LOAD, - /** @type {HTMLInputElement} */ ($('extension-root-dir'))); - }, - - /** - * Handles the showing of the extension private key file. - * @param {Event} e Change event. - * @private - */ - handleBrowsePrivateKey_: function(e) { - this.showFileDialog_( - chrome.developerPrivate.SelectType.FILE, - chrome.developerPrivate.FileType.PEM, - /** @type {HTMLInputElement} */ ($('extension-private-key'))); - }, - - /** - * Handles a response from a packDirectory call. - * @param {chrome.developerPrivate.PackDirectoryResponse} response The - * response of the pack call. - * @private - */ - onPackResponse_: function(response) { - /** @type {string} */ - var alertTitle; - /** @type {string} */ - var alertOk; - /** @type {string} */ - var alertCancel; - /** @type {function()} */ - var alertOkCallback; - /** @type {function()} */ - var alertCancelCallback; - - var closeAlert = function() { - extensions.ExtensionSettings.showOverlay(null); - }; - - switch (response.status) { - case chrome.developerPrivate.PackStatus.SUCCESS: - alertTitle = loadTimeData.getString('packExtensionOverlay'); - alertOk = loadTimeData.getString('ok'); - alertOkCallback = closeAlert; - // No 'Cancel' option. - break; - case chrome.developerPrivate.PackStatus.WARNING: - alertTitle = loadTimeData.getString('packExtensionWarningTitle'); - alertOk = loadTimeData.getString('packExtensionProceedAnyway'); - alertCancel = loadTimeData.getString('cancel'); - alertOkCallback = function() { - chrome.developerPrivate.packDirectory( - response.item_path, - response.pem_path, - response.override_flags, - this.onPackResponse_.bind(this)); - closeAlert(); - }.bind(this); - alertCancelCallback = closeAlert; - break; - case chrome.developerPrivate.PackStatus.ERROR: - alertTitle = loadTimeData.getString('packExtensionErrorTitle'); - alertOk = loadTimeData.getString('ok'); - alertOkCallback = function() { - extensions.ExtensionSettings.showOverlay( - $('pack-extension-overlay')); - }; - // No 'Cancel' option. - break; - default: - assertNotReached(); - return; - } - - alertOverlay.setValues(alertTitle, - response.message, - alertOk, - alertCancel, - alertOkCallback, - alertCancelCallback); - extensions.ExtensionSettings.showOverlay($('alertOverlay')); - }, - }; - - // Export - return { - PackExtensionOverlay: PackExtensionOverlay - }; -});
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0746556..8bbe039 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3620,8 +3620,6 @@ "app_list/crostini/crostini_app_model_builder.h", "app_list/crostini/crostini_installer_view.cc", "app_list/crostini/crostini_installer_view.h", - "app_list/crostini/crostini_util.cc", - "app_list/crostini/crostini_util.h", "app_list/internal_app/internal_app_icon_loader.cc", "app_list/internal_app/internal_app_icon_loader.h", "app_list/internal_app/internal_app_item.cc",
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index e504f49..c8b0e3b9 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -14,6 +14,7 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/genius_app/app_id.h" #include "chrome/browser/extensions/extension_service.h" @@ -27,7 +28,6 @@ #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/chrome_app_list_model_updater.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_model_builder.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/app_list/extension_app_item.h" #include "chrome/browser/ui/app_list/extension_app_model_builder.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_model_builder.h"
diff --git a/chrome/browser/ui/app_list/crostini/crostini_app_item.cc b/chrome/browser/ui/app_list/crostini/crostini_app_item.cc index 81270cf..a7271b2 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_app_item.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_app_item.cc
@@ -8,11 +8,13 @@ #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h" #include "chrome/browser/ui/app_list/crostini/crostini_installer_view.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" +#include "ui/app_list/app_list_constants.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_skia_operations.h" // static const char CrostiniAppItem::kItemType[] = "CrostiniAppItem"; @@ -24,7 +26,9 @@ const std::string& name, const gfx::ImageSkia* image_skia) : ChromeAppListItem(profile, id) { - SetIcon(*image_skia); + SetIcon(gfx::ImageSkiaOperations::CreateResizedImage( + *image_skia, skia::ImageOperations::RESIZE_BEST, + gfx::Size(app_list::kTileIconSize, app_list::kTileIconSize))); SetName(name); if (sync_item && sync_item->item_ordinal.IsValid()) { UpdateFromSync(sync_item);
diff --git a/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc b/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc index 1630e2e8..16cccb5 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc
@@ -4,10 +4,10 @@ #include "chrome/browser/ui/app_list/crostini/crostini_app_model_builder.h" -#include "ash/resources/grit/ash_resources.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_item.h" +#include "chrome/grit/chrome_unscaled_resources.h" #include "components/crx_file/id_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -54,11 +54,11 @@ const std::string& localized_name = crostini::CrostiniRegistryService::Registration::Localize( registration->name); - // TODO(timloh): Use a real icon + // TODO(timloh): Get an icon from the registry. InsertApp(std::make_unique<CrostiniAppItem>( profile(), GetSyncItem(app_id), app_id, localized_name, ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_LOGO_CROSTINI_TERMINAL))); + IDR_LOGO_CROSTINI_DEFAULT))); } void CrostiniAppModelBuilder::OnRegistryUpdated(
diff --git a/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc b/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc index f71a552e..7ff125cd 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc
@@ -11,9 +11,9 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_item.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/grit/generated_resources.h" #include "components/signin/core/account_id/account_id.h" @@ -29,6 +29,8 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/layout_provider.h" +using crostini::ConciergeClientResult; + namespace { CrostiniInstallerView* g_crostini_installer_view = nullptr; @@ -104,10 +106,24 @@ GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); - InstallImageLoader(); + // Kick off the Crostini Restart sequence. We will be added as an observer. + restart_id_ = crostini::CrostiniManager::GetInstance()->RestartCrostini( + profile_, kCrostiniDefaultVmName, kCrostiniDefaultContainerName, + base::BindOnce(&CrostiniInstallerView::StartContainerFinished, + weak_ptr_factory_.GetWeakPtr()), + this); return false; } +bool CrostiniInstallerView::Cancel() { + if (restart_id_ != crostini::CrostiniManager::kUninitializedRestartId) { + // Abort the long-running flow, and prevent our RestartObserver methods + // being called after "this" has been destroyed. + crostini::CrostiniManager::GetInstance()->AbortRestartCrostini(restart_id_); + } + return true; // Should close the dialog +} + gfx::Size CrostiniInstallerView::CalculatePreferredSize() const { int height = GetLayoutManager()->GetPreferredHeightForWidth(this, kDialogWidth); @@ -123,14 +139,7 @@ Profile* profile) : app_name_(base::ASCIIToUTF16(app_item->name())), profile_(profile), - cryptohome_id_(chromeos::ProfileHelper::Get() - ->GetUserByProfile(profile) - ->username_hash()), weak_ptr_factory_(this) { - // Get rid of the @domain.name in the container_user_name_ (an email address). - container_user_name_ = profile_->GetProfileUserName(); - container_user_name_ = - container_user_name_.substr(0, container_user_name_.find('@')); views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -178,85 +187,38 @@ GetWidget()->UpdateWindowTitle(); } -void CrostiniInstallerView::InstallImageLoader() { - VLOG(1) << "Installing cros-termina component"; +void CrostiniInstallerView::OnComponentLoaded(ConciergeClientResult result) { DCHECK_EQ(state_, State::INSTALL_START); state_ = State::INSTALL_IMAGE_LOADER; - g_browser_process->platform_part()->cros_component_manager()->Load( - "cros-termina", - component_updater::CrOSComponentManager::MountPolicy::kMount, - base::BindOnce(InstallImageLoaderFinished, - weak_ptr_factory_.GetWeakPtr())); -} - -void CrostiniInstallerView::InstallImageLoaderFinished( - base::WeakPtr<CrostiniInstallerView> weak_ptr, - component_updater::CrOSComponentManager::Error error, - const base::FilePath& result) { - DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce( - &CrostiniInstallerView::InstallImageLoaderFinishedOnUIThread, - weak_ptr, error, result)); -} - -void CrostiniInstallerView::InstallImageLoaderFinishedOnUIThread( - component_updater::CrOSComponentManager::Error error, - const base::FilePath& result) { - if (error != component_updater::CrOSComponentManager::Error::NONE) { - LOG(ERROR) - << "Failed to install the cros-termina component with error code: " - << static_cast<int>(error); + if (result != ConciergeClientResult::SUCCESS) { + LOG(ERROR) << "Failed to install the cros-termina component"; HandleError( l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_LOAD_TERMINA_ERROR)); return; } VLOG(1) << "cros-termina install success"; StepProgress(); - StartVmConcierge(); } -void CrostiniInstallerView::StartVmConcierge() { +void CrostiniInstallerView::OnConciergeStarted(ConciergeClientResult result) { DCHECK_EQ(state_, State::INSTALL_IMAGE_LOADER); state_ = State::START_CONCIERGE; - - crostini::CrostiniManager::GetInstance()->StartVmConcierge( - base::BindOnce(&CrostiniInstallerView::StartVmConciergeFinished, - weak_ptr_factory_.GetWeakPtr())); -} - -void CrostiniInstallerView::StartVmConciergeFinished(bool success) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!success) { - LOG(ERROR) << "Failed to install start Concierge"; + if (result != ConciergeClientResult::SUCCESS) { + LOG(ERROR) << "Failed to install start Concierge with error code: " + << static_cast<int>(result); HandleError(l10n_util::GetStringUTF16( IDS_CROSTINI_INSTALLER_START_CONCIERGE_ERROR)); return; } VLOG(1) << "VmConcierge service started"; StepProgress(); - CreateDiskImage(); } -void CrostiniInstallerView::CreateDiskImage() { - DCHECK_EQ(state_, State::START_CONCIERGE); +void CrostiniInstallerView::OnDiskImageCreated(ConciergeClientResult result) { + DCHECK_EQ(state_, State::INSTALL_IMAGE_LOADER); state_ = State::CREATE_DISK_IMAGE; - - VLOG(1) << "Creating crostini disk image"; - crostini::CrostiniManager::GetInstance()->CreateDiskImage( - cryptohome_id_, base::FilePath(kCrostiniDefaultVmName), - vm_tools::concierge::StorageLocation::STORAGE_CRYPTOHOME_ROOT, - base::BindOnce(&CrostiniInstallerView::CreateDiskImageFinished, - weak_ptr_factory_.GetWeakPtr())); -} - -void CrostiniInstallerView::CreateDiskImageFinished( - crostini::ConciergeClientResult result, - const base::FilePath& result_path) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (result != crostini::ConciergeClientResult::SUCCESS) { - LOG(ERROR) << "Failed to create disk image with error code: " + if (result != ConciergeClientResult::SUCCESS) { + LOG(ERROR) << "Failed to create disk imagewith error code: " << static_cast<int>(result); HandleError(l10n_util::GetStringUTF16( IDS_CROSTINI_INSTALLER_CREATE_DISK_IMAGE_ERROR)); @@ -264,24 +226,12 @@ } VLOG(1) << "Created crostini disk image"; StepProgress(); - StartTerminaVm(result_path); } -void CrostiniInstallerView::StartTerminaVm(const base::FilePath& result_path) { +void CrostiniInstallerView::OnVmStarted(ConciergeClientResult result) { DCHECK_EQ(state_, State::CREATE_DISK_IMAGE); state_ = State::START_TERMINA_VM; - - VLOG(1) << "Starting Termina VM"; - crostini::CrostiniManager::GetInstance()->StartTerminaVm( - kCrostiniDefaultVmName, result_path, - base::BindOnce(&CrostiniInstallerView::StartTerminaVmFinished, - weak_ptr_factory_.GetWeakPtr())); -} - -void CrostiniInstallerView::StartTerminaVmFinished( - crostini::ConciergeClientResult result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (result != crostini::ConciergeClientResult::SUCCESS) { + if (result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to start Termina VM with error code: " << static_cast<int>(result); HandleError(l10n_util::GetStringUTF16( @@ -290,26 +240,12 @@ } VLOG(1) << "Started Termina VM successfully"; StepProgress(); - StartContainer(); -} - -void CrostiniInstallerView::StartContainer() { - DCHECK_EQ(state_, State::START_TERMINA_VM); - state_ = State::START_CONTAINER; - VLOG(1) << "In vm " << kCrostiniDefaultVmName << ", starting container " - << kCrostiniDefaultContainerName << " as user " - << container_user_name_; - crostini::CrostiniManager::GetInstance()->StartContainer( - kCrostiniDefaultVmName, kCrostiniDefaultContainerName, - container_user_name_, - base::BindOnce(&CrostiniInstallerView::StartContainerFinished, - weak_ptr_factory_.GetWeakPtr())); } void CrostiniInstallerView::StartContainerFinished( - crostini::ConciergeClientResult result) { + ConciergeClientResult result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (result != crostini::ConciergeClientResult::SUCCESS) { + if (result != ConciergeClientResult::SUCCESS) { LOG(ERROR) << "Failed to start container with error code: " << static_cast<int>(result); HandleError(l10n_util::GetStringUTF16(
diff --git a/chrome/browser/ui/app_list/crostini/crostini_installer_view.h b/chrome/browser/ui/app_list/crostini/crostini_installer_view.h index 6b822a8..26e2ef5 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_installer_view.h +++ b/chrome/browser/ui/app_list/crostini/crostini_installer_view.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/component_updater/cros_component_installer.h" #include "ui/views/window/dialog_delegate.h" @@ -24,7 +25,9 @@ // The Crostini installer. Provides details about Crostini to the user and // installs it if the user chooses to do so. -class CrostiniInstallerView : public views::DialogDelegateView { +class CrostiniInstallerView + : public views::DialogDelegateView, + public crostini::CrostiniManager::RestartObserver { public: static void Show(const CrostiniAppItem* app_item, Profile* profile); @@ -34,8 +37,15 @@ base::string16 GetWindowTitle() const override; bool ShouldShowCloseButton() const override; bool Accept() override; + bool Cancel() override; gfx::Size CalculatePreferredSize() const override; + // crostini::CrostiniManager::RestartObserver + void OnComponentLoaded(crostini::ConciergeClientResult result) override; + void OnConciergeStarted(crostini::ConciergeClientResult result) override; + void OnDiskImageCreated(crostini::ConciergeClientResult result) override; + void OnVmStarted(crostini::ConciergeClientResult result) override; + static CrostiniInstallerView* GetActiveViewForTesting(); private: @@ -44,26 +54,6 @@ void HandleError(const base::string16& error_message); - void InstallImageLoader(); - static void InstallImageLoaderFinished( - base::WeakPtr<CrostiniInstallerView> weak_ptr, - component_updater::CrOSComponentManager::Error error, - const base::FilePath& result); - void InstallImageLoaderFinishedOnUIThread( - component_updater::CrOSComponentManager::Error error, - const base::FilePath& result); - - void StartVmConcierge(); - void StartVmConciergeFinished(bool success); - - void CreateDiskImage(); - void CreateDiskImageFinished(crostini::ConciergeClientResult result, - const base::FilePath& result_path); - - void StartTerminaVm(const base::FilePath& result_path); - void StartTerminaVmFinished(crostini::ConciergeClientResult result); - - void StartContainer(); void StartContainerFinished(crostini::ConciergeClientResult result); void ShowLoginShell(); @@ -88,8 +78,8 @@ views::ProgressBar* progress_bar_ = nullptr; base::string16 app_name_; Profile* profile_; - std::string cryptohome_id_; - std::string container_user_name_; + crostini::CrostiniManager::RestartId restart_id_ = + crostini::CrostiniManager::kUninitializedRestartId; base::WeakPtrFactory<CrostiniInstallerView> weak_ptr_factory_;
diff --git a/chrome/browser/ui/app_list/crostini/crostini_installer_view_browsertest.cc b/chrome/browser/ui/app_list/crostini/crostini_installer_view_browsertest.cc index 2d06d74..43bd8c65 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_installer_view_browsertest.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_installer_view_browsertest.cc
@@ -6,10 +6,10 @@ #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_service_impl.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_model_builder.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index 5baf12d..36ef6bf31 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/mus_property_mirror_ash.h" #include "ash/public/cpp/shelf_model.h" @@ -19,9 +18,10 @@ #include "ash/public/interfaces/window_properties.mojom.h" #include "ash/public/interfaces/window_state_type.mojom.h" #include "ash/shell.h" +#include "base/command_line.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/ash_config.h" -#include "chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h" +#include "chrome/browser/chromeos/net/network_portal_notification_controller.h" #include "chrome/browser/chromeos/night_light/night_light_client.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -50,9 +50,11 @@ #include "chrome/browser/ui/views/select_file_dialog_extension_factory.h" #include "chromeos/network/network_connect.h" #include "chromeos/network/network_handler.h" +#include "chromeos/network/portal_detector/network_portal_detector.h" #include "components/session_manager/core/session_manager.h" #include "components/session_manager/core/session_manager_observer.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" +#include "content/public/common/content_switches.h" #include "content/public/common/service_manager_connection.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" @@ -257,6 +259,18 @@ login_screen_client_ = std::make_unique<LoginScreenClient>(); media_client_ = std::make_unique<MediaClient>(); + // Do not create a NetworkPortalNotificationController for tests since the + // NetworkPortalDetector instance may be replaced. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kTestType)) { + chromeos::NetworkPortalDetector* detector = + chromeos::network_portal_detector::GetInstance(); + CHECK(detector); + network_portal_notification_controller_ = + std::make_unique<chromeos::NetworkPortalNotificationController>( + detector); + } + // TODO(mash): Port TabScrubber. if (chromeos::GetAshConfig() != ash::Config::MASH) { // Initialize TabScrubber after the Ash Shell has been initialized. @@ -281,11 +295,6 @@ g_browser_process->system_request_context()); night_light_client_->Start(); } - - if (ash::features::IsDockedMagnifierEnabled()) { - docked_magnifier_client_ = std::make_unique<DockedMagnifierClient>(); - docked_magnifier_client_->Start(); - } } void ChromeBrowserMainExtraPartsAsh::PostMainMessageLoopRun() { @@ -307,6 +316,7 @@ system_tray_client_.reset(); session_controller_client_.reset(); chrome_new_window_client_.reset(); + network_portal_notification_controller_.reset(); media_client_.reset(); login_screen_client_.reset(); ime_controller_client_.reset();
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h index 9ad744e..19698a2 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
@@ -15,6 +15,10 @@ class UserActivityForwarder; } +namespace chromeos { +class NetworkPortalNotificationController; +} + namespace ui { class UserActivityDetector; } @@ -27,7 +31,6 @@ class ChromeNewWindowClient; class ChromeShellContentState; class DataPromoNotification; -class DockedMagnifierClient; class ImeControllerClient; class ImmersiveContextMus; class ImmersiveHandlerFactoryMus; @@ -90,6 +93,10 @@ std::unique_ptr<VolumeController> volume_controller_; std::unique_ptr<VpnListForwarder> vpn_list_forwarder_; std::unique_ptr<WallpaperControllerClient> wallpaper_controller_client_; + // TODO(stevenjb): Move NetworkPortalNotificationController to c/b/ui/ash and + // elim chromeos:: namespace. https://crbug.com/798569. + std::unique_ptr<chromeos::NetworkPortalNotificationController> + network_portal_notification_controller_; std::unique_ptr<internal::ChromeLauncherControllerInitializer> chrome_launcher_controller_initializer_; @@ -110,7 +117,6 @@ // Initialized in PostBrowserStart in all configs: std::unique_ptr<DataPromoNotification> data_promo_notification_; std::unique_ptr<NightLightClient> night_light_client_; - std::unique_ptr<DockedMagnifierClient> docked_magnifier_client_; DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsAsh); };
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index 8015912..b1f186d 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -23,6 +23,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/ash_config.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/extensions/chrome_app_icon_loader.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/prefs/pref_service_syncable_util.h" @@ -33,7 +34,6 @@ #include "chrome/browser/ui/app_list/app_sync_ui_state.h" #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_icon_loader.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc index 60478dc..23d6439 100644 --- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc +++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
@@ -8,7 +8,10 @@ #include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/window_properties.h" #include "base/bind.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" +#include "base/strings/string_util.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/ui/ash/launcher/app_window_base.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" @@ -20,12 +23,6 @@ #include "ui/display/manager/display_manager.h" #include "ui/views/widget/widget.h" -namespace { - -constexpr char kArcAppIdPrefix[] = "org.chromium.arc"; - -} // namespace - CrostiniAppWindowShelfController::CrostiniAppWindowShelfController( ChromeLauncherController* owner) : AppWindowLauncherController(owner) { @@ -62,30 +59,32 @@ if (!visible) return; - const std::string* window_app_id = - exo::ShellSurface::GetApplicationId(window); - if (window_app_id == nullptr) - return; - - // Skip handling ARC++ windows. - if (strncmp(window_app_id->c_str(), kArcAppIdPrefix, - sizeof(kArcAppIdPrefix) - 1) == 0) - return; - // Skip when this window has been handled. This can happen when the window // becomes visible again. auto app_window_it = aura_window_to_app_window_.find(window); if (app_window_it != aura_window_to_app_window_.end()) return; - RegisterAppWindow(window, window_app_id); + const std::string* window_app_id = + exo::ShellSurface::GetApplicationId(window); + if (window_app_id == nullptr) + return; + crostini::CrostiniRegistryService* registry_service = + crostini::CrostiniRegistryServiceFactory::GetForProfile( + owner()->profile()); + const std::string& shelf_app_id = registry_service->GetCrostiniShelfAppId( + *window_app_id, exo::ShellSurface::GetStartupId(window)); + // Non-crostini apps (i.e. arc++) are filtered out here. + if (shelf_app_id.empty()) + return; + + RegisterAppWindow(window, shelf_app_id); } void CrostiniAppWindowShelfController::RegisterAppWindow( aura::Window* window, - const std::string* window_app_id) { - const std::string crostini_app_id = CreateCrostiniAppId(*window_app_id); - const ash::ShelfID shelf_id(crostini_app_id); + const std::string& shelf_app_id) { + const ash::ShelfID shelf_id(shelf_app_id); views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); aura_window_to_app_window_[window] = std::make_unique<AppWindowBase>(shelf_id, widget);
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h index 2e9123c..6dac2b6 100644 --- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h +++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h
@@ -45,8 +45,7 @@ using AuraWindowToAppWindow = std::map<aura::Window*, std::unique_ptr<AppWindowBase>>; - void RegisterAppWindow(aura::Window* window, - const std::string* window_app_id); + void RegisterAppWindow(aura::Window* window, const std::string& shelf_app_id); void UnregisterAppWindow(AppWindowBase* app_window); // AppWindowLauncherController:
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc index 64dfc15..a763e37 100644 --- a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc +++ b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
@@ -9,9 +9,10 @@ #include "ash/public/cpp/shelf_model.h" #include "base/metrics/user_metrics.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" -#include "chrome/browser/ui/app_list/crostini/crostini_util.h" #include "chrome/browser/ui/ash/launcher/arc_launcher_context_menu.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h" @@ -40,7 +41,9 @@ } // Create an CrostiniShelfContextMenu if the item is Crostini app. - if (IsCrostiniAppId(item->id.app_id)) { + if (crostini::CrostiniRegistryServiceFactory::GetForProfile( + controller->profile()) + ->IsCrostiniShelfAppId(item->id.app_id)) { return std::make_unique<CrostiniShelfContextMenu>(controller, item, display_id); }
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm index c10f54a..1e2fca94 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm
@@ -173,7 +173,7 @@ MDDownloadShelfCloseButton* closeButton = scopedCloseButton; closeButton.autoresizingMask = [NSView cr_localizedAutoresizingMask:NSViewMinXMargin]; - closeButton.icon = &vector_icons::kClose16Icon; + closeButton.icon = &vector_icons::kCloseRoundedIcon; [closeButton cr_setAccessibilityLabel:l10n_util::GetNSString(IDS_HIDE_DOWNLOADS)]; closeButton.target = self;
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm index b123fe18..657865bc 100644 --- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm +++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
@@ -36,18 +36,6 @@ namespace { -// Update the App Controller with a new Profile. Used when a Profile is locked -// to set the Controller to the Guest profile so the old Profile's bookmarks, -// etc... cannot be accessed. -void ChangeAppControllerForProfile(Profile* profile, - Profile::CreateStatus status) { - if (status == Profile::CREATE_STATUS_INITIALIZED) { - AppController* controller = - base::mac::ObjCCast<AppController>([NSApp delegate]); - [controller windowChangedToProfile:profile]; - } -} - // An open User Manager window. There can only be one open at a time. This // is reset to NULL when the window is closed. UserManagerMac* instance_ = nullptr; // Weak. @@ -368,14 +356,8 @@ // will not trigger a -windowChangedToProfile and update the menu bar. // This is only important if the active profile is Guest, which may have // happened after locking a profile. - if (profiles::SetActiveProfileToGuestIfLocked()) { - g_browser_process->profile_manager()->CreateProfileAsync( - ProfileManager::GetGuestProfilePath(), - base::Bind(&ChangeAppControllerForProfile), - base::string16(), - std::string(), - std::string()); - } + if (profiles::SetActiveProfileToGuestIfLocked()) + app_controller_mac::CreateGuestProfileIfNeeded(); [[self window] makeKeyAndOrderFront:self]; }
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc index 67037365..e0c6b1c 100644 --- a/chrome/browser/ui/startup/bad_flags_prompt.cc +++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -141,25 +141,6 @@ // On Android, ShowBadFlagsPrompt doesn't show the warning notification // for flags which are not available in about:flags. #if !defined(OS_ANDROID) - // Flags only available in specific builds, for which to display a warning - // "the flag is not implemented in this build", if necessary. - struct { - const char* name; - bool is_invalid; - } conditional_flags[] = { - {switches::kEnableHeapProfiling, - base::trace_event::MemoryDumpManager:: - GetHeapProfilingModeFromCommandLine() == - base::trace_event::kHeapProfilingModeInvalid}, - }; - for (auto conditional_flag : conditional_flags) { - if (conditional_flag.is_invalid) { - ShowBadFlagsInfoBar(web_contents, IDS_UNIMPLEMENTED_FLAGS_WARNING_MESSAGE, - conditional_flag.name); - return; - } - } - for (const char* flag : kBadFlags) { if (base::CommandLine::ForCurrentProcess()->HasSwitch(flag)) { ShowBadFlagsInfoBar(web_contents, IDS_BAD_FLAGS_WARNING_MESSAGE, flag);
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 8dcc110..d1fe741 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -11,6 +11,7 @@ #include "components/autofill/core/browser/suggestion.h" #include "ui/accessibility/ax_node_data.h" #include "ui/native_theme/native_theme.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/image_view.h" @@ -59,8 +60,8 @@ frontend_id == autofill::POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE; - SetFocusBehavior(is_separator_ ? FocusBehavior::ALWAYS - : FocusBehavior::NEVER); + SetFocusBehavior(is_separator_ ? FocusBehavior::NEVER + : FocusBehavior::ALWAYS); CreateContent(); } @@ -73,6 +74,7 @@ return; is_selected_ = is_selected; + NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true); RefreshStyle(); } @@ -137,8 +139,32 @@ } void AutofillPopupRowView::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ax::mojom::Role::kMenuItem; node_data->SetName(controller_->GetSuggestionAt(line_number_).value); + + if (is_separator_) { + // Separators are not selectable. + node_data->role = ax::mojom::Role::kSplitter; + } else { + // Options are selectable. + node_data->role = ax::mojom::Role::kMenuItem; + node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, + is_selected_); + + // Compute set size and position in set, which must not include separators. + int set_size = 0; + int pos_in_set = line_number_ + 1; + for (int i = 0; i < controller_->GetLineCount(); ++i) { + if (controller_->GetSuggestionAt(i).frontend_id == + autofill::POPUP_ITEM_ID_SEPARATOR) { + if (i < line_number_) + --pos_in_set; + } else { + ++set_size; + } + } + node_data->AddIntAttribute(ax::mojom::IntAttribute::kSetSize, set_size); + node_data->AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, pos_in_set); + } } void AutofillPopupRowView::CreateContent() { @@ -233,11 +259,31 @@ return size; } +void AutofillPopupViewNativeViews::VisibilityChanged(View* starting_from, + bool is_visible) { + if (is_visible) { + GetViewAccessibility().OnAutofillShown(); + } else { + GetViewAccessibility().OnAutofillHidden(); + NotifyAccessibilityEvent(ax::mojom::Event::kMenuEnd, true); + } +} + void AutofillPopupViewNativeViews::OnSelectedRowChanged( base::Optional<int> previous_row_selection, base::Optional<int> current_row_selection) { - if (previous_row_selection) + if (previous_row_selection) { rows_[*previous_row_selection]->SetSelected(false); + } else { + // Fire this the first time a row is selected. By firing this and the + // matching kMenuEnd event, we are telling screen readers that the focus + // is only changing temporarily, and the screen reader will restore the + // focus back to the appropriate textfield when the menu closes. + // This is deferred until the first focus so that the screen reader doesn't + // treat the textfield as unfocused while the user edits, just because + // autofill options are visible. + NotifyAccessibilityEvent(ax::mojom::Event::kMenuStart, true); + } if (current_row_selection) rows_[*current_row_selection]->SetSelected(true);
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h index 8823f71..49f4c55 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h
@@ -98,6 +98,9 @@ void OnMouseMoved(const ui::MouseEvent& event) override {} private: + // views::View: + void VisibilityChanged(View* starting_from, bool is_visible) override; + void OnSelectedRowChanged(base::Optional<int> previous_row_selection, base::Optional<int> current_row_selection) override; void OnSuggestionsChanged() override;
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc index 326832b..255c746 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
@@ -10,10 +10,12 @@ #include "build/build_config.h" #include "chrome/browser/ui/autofill/autofill_popup_controller.h" #include "chrome/browser/ui/autofill/autofill_popup_layout_model.h" +#include "chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h" #include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/suggestion.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/aura/test/aura_test_base.h" #include "ui/events/base_event_utils.h" #include "ui/events/test/event_generator.h" @@ -170,6 +172,45 @@ view()->Hide(); } +TEST_F(AutofillPopupViewNativeViewsTest, AccessibilityTest) { + CreateAndShowView({autofill::POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY, + autofill::POPUP_ITEM_ID_SEPARATOR, + autofill::POPUP_ITEM_ID_AUTOFILL_OPTIONS}); + + // Select first item. + static_cast<autofill::AutofillPopupRowView*>(view()->child_at(0)) + ->SetSelected(true); + + EXPECT_EQ(view()->child_count(), 3); + + // Item 0. + ui::AXNodeData node_data_0; + view()->child_at(0)->GetAccessibleNodeData(&node_data_0); + EXPECT_EQ(ax::mojom::Role::kMenuItem, node_data_0.role); + EXPECT_EQ(1, node_data_0.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(2, node_data_0.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + EXPECT_TRUE( + node_data_0.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)); + + // Item 1 (separator). + ui::AXNodeData node_data_1; + view()->child_at(1)->GetAccessibleNodeData(&node_data_1); + EXPECT_FALSE(node_data_1.HasIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_FALSE(node_data_1.HasIntAttribute(ax::mojom::IntAttribute::kSetSize)); + EXPECT_EQ(ax::mojom::Role::kSplitter, node_data_1.role); + EXPECT_FALSE( + node_data_1.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)); + + // Item 2. + ui::AXNodeData node_data_2; + view()->child_at(2)->GetAccessibleNodeData(&node_data_2); + EXPECT_EQ(2, node_data_2.GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + EXPECT_EQ(2, node_data_2.GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + EXPECT_EQ(ax::mojom::Role::kMenuItem, node_data_2.role); + EXPECT_FALSE( + node_data_2.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)); +} + TEST_P(AutofillPopupViewNativeViewsForEveryTypeTest, ShowClickTest) { const TypeClicks& click = GetParam(); CreateAndShowView({click.id});
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc index 642148e7..b952f924 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -342,7 +342,7 @@ GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR))); views::SetImageFromVectorIcon( - close_button_, vector_icons::kClose16Icon, + close_button_, vector_icons::kCloseRoundedIcon, DownloadItemView::GetTextColorForThemeProvider(GetThemeProvider())); }
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc index 42593d01..b3ace6f 100644 --- a/chrome/browser/ui/views/find_bar_view.cc +++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -465,6 +465,6 @@ base_icon_color); views::SetImageFromVectorIcon(find_next_button_, kCaretDownIcon, base_icon_color); - views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, + views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon, base_icon_color); }
diff --git a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc b/chrome/browser/ui/views/frame/hosted_app_menu_button.cc index 27078703..9a7b1103 100644 --- a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc +++ b/chrome/browser/ui/views/frame/hosted_app_menu_button.cc
@@ -26,8 +26,8 @@ SetInkDropMode(InkDropMode::ON); // Disable focus ring for consistency with sibling buttons and AppMenuButton. SetFocusPainter(nullptr); - // We have no need for a border, native theme borders can cause our menu icon - // to get cropped, see https://crbug.com/831968. + // Avoid the native theme border, which would crop the icon (see + // https://crbug.com/831968). SetBorder(nullptr); // This name is guaranteed not to change during the lifetime of this button. // Get the app name only, aka "Google Docs" instead of "My Doc - Google Docs",
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 5bb6b84..1e0fde6 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -112,7 +112,7 @@ close_button_ = views::CreateVectorImageButton(this); // This is the wrong color, but allows the button's size to be computed // correctly. We'll reset this with the correct color in OnThemeChanged(). - views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, + views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon, gfx::kPlaceholderColor); close_button_->SetAccessibleName( l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); @@ -216,7 +216,7 @@ SetBackground(views::CreateSolidBackground(background_color)); const SkColor text_color = GetColor(kTextColor); - views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, + views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon, text_color); for (int i = 0; i < child_count(); ++i) {
diff --git a/chrome/browser/ui/views/infobars/infobar_view_unittest.cc b/chrome/browser/ui/views/infobars/infobar_view_unittest.cc index 444f1fe..57e7937 100644 --- a/chrome/browser/ui/views/infobars/infobar_view_unittest.cc +++ b/chrome/browser/ui/views/infobars/infobar_view_unittest.cc
@@ -36,6 +36,13 @@ return InfoBarService::FromWebContents(web_contents_); } + // Detaches |infobar_container_view_| from infobar_service(), so that newly- + // created infobars will not be placed in a container. This can be used to + // simulate creating an infobar in a background tab. + void DetachContainer() { + infobar_container_view_.ChangeInfoBarManager(nullptr); + } + private: content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; @@ -53,3 +60,14 @@ EXPECT_EQ(i > 0, infobar->ShouldDrawSeparator()); } } + +// Regression test for crbug.com/834728 . +TEST_F(InfoBarViewTest, LayoutOnHiddenInfoBar) { + // Calling Layout() on an infobar inside a container should not crash. + InfoBarView* infobar = TestInfoBarDelegate::Create(infobar_service()); + ASSERT_TRUE(infobar); + infobar->Layout(); + // Neither should calling it on an infobar not in a container. + DetachContainer(); + infobar->Layout(); +}
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.cc b/chrome/browser/ui/views/page_info/chosen_object_view.cc index 3e291cf..c426974 100644 --- a/chrome/browser/ui/views/page_info/chosen_object_view.cc +++ b/chrome/browser/ui/views/page_info/chosen_object_view.cc
@@ -76,7 +76,7 @@ if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { delete_button_ = views::CreateVectorImageButton(this); views::SetImageFromVectorIcon( - delete_button_, vector_icons::kClose16Icon, + delete_button_, vector_icons::kCloseRoundedIcon, views::style::GetColor(*this, CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_PRIMARY));
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.cc b/chrome/browser/ui/views/profiles/user_manager_view.cc index b7fce4d4..07ed21be 100644 --- a/chrome/browser/ui/views/profiles/user_manager_view.cc +++ b/chrome/browser/ui/views/profiles/user_manager_view.cc
@@ -46,6 +46,10 @@ #include "ui/views/win/hwnd_util.h" #endif +#if defined(OS_MACOSX) +#include "chrome/browser/app_controller_mac.h" +#endif + namespace { // An open User Manager window. There can only be one open at a time. This @@ -151,6 +155,10 @@ // active profile to Guest. profiles::SetActiveProfileToGuestIfLocked(); +#if defined(OS_MACOSX) + app_controller_mac::CreateGuestProfileIfNeeded(); +#endif + // Note the time we started opening the User Manager. g_user_manager_view->set_user_manager_started_showing(base::Time::Now()); @@ -379,6 +387,10 @@ // active profile to Guest. profiles::SetActiveProfileToGuestIfLocked(); +#if defined(OS_MACOSX) + app_controller_mac::CreateGuestProfileIfNeeded(); +#endif + DCHECK(!g_user_manager_view); g_user_manager_view = instance.release(); // |g_user_manager_view| takes over ownership.
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 255fb71..53b1fc7cc 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -275,8 +275,7 @@ if (!network_portal_detector_) { NetworkPortalDetectorImpl* detector = new NetworkPortalDetectorImpl( g_browser_process->system_network_context_manager() - ->GetURLLoaderFactory(), - false); + ->GetURLLoaderFactory()); detector->set_portal_test_url(GURL(kRestrictiveProxyURL)); network_portal_detector_.reset(detector); network_portal_detector_->AddObserver(this);
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 40285b1..c58e5f9 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -116,6 +116,7 @@ const char kEnrollmentJSPath[] = "enrollment.js"; const char kArcAssistantLogoPath[] = "assistant_logo.png"; const char kArcPlaystoreCSSPath[] = "playstore.css"; +const char kArcOverlayCSSPath[] = "overlay.css"; const char kArcPlaystoreJSPath[] = "playstore.js"; const char kArcPlaystoreLogoPath[] = "playstore.svg"; const char kProductLogoPath[] = "product-logo.png"; @@ -169,7 +170,8 @@ // No #else section here as Sync Settings screen is Chrome-specific. #endif - // Required for postprocessing of Goolge PlayStore Terms. + // Required for postprocessing of Goolge PlayStore Terms and Overlay help. + source->AddResourcePath(kArcOverlayCSSPath, IDR_ARC_SUPPORT_OVERLAY_CSS); source->AddResourcePath(kArcPlaystoreCSSPath, IDR_ARC_SUPPORT_PLAYSTORE_CSS); source->AddResourcePath(kArcPlaystoreJSPath, IDR_ARC_SUPPORT_PLAYSTORE_JS); source->AddResourcePath(kArcPlaystoreLogoPath,
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc index bf9bf597..2b653ec 100644 --- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
@@ -31,7 +31,11 @@ const char* name; int id; } kLocalizedStrings[] = { - {"title", IDS_MULTIDEVICE_SETUP_DIALOG_TITLE}, {"cancel", IDS_CANCEL}, + {"accept", IDS_MULTIDEVICE_SETUP_ACCEPT_LABEL}, + {"cancel", IDS_CANCEL}, + {"done", IDS_DONE}, + {"title", IDS_MULTIDEVICE_SETUP_DIALOG_TITLE}, + {"tryAgain", IDS_MULTIDEVICE_SETUP_TRY_AGAIN_LABEL}, }; for (const auto& entry : kLocalizedStrings)
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js deleted file mode 100644 index 85ec336..0000000 --- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js +++ /dev/null
@@ -1,269 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -GEN('#include "base/command_line.h"'); -GEN('#include "chrome/common/chrome_features.h"'); - -/** - * TestFixture for kiosk app settings WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function KioskAppSettingsWebUITest() {} - -KioskAppSettingsWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** - * Browse to the kiosk app settings page. - */ - browsePreload: 'chrome://extensions/', - - /** @override */ - commandLineSwitches: [{ - switchName: 'enable-consumer-kiosk', - }], - - /** @override */ - featureList: ['', 'features::kMaterialDesignExtensions'], - - /** - * Mock settings data. - * @private - */ - settings_: { - apps: [ - { - id: 'app_1', - name: 'App1 Name', - iconURL: '', - autoLaunch: false, - isLoading: false, - }, - { - id: 'app_2', - name: '', // no name - iconURL: '', - autoLaunch: false, - isLoading: true, - }, - ], - disableBailout: false, - hasAutoLaunchApp: false - }, - - /** - * Register a mock dictionary handler. - */ - preLoad: function() { - this.makeAndRegisterMockHandler( - ['getKioskAppSettings', - 'addKioskApp', - 'removeKioskApp', - 'enableKioskAutoLaunch', - 'disableKioskAutoLaunch' - ]); - this.mockHandler.stubs().getKioskAppSettings(ANYTHING).will( - callFunction(function() { - extensions.KioskAppsOverlay.setSettings(this.settings_); - }.bind(this))); - this.mockHandler.stubs().addKioskApp(ANYTHING); - this.mockHandler.stubs().removeKioskApp(ANYTHING); - this.mockHandler.stubs().enableKioskAutoLaunch(ANYTHING); - this.mockHandler.stubs().disableKioskAutoLaunch(ANYTHING); - }, - - setUp: function() { - // Shows the kiosk apps management overlay. - cr.dispatchSimpleEvent($('add-kiosk-app'), 'click'); - } -}; - -// Test opening kiosk app settings has correct location and app items have -// correct label. -TEST_F('KioskAppSettingsWebUITest', 'testOpenKioskAppSettings', function() { - assertEquals(this.browsePreload, document.location.href); - - var appItems = $('kiosk-app-list').items; - assertEquals(this.settings_.apps.length, appItems.length); - assertEquals(this.settings_.apps[0].name, appItems[0].name.textContent); - assertFalse(appItems[0].icon.classList.contains('spinner')); - assertEquals(this.settings_.apps[1].id, appItems[1].name.textContent); - assertTrue(appItems[1].icon.classList.contains('spinner')); -}); - -// Verify that enter key on 'kiosk-app-id-edit' adds an app. -TEST_F('KioskAppSettingsWebUITest', 'testAddKioskApp', function() { - var testAppId = 'app_3'; - var appIdInput = $('kiosk-app-id-edit'); - - appIdInput.value = testAppId; - - this.mockHandler.expects(once()).addKioskApp([testAppId]); - var keypress = new KeyboardEvent('keypress', {cancelable: true, bubbles: true, key: 'Enter'}); - appIdInput.dispatchEvent(keypress); -}); - -// Verify that the 'kiosk-app-add' button adds an app. -TEST_F('KioskAppSettingsWebUITest', 'testAddKioskAppByAddButton', function() { - var testAppId = 'app_3'; - $('kiosk-app-id-edit').value = testAppId; - - this.mockHandler.expects(once()).addKioskApp([testAppId]); - cr.dispatchSimpleEvent($('kiosk-app-add'), 'click'); -}); - -// Verify that the 'done' button adds an app. -TEST_F('KioskAppSettingsWebUITest', 'testAddKioskAppByDoneButton', function() { - var testAppId = 'app_3'; - $('kiosk-app-id-edit').value = testAppId; - - this.mockHandler.expects(once()).addKioskApp([testAppId]); - cr.dispatchSimpleEvent($('kiosk-options-overlay-confirm'), 'click'); -}); - -// Test the row delete button. -TEST_F('KioskAppSettingsWebUITest', 'testRemoveKioskApp', function() { - var appItem = $('kiosk-app-list').items[0]; - var appId = appItem.data.id; - - this.mockHandler.expects(once()).removeKioskApp([appId]); - appItem.querySelector('.row-delete-button').click(); -}); - -// Test enable/disable auto launch buttons. -TEST_F('KioskAppSettingsWebUITest', 'testEnableDisableAutoLaunch', function() { - var appItem = $('kiosk-app-list').items[0]; - var appId = appItem.data.id; - - var enableAutoLaunchCalled = false; - this.mockHandler.expects(once()).enableKioskAutoLaunch([appId]). - will(callFunction(function() { - enableAutoLaunchCalled = true; - })); - appItem.querySelector('.enable-auto-launch-button').click(); - expectTrue(enableAutoLaunchCalled); - - var disableAutoLaunchCalled = false; - this.mockHandler.expects(once()).disableKioskAutoLaunch([appId]). - will(callFunction(function() { - disableAutoLaunchCalled = true; - })); - appItem.querySelector('.disable-auto-launch-button').click(); - expectTrue(disableAutoLaunchCalled); -}); - -// Verify that updateApp updates app info. -TEST_F('KioskAppSettingsWebUITest', 'testUpdateApp', function() { - var appItems = $('kiosk-app-list').items; - assertEquals(appItems[1].data.id, 'app_2'); - expectEquals(appItems[1].data.name, ''); - expectTrue(appItems[1].icon.classList.contains('spinner')); - expectFalse(appItems[1].autoLaunch); - - // New data changes name, autoLaunch and isLoading. - var newName = 'Name for App2'; - var newApp2 = { - id: 'app_2', - name: newName, - iconURL: '', - autoLaunch: true, - isLoading: false, - }; - extensions.KioskAppsOverlay.updateApp(newApp2); - - assertEquals('app_2', appItems[1].data.id); - expectEquals(newName, appItems[1].data.name, newName); - expectEquals(newName, appItems[1].name.textContent); - expectFalse(appItems[1].icon.classList.contains('spinner')); - expectTrue(appItems[1].autoLaunch); -}); - -// Verify that showError makes error banner visible. -TEST_F('KioskAppSettingsWebUITest', 'testShowError', function() { - extensions.KioskAppsOverlay.showError('A bad app'); - expectTrue($('kiosk-apps-error-banner').classList.contains('visible')); -}); - -// Verify that checking disable bailout checkbox brings up confirmation UI and -// the check only remains when the confirmation UI is acknowledged. -TEST_F('KioskAppSettingsWebUITest', 'testCheckDisableBailout', function() { - var checkbox = $('kiosk-disable-bailout-shortcut'); - var confirmOverlay = $('kiosk-disable-bailout-confirm-overlay'); - expectFalse(confirmOverlay.classList.contains('showing')); - - // Un-checking the box does not trigger confirmation. - checkbox.checked = false; - cr.dispatchSimpleEvent(checkbox, 'change'); - expectFalse(confirmOverlay.classList.contains('showing')); - - // Checking the box trigger confirmation. - checkbox.checked = true; - cr.dispatchSimpleEvent(checkbox, 'change'); - expectTrue(confirmOverlay.classList.contains('showing')); - - // Confirm it and the check remains. - cr.dispatchSimpleEvent($('kiosk-disable-bailout-confirm-button'), 'click'); - expectTrue(checkbox.checked); - expectFalse(confirmOverlay.classList.contains('showing')); - - // And canceling resets the check. - checkbox.checked = true; - cr.dispatchSimpleEvent(checkbox, 'change'); - expectTrue(confirmOverlay.classList.contains('showing')); - cr.dispatchSimpleEvent($('kiosk-disable-bailout-cancel-button'), 'click'); - expectFalse(checkbox.checked); - expectFalse(confirmOverlay.classList.contains('showing')); -}); - -// Verify that disable bailout checkbox is hidden without kiosk auto launch. -TEST_F('KioskAppSettingsWebUITest', 'testHideDisableBailout', function() { - var checkbox = $('kiosk-disable-bailout-shortcut'); - var kioskEnabledSettings = { - kioskEnabled: true, - autoLaunchEnabled: true - }; - extensions.KioskAppsOverlay.enableKiosk(kioskEnabledSettings); - expectFalse(checkbox.parentNode.hidden); - - kioskEnabledSettings.autoLaunchEnabled = false; - extensions.KioskAppsOverlay.enableKiosk(kioskEnabledSettings); - expectTrue(checkbox.parentNode.hidden); -}); - -// Verify that disable bailout checkbox is disabled with no auto launch app. -TEST_F('KioskAppSettingsWebUITest', 'testAllowDisableBailout', function() { - var checkbox = $('kiosk-disable-bailout-shortcut'); - - this.settings_.hasAutoLaunchApp = false; - extensions.KioskAppsOverlay.setSettings(this.settings_); - expectTrue(checkbox.disabled); - - this.settings_.hasAutoLaunchApp = true; - extensions.KioskAppsOverlay.setSettings(this.settings_); - expectFalse(checkbox.disabled); -}); - -/** - * TestFixture for kiosk app settings when consumer kiosk is disabled. - * @extends {testing.Test} - * @constructor - */ -function NoConsumerKioskWebUITest() {} - -NoConsumerKioskWebUITest.prototype = { - __proto__: KioskAppSettingsWebUITest.prototype, - - /** @override */ - commandLineSwitches: [], - - /** @override */ - setUp: function() {} -}; - -// Test kiosk app settings are not visible when consumer kiosk is disabled. -TEST_F('NoConsumerKioskWebUITest', 'settingsHidden', function() { - assertEquals(this.browsePreload, document.location.href); - assertTrue($('add-kiosk-app').hidden); -});
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js deleted file mode 100644 index 7d4bef5..0000000 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js +++ /dev/null
@@ -1,539 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(dbeam): test for loading unpacked extensions? - -GEN('#include "chrome/browser/ui/webui/extensions/' + - 'extension_settings_browsertest.h"'); -GEN('#include "chrome/common/chrome_features.h"'); - -// The id of the extension from |InstallGoodExtension|. -var GOOD_EXTENSION_ID = 'ldnnhddmnhbkjipkidpdiheffobcpfmf'; - -// The id of the extension from |InstallErrorsExtension|. -var ERROR_EXTENSION_ID = 'pdlpifnclfacjobnmbpngemkalkjamnf'; - -/** - * Test C++ fixture for settings WebUI testing. - * @constructor - * @extends {testing.Test} - */ -function ExtensionSettingsUIBrowserTest() {} - -/** - * TestFixture for extension settings WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function ExtensionSettingsWebUITest() {} - -ExtensionSettingsWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - isAsync: true, - - /** @override */ - runAccessibilityChecks: true, - - /** @override */ - accessibilityIssuesAreErrors: true, - - /** - * A URL to load before starting each test. - * @type {string} - * @const - */ - browsePreload: 'chrome://extensions/', - - /** @override */ - typedefCppFixture: 'ExtensionSettingsUIBrowserTest', - - /** @override */ - featureList: ['', 'features::kMaterialDesignExtensions'], - - /** @override */ - setUp: function() { - testing.Test.prototype.setUp.call(this); - testing.Test.disableAnimationsAndTransitions(); - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/560903 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - '#kiosk-app-list'); - }, - - /** - * Holds an array of steps that should happen in order during a test. - * The last step should be |testDone|. - * @protected {Array<!Function>} - * */ - steps: [], - - /** - * Advances to the next step in the test. Every step should call this. - * @protected - * */ - nextStep: function() { - assertTrue(this.steps.length > 0); - this.steps.shift().call(this); - }, - - /** - * Will wait for the page to load before calling the next step. This should be - * the first step in every test. - * @protected - * */ - waitForPageLoad: function() { - assertEquals(this.browsePreload, document.location.href); - var extensionList = getRequiredElement('extension-settings-list'); - extensionList.loadFinished.then(this.nextStep.bind(this)); - }, - - /** @protected */ - enableDeveloperMode: function() { - // Toggling developer mode triggers a page update, so we need to be able to - // wait for the update to finish. - $('extension-settings-list').resetLoadFinished(); - var waitForPage = this.waitForPageLoad.bind(this); - document.addEventListener('devControlsVisibilityUpdated', - function devCallback() { - // Callback should only be handled once. - document.removeEventListener('devControlsVisibilityUpdated', devCallback); - - chrome.developerPrivate.getProfileConfiguration(function(profileInfo) { - assertTrue(extensionSettings.classList.contains('dev-mode')); - assertTrue(profileInfo.inDeveloperMode); - - // This event isn't thrown because transitions are disabled. - // Ensure transition here so that any dependent code does not break. - ensureTransitionEndEvent($('dev-controls'), 0); - - waitForPage(); - }); - }); - - var extensionSettings = getRequiredElement('extension-settings'); - assertFalse(extensionSettings.classList.contains('dev-mode')); - $('toggle-dev-on').click(); - }, - - /** @protected */ - testDeveloperMode: function() { - var next = this.nextStep.bind(this); - var checkDevModeIsOff = function() { - chrome.developerPrivate.getProfileConfiguration(function(profileInfo) { - assertFalse(profileInfo.inDeveloperMode); - next(); - }); - }; - this.steps = [this.waitForPageLoad, - checkDevModeIsOff, - this.enableDeveloperMode, - testDone]; - this.nextStep(); - }, -}; - -// Flaky: http://crbug.com/505506. -// Verify that developer mode doesn't change behavior when the number of -// extensions changes. -TEST_F('ExtensionSettingsWebUITest', 'DISABLED_testDeveloperModeNoExtensions', - function() { - this.testDeveloperMode(); -}); - -TEST_F('ExtensionSettingsWebUITest', 'testEmptyExtensionList', function() { - var verifyListIsHiddenAndEmpty = function() { - assertTrue($('extension-list-wrapper').hidden); - assertFalse($('no-extensions').hidden); - assertEquals(0, $('extension-settings-list').childNodes.length); - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, verifyListIsHiddenAndEmpty, testDone]; - this.nextStep(); -}); - -TEST_F('ExtensionSettingsWebUITest', 'testChromeSendHandled', function() { - var testPackExtenion = function() { - // This dialog should be hidden at first. - assertFalse($('pack-extension-overlay').classList.contains('showing')); - - // Show the dialog, which triggers a chrome.send() for metrics purposes. - cr.dispatchSimpleEvent($('pack-extension'), 'click'); - assertTrue($('pack-extension-overlay').classList.contains('showing')); - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, testPackExtenion, testDone]; - this.nextStep(); -}); - -/** - * @param {chrome.developerPrivate.EventType} eventType - * @param {function():void} callback - * @constructor - */ -function UpdateListener(eventType, callback) { - this.callback_ = callback; - this.eventType_ = eventType; - this.onItemStateChangedListener_ = this.onItemStateChanged_.bind(this); - chrome.developerPrivate.onItemStateChanged.addListener( - this.onItemStateChangedListener_); -} - -UpdateListener.prototype = { - /** @private */ - onItemStateChanged_: function(data) { - if (this.eventType_ == data.event_type) { - window.setTimeout(function() { - chrome.developerPrivate.onItemStateChanged.removeListener( - this.onItemStateChangedListener_); - this.callback_(); - }.bind(this), 0); - } - } -}; - -function BasicExtensionSettingsWebUITest() {} - -BasicExtensionSettingsWebUITest.prototype = { - __proto__: ExtensionSettingsWebUITest.prototype, - - /** @override */ - testGenPreamble: function() { - // Install multiple types of extensions to ensure we handle each type. - // TODO(devlin): There are more types to add here. - GEN(' InstallGoodExtension();'); - GEN(' InstallErrorsExtension();'); - GEN(' InstallSharedModule();'); - GEN(' InstallPackagedApp();'); - - GEN(' SetAutoConfirmUninstall();'); - }, - - /** @protected */ - verifyDisabledWorks: function() { - var listener = new UpdateListener( - chrome.developerPrivate.EventType.UNLOADED, - function() { - var node = getRequiredElement(GOOD_EXTENSION_ID); - assertTrue(node.classList.contains('inactive-extension')); - this.nextStep(); - }.bind(this)); - chrome.management.setEnabled(GOOD_EXTENSION_ID, false); - }, - - /** @protected */ - verifyEnabledWorks: function() { - var listener = new UpdateListener( - chrome.developerPrivate.EventType.LOADED, - function() { - var node = getRequiredElement(GOOD_EXTENSION_ID); - assertFalse(node.classList.contains('inactive-extension')); - this.nextStep(); - }.bind(this)); - chrome.management.setEnabled(GOOD_EXTENSION_ID, true); - }, - - /** @protected */ - verifyUninstallWorks: function() { - var listener = new UpdateListener( - chrome.developerPrivate.EventType.UNINSTALLED, - function() { - assertEquals(null, $(GOOD_EXTENSION_ID)); - this.nextStep(); - }.bind(this)); - chrome.test.runWithUserGesture(function() { - chrome.management.uninstall(GOOD_EXTENSION_ID); - }); - }, -}; - -// Verify that developer mode doesn't change behavior when the number of -// extensions changes. -TEST_F('BasicExtensionSettingsWebUITest', 'testDeveloperModeManyExtensions', - function() { - this.testDeveloperMode(); -}); - -TEST_F('BasicExtensionSettingsWebUITest', 'testDisable', function() { - this.steps = [this.waitForPageLoad, this.verifyDisabledWorks, testDone]; - this.nextStep(); -}); - -TEST_F('BasicExtensionSettingsWebUITest', 'testEnable', function() { - this.steps = [this.waitForPageLoad, - this.verifyDisabledWorks, - this.verifyEnabledWorks, - testDone]; - this.nextStep(); -}); - -TEST_F('BasicExtensionSettingsWebUITest', 'testUninstall', function() { - this.steps = [this.waitForPageLoad, this.verifyUninstallWorks, testDone]; - this.nextStep(); -}); - -TEST_F('BasicExtensionSettingsWebUITest', 'testNonEmptyExtensionList', - function() { - var verifyListIsNotHiddenAndEmpty = function() { - assertFalse($('extension-list-wrapper').hidden); - assertTrue($('no-extensions').hidden); - assertGT($('extension-settings-list').childNodes.length, 0); - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, verifyListIsNotHiddenAndEmpty, testDone]; - this.nextStep(); -}); - -function AutoScrollExtensionSettingsWebUITest() {} - -/** - * A variation for testing auto-scroll when an id query param is passed in the - * url. - * @constructor - * @extends {BasicExtensionSettingsWebUITest} - */ -AutoScrollExtensionSettingsWebUITest.prototype = { - __proto__: BasicExtensionSettingsWebUITest.prototype, - - /** @override */ - browsePreload: 'chrome://extensions/?id=' + GOOD_EXTENSION_ID, - - /** @override */ - testGenPreamble: function() { - BasicExtensionSettingsWebUITest.prototype.testGenPreamble.call(this); - // The window needs to be sufficiently small in order to ensure a scroll bar - // is available. - GEN(' ShrinkWebContentsView();'); - }, -}; - -TEST_F('AutoScrollExtensionSettingsWebUITest', 'testAutoScroll', function() { - var checkHasScrollbar = function() { - assertGT(document.scrollingElement.scrollHeight, - document.body.clientHeight); - this.nextStep(); - }; - var checkIsScrolled = function() { - assertGT(document.scrollingElement.scrollTop, 0); - this.nextStep(); - }; - var checkScrolledToTop = function() { - assertEquals(0, document.scrollingElement.scrollTop); - this.nextStep(); - }; - var scrollToTop = function() { - document.scrollingElement.scrollTop = 0; - this.nextStep(); - }; - // Test that a) autoscroll works on first page load and b) updating the - // page doesn't result in autoscroll triggering again. - this.steps = [this.waitForPageLoad, - checkHasScrollbar, - checkIsScrolled, - scrollToTop, - this.enableDeveloperMode, - checkScrolledToTop, - testDone]; - this.nextStep(); -}); - -function ErrorConsoleExtensionSettingsWebUITest() {} - -ErrorConsoleExtensionSettingsWebUITest.prototype = { - __proto__: ExtensionSettingsWebUITest.prototype, - - /** @override */ - testGenPreamble: function() { - GEN(' EnableErrorConsole();'); - GEN(' InstallGoodExtension();'); - GEN(' InstallErrorsExtension();'); - }, -}; - -// Flaky on all platforms: http://crbug.com/499884, http://crbug.com/463245. -TEST_F('ErrorConsoleExtensionSettingsWebUITest', - 'DISABLED_testErrorListButtonVisibility', function() { - var testButtonVisibility = function() { - var extensionList = $('extension-list-wrapper'); - - var visibleButtons = extensionList.querySelectorAll( - '.errors-link:not([hidden])'); - expectEquals(1, visibleButtons.length); - - if (visibleButtons.length > 0) { - var errorLink = $(ERROR_EXTENSION_ID).querySelector('.errors-link'); - expectEquals(visibleButtons[0], errorLink); - - var errorIcon = errorLink.querySelector('img'); - expectTrue(errorIcon.classList.contains('extension-error-warning-icon')); - } - - var hiddenButtons = extensionList.querySelectorAll('.errors-link[hidden]'); - expectEquals(1, hiddenButtons.length); - - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, - this.enableDeveloperMode, - testButtonVisibility, - testDone]; - this.nextStep(); -}); - -/** - * TestFixture for extension settings WebUI testing (commands config edition). - * @extends {testing.Test} - * @constructor - */ -function SettingsCommandsExtensionSettingsWebUITest() {} - -SettingsCommandsExtensionSettingsWebUITest.prototype = { - __proto__: ExtensionSettingsWebUITest.prototype, - - /** - * A URL to load before starting each test. - * @type {string} - * @const - */ - browsePreload: 'chrome://extensions/configureCommands', -}; - -TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'testChromeSendHandler', - function() { - // Just navigating to the page should trigger the chrome.send(). - var assertOverlayVisible = function() { - assertTrue($('extension-commands-overlay').classList.contains('showing')); - assertEquals($('extension-commands-overlay').getAttribute('aria-hidden'), - 'false'); - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, assertOverlayVisible, testDone]; - this.nextStep(); -}); - -TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'extensionSettingsUri', - function() { - var closeCommandOverlay = function() { - assertTrue($('extension-commands-overlay').classList.contains('showing')); - assertEquals($('extension-commands-overlay').getAttribute('aria-hidden'), - 'false'); - assertEquals(window.location.href, 'chrome://extensions/configureCommands'); - - // Close command overlay. - $('extension-commands-dismiss').click(); - - assertFalse($('extension-commands-overlay').classList.contains('showing')); - assertEquals($('extension-commands-overlay').getAttribute('aria-hidden'), - 'true'); - this.nextStep(); - }; - - var checkExtensionsUrl = function() { - // After closing the overlay, the URL shouldn't include commands overlay - // reference. - assertEquals(window.location.href, 'chrome://extensions/'); - this.nextStep(); - }; - - this.steps = [this.waitForPageLoad, - closeCommandOverlay, - checkExtensionsUrl, - testDone]; - this.nextStep(); -}); - -/** - * @constructor - * @extends {ExtensionSettingsWebUITest} - */ -function InstallGoodExtensionSettingsWebUITest() {} - -InstallGoodExtensionSettingsWebUITest.prototype = { - __proto__: ExtensionSettingsWebUITest.prototype, - - /** @override */ - testGenPreamble: function() { - GEN(' InstallGoodExtension();'); - }, - - emptyTestForAccessibility() { - this.steps = [this.waitForPageLoad, testDone]; - this.nextStep(); - }, -}; - -TEST_F('InstallGoodExtensionSettingsWebUITest', 'testAccessibility', - function() { - this.emptyTestForAccessibility(); -}); - -TEST_F('InstallGoodExtensionSettingsWebUITest', 'showOptions', function() { - var showExtensionOptions = function() { - var optionsOverlay = extensions.ExtensionOptionsOverlay.getInstance(); - optionsOverlay.setExtensionAndShow(GOOD_EXTENSION_ID, 'GOOD!', '', - this.nextStep.bind(this)); - - // Preferred size changes don't happen in browser tests. Just fake it. - document.querySelector('extensionoptions').onpreferredsizechanged( - {width: 500, height: 500}); - }; - - this.steps = [this.waitForPageLoad, showExtensionOptions, testDone]; - this.nextStep(); -}); - -/** - * @constructor - * @extends {InstallGoodExtensionSettingsWebUITest} - */ -function ManagedExtensionSettingsWebUITest() {} - -ManagedExtensionSettingsWebUITest.prototype = { - __proto__: InstallGoodExtensionSettingsWebUITest.prototype, - - /** @override */ - testGenPreamble: function() { - GEN(' AddManagedPolicyProvider();'); - InstallGoodExtensionSettingsWebUITest.prototype.testGenPreamble.call(this); - }, -}; - -TEST_F('ManagedExtensionSettingsWebUITest', 'testAccessibility', function() { - this.emptyTestForAccessibility(); -}); - -/** - * @constructor - * @extends {InstallGoodExtensionSettingsWebUITest} - */ -function OptionsDialogExtensionSettingsWebUITest() {} - -OptionsDialogExtensionSettingsWebUITest.prototype = { - __proto__: InstallGoodExtensionSettingsWebUITest.prototype, - - setUp() { - InstallGoodExtensionSettingsWebUITest.prototype.setUp.call(this); - - // False positive on iframe hosting the <extensionoptions> guest view. - this.accessibilityAuditConfig.ignoreSelectors( - 'focusableElementNotVisibleAndNotAriaHidden', 'iframe'); - }, - - /** @override */ - browsePreload: ExtensionSettingsWebUITest.prototype.browsePreload + - '?options=' + GOOD_EXTENSION_ID, -}; - -TEST_F('OptionsDialogExtensionSettingsWebUITest', 'testAccessibility', - function() { - this.emptyTestForAccessibility(); -});
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 207eb0e..0e6359f 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/ui/webui/extensions/extension_settings_handler.h" #include "chrome/browser/ui/webui/extensions/install_extension_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -54,8 +53,8 @@ class ExtensionWebUiTimer : public content::WebContentsObserver { public: - explicit ExtensionWebUiTimer(content::WebContents* web_contents, bool is_md) - : content::WebContentsObserver(web_contents), is_md_(is_md) {} + explicit ExtensionWebUiTimer(content::WebContents* web_contents) + : content::WebContentsObserver(web_contents) {} ~ExtensionWebUiTimer() override {} void DidStartNavigation( @@ -72,13 +71,8 @@ !timer_) { // See comment in DocumentOnLoadCompletedInMainFrame() return; } - if (is_md_) { - UMA_HISTOGRAM_TIMES("Extensions.WebUi.DocumentLoadedInMainFrameTime.MD", - timer_->Elapsed()); - } else { - UMA_HISTOGRAM_TIMES("Extensions.WebUi.DocumentLoadedInMainFrameTime.Uber", - timer_->Elapsed()); - } + UMA_HISTOGRAM_TIMES("Extensions.WebUi.DocumentLoadedInMainFrameTime.MD", + timer_->Elapsed()); } void DocumentOnLoadCompletedInMainFrame() override { @@ -89,22 +83,14 @@ // will receive this current callback. return; } - if (is_md_) { - UMA_HISTOGRAM_TIMES("Extensions.WebUi.LoadCompletedInMainFrame.MD", - timer_->Elapsed()); - } else { - UMA_HISTOGRAM_TIMES("Extensions.WebUi.LoadCompletedInMainFrame.Uber", - timer_->Elapsed()); - } + UMA_HISTOGRAM_TIMES("Extensions.WebUi.LoadCompletedInMainFrame.MD", + timer_->Elapsed()); timer_.reset(); } void WebContentsDestroyed() override { delete this; } private: - // Whether this is the MD version of the chrome://extensions page. - bool is_md_; - std::unique_ptr<base::ElapsedTimer> timer_; DISALLOW_COPY_AND_ASSIGN(ExtensionWebUiTimer); @@ -390,74 +376,31 @@ return source; } -content::WebUIDataSource* CreateExtensionsHTMLSource() { - content::WebUIDataSource* source = - content::WebUIDataSource::Create(chrome::kChromeUIExtensionsHost); - - source->SetJsonPath("strings.js"); - source->AddResourcePath("extensions.js", IDR_EXTENSIONS_JS); - source->AddResourcePath("extension_command_list.js", - IDR_EXTENSION_COMMAND_LIST_JS); - source->AddResourcePath("extension_list.js", IDR_EXTENSION_LIST_JS); - source->SetDefaultResource(IDR_EXTENSIONS_HTML); - source->DisableDenyXFrameOptions(); - return source; -} - } // namespace ExtensionsUI::ExtensionsUI(content::WebUI* web_ui) : WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource* source = nullptr; - bool is_md = - base::FeatureList::IsEnabled(features::kMaterialDesignExtensions); + in_dev_mode_.Init( + prefs::kExtensionsUIDeveloperMode, profile->GetPrefs(), + base::Bind(&ExtensionsUI::OnDevModeChanged, base::Unretained(this))); - if (is_md) { - in_dev_mode_.Init( - prefs::kExtensionsUIDeveloperMode, profile->GetPrefs(), - base::Bind(&ExtensionsUI::OnDevModeChanged, base::Unretained(this))); + source = CreateMdExtensionsSource(*in_dev_mode_); - source = CreateMdExtensionsSource(*in_dev_mode_); - - source->AddBoolean( - "isGuest", + source->AddBoolean( + "isGuest", #if defined(OS_CHROMEOS) - user_manager::UserManager::Get()->IsLoggedInAsGuest() || - user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()); + user_manager::UserManager::Get()->IsLoggedInAsGuest() || + user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()); #else - profile->IsOffTheRecord()); + profile->IsOffTheRecord()); #endif - auto install_extension_handler = - std::make_unique<InstallExtensionHandler>(); - InstallExtensionHandler* handler = install_extension_handler.get(); - web_ui->AddMessageHandler(std::move(install_extension_handler)); - handler->GetLocalizedValues(source); - } else { - source = CreateExtensionsHTMLSource(); - - auto extension_settings_handler = - std::make_unique<ExtensionSettingsHandler>(); - ExtensionSettingsHandler* settings_handler = - extension_settings_handler.get(); - web_ui->AddMessageHandler(std::move(extension_settings_handler)); - settings_handler->GetLocalizedValues(source); - - auto extension_loader_handler = - std::make_unique<ExtensionLoaderHandler>(profile); - ExtensionLoaderHandler* loader_handler = extension_loader_handler.get(); - web_ui->AddMessageHandler(std::move(extension_loader_handler)); - loader_handler->GetLocalizedValues(source); - - auto install_extension_handler = - std::make_unique<InstallExtensionHandler>(); - InstallExtensionHandler* install_handler = install_extension_handler.get(); - web_ui->AddMessageHandler(std::move(install_extension_handler)); - install_handler->GetLocalizedValues(source); - - web_ui->AddMessageHandler(std::make_unique<MetricsHandler>()); - } + auto install_extension_handler = std::make_unique<InstallExtensionHandler>(); + InstallExtensionHandler* handler = install_extension_handler.get(); + web_ui->AddMessageHandler(std::move(install_extension_handler)); + handler->GetLocalizedValues(source); #if defined(OS_CHROMEOS) auto kiosk_app_handler = std::make_unique<chromeos::KioskAppsHandler>( @@ -475,7 +418,7 @@ content::WebUIDataSource::Add(profile, source); // Handles its own lifetime. - new ExtensionWebUiTimer(web_ui->GetWebContents(), is_md); + new ExtensionWebUiTimer(web_ui->GetWebContents()); } ExtensionsUI::~ExtensionsUI() {}
diff --git a/chrome/browser/ui/webui/policy_tool_ui_browsertest.cc b/chrome/browser/ui/webui/policy_tool_ui_browsertest.cc index 3f812c1f..a740f55 100644 --- a/chrome/browser/ui/webui/policy_tool_ui_browsertest.cc +++ b/chrome/browser/ui/webui/policy_tool_ui_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" +#include "build/build_config.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h" @@ -261,7 +262,13 @@ return value->GetString(); } -IN_PROC_BROWSER_TEST_F(PolicyToolUITest, CreatingSessionFiles) { +// Flaky on Win buildbots. See crbug.com/832673. +#if defined(OS_WIN) +#define MAYBE_CreatingSessionFiles DISABLED_CreatingSessionFiles +#else +#define MAYBE_CreatingSessionFiles CreatingSessionFiles +#endif +IN_PROC_BROWSER_TEST_F(PolicyToolUITest, MAYBE_CreatingSessionFiles) { base::ScopedAllowBlockingForTesting allow_blocking; // Check that the directory is not created yet. EXPECT_FALSE(PathExists(GetSessionsDir()));
diff --git a/chrome/browser/vr/elements/vector_icon.cc b/chrome/browser/vr/elements/vector_icon.cc index 3ffdda2d..0570a5d 100644 --- a/chrome/browser/vr/elements/vector_icon.cc +++ b/chrome/browser/vr/elements/vector_icon.cc
@@ -22,13 +22,11 @@ SkColor GetColor() const { return color_; } - void SetIcon(const gfx::VectorIcon* icon) { - SetAndDirty(&icon_no_1x_.rep, icon ? icon->rep : nullptr); - } + void SetIcon(const gfx::VectorIcon* icon) { SetAndDirty(&icon_, icon); } private: void Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) override { - if (icon_no_1x_.is_empty()) + if (icon_ == nullptr || icon_->is_empty()) return; cc::SkiaPaintCanvas paint_canvas(sk_canvas); gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); @@ -39,12 +37,12 @@ float icon_size = size_.height(); float icon_corner_offset = (size_.height() - icon_size) / 2; VectorIcon::DrawVectorIcon( - &gfx_canvas, icon_no_1x_, icon_size, + &gfx_canvas, *icon_, icon_size, gfx::PointF(icon_corner_offset, icon_corner_offset), color_); } gfx::SizeF size_; - gfx::VectorIcon icon_no_1x_{}; + const gfx::VectorIcon* icon_ = nullptr; SkColor color_ = SK_ColorWHITE; DISALLOW_COPY_AND_ASSIGN(VectorIconTexture); }; @@ -91,12 +89,9 @@ canvas->Translate( {static_cast<int>(corner.x()), static_cast<int>(corner.y())}); - // Explicitly cut out the 1x version of the icon, as PaintVectorIcon draws the - // 1x version if device scale factor isn't set. See crbug.com/749146. If all - // icons end up being drawn via VectorIcon instances, this will not be - // required (the 1x version is automatically elided by this class). - gfx::VectorIcon icon_no_1x{icon.rep}; - PaintVectorIcon(canvas, icon_no_1x, size_px, color); + // Don't use CreateVectorIcon() because its icon caching is not thread safe. + // Instead, just redraw the VectorIcon. + PaintVectorIcon(canvas, icon, size_px, color); } } // namespace vr
diff --git a/chrome/browser/vr/elements/vector_icon_unittest.cc b/chrome/browser/vr/elements/vector_icon_unittest.cc index bf802c0..b1bd0bcf 100644 --- a/chrome/browser/vr/elements/vector_icon_unittest.cc +++ b/chrome/browser/vr/elements/vector_icon_unittest.cc
@@ -40,7 +40,7 @@ TEST(VectorIcon, SmokeTest) { UiScene scene; auto icon = std::make_unique<TestVectorIcon>(kMaximumWidth); - icon->SetIcon(vector_icons::kClose16Icon); + icon->SetIcon(vector_icons::kCloseRoundedIcon); UiTexture* texture = icon->GetTexture(); scene.AddUiElement(kRoot, std::move(icon)); base::TimeTicks start_time = MsToTicks(1);
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index be727494..1d0cf4ce5 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1382,7 +1382,7 @@ Create<DiscButton>(kWebVrTimeoutMessageButton, kPhaseForeground, base::BindRepeating(&UiBrowserInterface::ExitPresent, base::Unretained(browser_)), - vector_icons::kClose16Icon, audio_delegate_); + vector_icons::kCloseRoundedIcon, audio_delegate_); button->SetVisible(false); button->SetTranslate(0, -kTimeoutMessageTextWidthDMM, 0); button->SetRotate(1, 0, 0, kTimeoutButtonRotationRad); @@ -1645,7 +1645,7 @@ kSpeechRecognitionListeningCloseButton, kPhaseForeground, base::BindRepeating(&UiBrowserInterface::SetVoiceSearchActive, base::Unretained(browser_), false), - vector_icons::kClose16Icon, audio_delegate_); + vector_icons::kCloseRoundedIcon, audio_delegate_); close_button->SetSize(kVoiceSearchCloseButtonDiameter, kVoiceSearchCloseButtonDiameter); close_button->set_hover_offset(kButtonZOffsetHoverDMM * kContentDistance); @@ -2585,7 +2585,7 @@ base::Unretained(model_), base::Unretained(browser_)); std::unique_ptr<DiscButton> element = Create<DiscButton>(kCloseButton, kPhaseForeground, click_handler, - vector_icons::kClose16Icon, audio_delegate_); + vector_icons::kCloseRoundedIcon, audio_delegate_); element->set_contributes_to_parent_bounds(false); element->SetSize(kCloseButtonDiameter, kCloseButtonDiameter); element->set_hover_offset(kButtonZOffsetHoverDMM * kCloseButtonDistance);
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 133b262..419a94a 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -385,7 +385,7 @@ // Enables media content bitstream remoting, an optimization that can activate // during Cast Tab Mirroring. const base::Feature kMediaRemoting{"MediaRemoting", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #endif // !defined(OS_ANDROID) // Enables or disables modal permission prompts.
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 0206f7f..1bcc9f9 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -15,10 +15,18 @@ "channel": "stable", "extension_types": ["extension", "platform_app"] }, - "accessibilityFeatures.read": { + "accessibilityFeatures.read": [{ "channel": "stable", "extension_types": ["extension", "platform_app"] - }, + }, { + "channel": "stable", + "extension_types": ["legacy_packaged_app"], + "platforms": ["chromeos"], + "whitelist": [ + "0EA6B717932AD64C469C1CCB6911457733295907", // http://crbug.com/835115 + "58B0C2968C335964D5433E89CA4D86628A0E3D4B" // http://crbug.com/835115 + ] + }], "accessibilityPrivate": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl index 8e27ac3..8d98e48 100644 --- a/chrome/common/extensions/api/automation.idl +++ b/chrome/common/extensions/api/automation.idl
@@ -285,7 +285,11 @@ /** * This node was removed. */ - nodeRemoved + nodeRemoved, + /** + * This subtree has finished an update. + */ + subtreeUpdateEnd }; // Where the node's name is from.
diff --git a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc index 4373161..dfe44a7b 100644 --- a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -202,8 +202,15 @@ if (!tree_.Unserialize(params.update)) return false; - if (is_active_profile) + if (is_active_profile) { owner_->SendNodesRemovedEvent(&tree_, deleted_node_ids_); + + ui::AXNode* target = tree_.GetFromId(params.id); + if (target) { + owner_->SendTreeChangeEvent( + api::automation::TREE_CHANGE_TYPE_SUBTREEUPDATEEND, &tree_, target); + } + } } // Exit early if this isn't the active profile.
diff --git a/chrome/renderer/extensions/tabs_hooks_delegate_unittest.cc b/chrome/renderer/extensions/tabs_hooks_delegate_unittest.cc index 368614f..45170ed9 100644 --- a/chrome/renderer/extensions/tabs_hooks_delegate_unittest.cc +++ b/chrome/renderer/extensions/tabs_hooks_delegate_unittest.cc
@@ -110,6 +110,9 @@ tester.TestConnect("4, {name: 'channel'}", "channel", MessageTarget::ForTab(4, messaging_util::kNoFrameId), kExpectIncludeTlsChannelId); + tester.TestConnect("9, {frameId: null}", "", + MessageTarget::ForTab(9, messaging_util::kNoFrameId), + kExpectIncludeTlsChannelId); tester.TestConnect("9, {frameId: 16}", "", MessageTarget::ForTab(9, 16), kExpectIncludeTlsChannelId); tester.TestConnect("25, {}", "", @@ -141,6 +144,10 @@ tester.TestSendMessage("1, {data: 'hello'}, function() {}", kStandardMessage, MessageTarget::ForTab(1, messaging_util::kNoFrameId), kExpectIncludeTlsChannelId, SendMessageTester::OPEN); + tester.TestSendMessage("1, {data: 'hello'}, {frameId: null}", + kStandardMessage, + MessageTarget::ForTab(1, messaging_util::kNoFrameId), + kExpectIncludeTlsChannelId, SendMessageTester::CLOSED); tester.TestSendMessage("1, {data: 'hello'}, {frameId: 10}", kStandardMessage, MessageTarget::ForTab(1, 10), kExpectIncludeTlsChannelId, SendMessageTester::CLOSED);
diff --git a/chrome/services/media_gallery_util/media_metadata_parser.cc b/chrome/services/media_gallery_util/media_metadata_parser.cc index edeace4..ae99a20 100644 --- a/chrome/services/media_gallery_util/media_metadata_parser.cc +++ b/chrome/services/media_gallery_util/media_metadata_parser.cc
@@ -62,12 +62,12 @@ it != extractor.stream_infos().end(); ++it) { chrome::mojom::MediaStreamInfoPtr stream_info = chrome::mojom::MediaStreamInfo::New( - it->type, std::make_unique<base::DictionaryValue>()); + it->type, base::Value(base::Value::Type::DICTIONARY)); for (std::map<std::string, std::string>::const_iterator tag_it = it->tags.begin(); tag_it != it->tags.end(); ++tag_it) { - stream_info->additional_properties->SetKey(tag_it->first, - base::Value(tag_it->second)); + stream_info->additional_properties.SetKey(tag_it->first, + base::Value(tag_it->second)); } metadata->raw_tags.push_back(std::move(stream_info)); }
diff --git a/chrome/services/media_gallery_util/public/mojom/BUILD.gn b/chrome/services/media_gallery_util/public/mojom/BUILD.gn index 2bc6cbc8..bfe58641 100644 --- a/chrome/services/media_gallery_util/public/mojom/BUILD.gn +++ b/chrome/services/media_gallery_util/public/mojom/BUILD.gn
@@ -11,7 +11,6 @@ ] public_deps = [ - "//mojo/common:common_custom_types", "//mojo/public/mojom/base", ] }
diff --git a/chrome/services/media_gallery_util/public/mojom/media_parser.mojom b/chrome/services/media_gallery_util/public/mojom/media_parser.mojom index 3dbbde5..e893c9b 100644 --- a/chrome/services/media_gallery_util/public/mojom/media_parser.mojom +++ b/chrome/services/media_gallery_util/public/mojom/media_parser.mojom
@@ -4,9 +4,9 @@ module chrome.mojom; -import "mojo/common/values.mojom"; import "mojo/public/mojom/base/file.mojom"; import "mojo/public/mojom/base/time.mojom"; +import "mojo/public/mojom/base/values.mojom"; interface MediaParser { // Extracts metadata from media data with |mime_type|, |total_size| and @@ -57,7 +57,7 @@ string type; // A string->string dictionary of tags for the media stream. - mojo.common.mojom.DictionaryValue additional_properties; + mojo_base.mojom.DictionaryValue additional_properties; }; // All data are parsed from user-defined media data. The consumer of this API should filter special
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 680fc92..d70ec3b 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -37,8 +37,6 @@ "../../../browser/ui/webui/chromeos/bluetooth_pairing_dialog_browsertest.js", "../../../browser/ui/webui/chromeos/certificate_manager_dialog_browsertest.js", "../../../browser/ui/webui/chromeos/set_time_ui_browsertest.js", - "../../../browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js", - "../../../browser/ui/webui/extensions/extension_settings_browsertest.js", "../../../browser/ui/webui/identity_internals_ui_browsertest.js", "../../../browser/ui/webui/sync_internals_browsertest.js", "../chromeos/oobe_webui_browsertest.js", @@ -119,6 +117,7 @@ if (is_chromeos) { sources += [ + "multidevice_setup/multidevice_setup_browsertest.js", "settings/easy_unlock_browsertest_chromeos.js", "sys_internals/sys_internals_browsertest.js", ]
diff --git a/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js b/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js new file mode 100644 index 0000000..4ec44bf --- /dev/null +++ b/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js
@@ -0,0 +1,38 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** @fileoverview Tests for MultiDevice unified setup WebUI. */ + +GEN('#if defined(OS_CHROMEOS)'); + +/** @const {string} Path to source root. */ +var ROOT_PATH = '../../../../../'; + +// Polymer BrowserTest fixture. +GEN_INCLUDE( + [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']); + +/** + * Test fixture for MultiDeviceSetup elements. + * @constructor + * @extends {PolymerTest} + */ +function MultiDeviceSetupBrowserTest() {} + +MultiDeviceSetupBrowserTest.prototype = { + __proto__: PolymerTest.prototype, + + browsePreload: 'chrome://multidevice-setup/', + + extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([ + 'navigation_test.js', + ]), +}; + +TEST_F('MultiDeviceSetupBrowserTest', 'All', function() { + multidevice_setup.registerTests(); + mocha.run(); +}); + +GEN('#endif');
diff --git a/chrome/test/data/webui/multidevice_setup/navigation_test.js b/chrome/test/data/webui/multidevice_setup/navigation_test.js new file mode 100644 index 0000000..438bb2b --- /dev/null +++ b/chrome/test/data/webui/multidevice_setup/navigation_test.js
@@ -0,0 +1,72 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Suite of tests for button navigation functionality in + * MultiDevice setup WebUI. + */ +cr.define('multidevice_setup', () => { + function registerTests() { + suite('MultiDeviceSetup', () => { + /** + * MultiDeviceSetup created before each test. + * @type {MultiDeviceSetup} + */ + let multiDeviceSetupElement; + + const FAILURE = 'setup-failed-page'; + const SUCCESS = 'setup-succeeded-page'; + const START = 'start-setup-page'; + + function tapForwardNavigation() { + MockInteractions.tap( + multiDeviceSetupElement.$$('button-bar').$.forward); + } + + function tapBackwardNavigation() { + MockInteractions.tap( + multiDeviceSetupElement.$$('button-bar').$.backward); + } + + setup(() => { + PolymerTest.clearBody(); + multiDeviceSetupElement = document.createElement('multidevice-setup'); + document.body.appendChild(multiDeviceSetupElement); + }); + + test( + 'Check SetupFailedPage forward button goes to start page', + done => { + multiDeviceSetupElement.visiblePageName_ = FAILURE; + multiDeviceSetupElement.addEventListener( + 'visible-page_-changed', function() { + if (multiDeviceSetupElement.visiblePage_ && + multiDeviceSetupElement.visiblePage_.is == START) { + done(); + } + }); + tapForwardNavigation(); + }); + + test('Check SetupFailedPage backward button closes UI', done => { + multiDeviceSetupElement.visiblePageName_ = FAILURE; + multiDeviceSetupElement.addEventListener('ui-closed', () => done()); + tapBackwardNavigation(); + }); + + test('Check SetupSucceededPage forward button closes UI', done => { + multiDeviceSetupElement.visiblePageName_ = SUCCESS; + multiDeviceSetupElement.addEventListener('ui-closed', () => done()); + tapForwardNavigation(); + }); + + test('Check StartSetupPage backward button closes UI', done => { + multiDeviceSetupElement.visiblePageName_ = START; + multiDeviceSetupElement.addEventListener('ui-closed', () => done()); + tapBackwardNavigation(); + }); + }); + } + return {registerTests: registerTests}; +});
diff --git a/chromecast/README.md b/chromecast/README.md index 1d2db418..5858c2a 100644 --- a/chromecast/README.md +++ b/chromecast/README.md
@@ -11,17 +11,14 @@ * If you are adding a new feature, add it to `cast_features.cc` so it lives alongside existing features - * Add registration of your new feature via `RegisterFeature(&feature)`. - You can add it to `RegisterFeatures()` so it lives with existing features + * Add your new feature to the list of `kFeatures` in `cast_features.cc` ```c++ const base::Feature kMyFeature{"my_feature", base::FEATURE_DISABLED_BY_DEFAULT}; -void RegisterFeatures() { - // ...other features - RegisterFeature(&kMyFeature); + +const base::Feature* kFeatures[] = { + // ..other features + &kMyFeature } ``` - - * If you are writing a unit test that touches code that reads your feature be - sure to call `RegisterFeaturesForTesting()` in your unit test constructor
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index 11d4149..0e96a5d 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -98,6 +98,12 @@ if (is_android) { deps += [ ":jni_headers" ] } + + if (chromecast_branding == "public") { + sources += [ "cast_features_internal.cc" ] + } else { + deps += [ "//chromecast/internal/base:cast_internal_features" ] + } } # chromecast related switch values
diff --git a/chromecast/base/cast_features.cc b/chromecast/base/cast_features.cc index fb4eb600..62acd77 100644 --- a/chromecast/base/cast_features.cc +++ b/chromecast/base/cast_features.cc
@@ -2,28 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chromecast/base/cast_features.h" + #include <algorithm> #include <utility> -#include "chromecast/base/cast_features.h" - #include "base/command_line.h" #include "base/feature_list.h" #include "base/lazy_instance.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_param_associator.h" #include "base/metrics/field_trial_params.h" +#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" namespace chromecast { namespace { - -// The mapping of feature names to features that have been registered -// LazyInstance -base::LazyInstance<std::vector<const base::Feature*>>::DestructorAtExit - g_features; - // A constant used to always activate a FieldTrial. const base::FieldTrial::Probability k100PercentProbability = 100; @@ -34,16 +29,10 @@ LAZY_INSTANCE_INITIALIZER; bool g_experiment_ids_initialized = false; -void ClearFeatures() { - g_features.Get().clear(); -} - -void RegisterFeatures() { - RegisterFeature(&kAllowUserMediaAccess); - RegisterFeature(&kEnableQuic); - RegisterFeature(&kTripleBuffer720); - RegisterFeature(&kSingleBuffer); - RegisterFeature(&kDisableIdleSocketsCloseOnMemoryPressure); +// The collection of features that have been registered by unit tests +std::vector<const base::Feature*>& GetTestFeatures() { + static base::NoDestructor<std::vector<const base::Feature*>> g_features_for_test; + return *g_features_for_test; } void SetExperimentIds(const base::ListValue& list) { @@ -125,11 +114,9 @@ // // --disable-features=enable_foo,enable_bar // -// 5) If you add a new feature to the system you must register the feature. +// 5) If you add a new feature to the system you must include it in kFeatures // This is because the system relies on knowing all of the features so -// it can properly iterate over all features to detect changes. You -// should register your feature via RegisterFeature(&feature) and most likely -// your feature registration should live in RegisterFeatures() function +// it can properly iterate over all features to detect changes. // // Begin Chromecast Feature definitions. @@ -157,12 +144,30 @@ base::FEATURE_DISABLED_BY_DEFAULT}; // End Chromecast Feature definitions. +const base::Feature* kFeatures[] = { + &kAllowUserMediaAccess, + &kEnableQuic, + &kTripleBuffer720, + &kSingleBuffer, + &kDisableIdleSocketsCloseOnMemoryPressure, +}; // An iterator for a base::DictionaryValue. Use an alias for brevity in loops. using Iterator = base::DictionaryValue::Iterator; -std::vector<const base::Feature*> GetFeatures() { - return g_features.Get(); +std::vector<const base::Feature*> GetInternalFeatures(); + +const std::vector<const base::Feature*>& GetFeatures() { + static const base::NoDestructor<std::vector<const base::Feature*>> features([] { + auto features = std::vector<const base::Feature*>( + kFeatures, kFeatures + sizeof(kFeatures) / sizeof(base::Feature*)); + auto internal_features = GetInternalFeatures(); + features.insert(features.end(), internal_features.begin(), internal_features.end()); + return features; + }()); + if (GetTestFeatures().size() > 0) + return GetTestFeatures(); + return *features; } void InitializeFeatureList(const base::DictionaryValue& dcs_features, @@ -171,8 +176,6 @@ const std::string& cmd_line_disable_features) { DCHECK(!base::FeatureList::GetInstance()); - RegisterFeatures(); - // Set the experiments. SetExperimentIds(dcs_experiment_ids); @@ -257,14 +260,10 @@ base::FeatureList::SetInstance(std::move(feature_list)); } -bool IsFeatureRegistered(const base::Feature& feature) { - std::vector<const base::Feature*> features = g_features.Get(); - auto it = std::find(features.begin(), features.end(), &feature); - return it != features.end(); -} - bool IsFeatureEnabled(const base::Feature& feature) { - DCHECK(IsFeatureRegistered(feature)) << feature.name; + DCHECK(std::find(GetFeatures().begin(), GetFeatures().end(), &feature) != + GetFeatures().end()) + << feature.name; return base::FeatureList::IsEnabled(feature); } @@ -322,26 +321,14 @@ return g_experiment_ids.Get(); } -void ClearFeaturesForTesting() { - ClearFeatures(); -} - -void RegisterFeature(const base::Feature* feature) { - DCHECK(!IsFeatureRegistered(*feature)) - << feature->name << " is already registered"; - g_features.Get().push_back(feature); -} - -void RegisterFeaturesForTesting() { - // Clear out all existing features. This is to prevent DCHECK failures - // for duplicate feature registration during testing - ClearFeatures(); - RegisterFeatures(); -} - void ResetCastFeaturesForTesting() { g_experiment_ids_initialized = false; base::FeatureList::ClearInstanceForTesting(); + GetTestFeatures().clear(); +} + +void SetFeaturesForTest(std::vector<const base::Feature*> features) { + GetTestFeatures() = std::move(features); } } // namespace chromecast
diff --git a/chromecast/base/cast_features.h b/chromecast/base/cast_features.h index 8853793..66d4bfd 100644 --- a/chromecast/base/cast_features.h +++ b/chromecast/base/cast_features.h
@@ -30,7 +30,7 @@ // Get an iterable list of all of the cast features for checking all features as // a collection. -std::vector<const base::Feature*> GetFeatures(); +const std::vector<const base::Feature*>& GetFeatures(); // Below are utilities needed by the Cast receiver to persist feature // information. Client code which is simply querying the status of a feature @@ -50,7 +50,7 @@ const std::string& cmd_line_disable_features); // Determine whether or not a feature is enabled. This replaces -// base::FeatureList::IsEnabled for Cast builds +// base::FeatureList::IsEnabled for Cast builds. bool IsFeatureEnabled(const base::Feature& feature); // Given a dictionary of features, create a copy that is ready to be persisted @@ -64,19 +64,13 @@ // thread. const std::unordered_set<int32_t>& GetDCSExperimentIds(); -// Remove all feature registrations. Required for certain test patterns -void ClearFeaturesForTesting(); - -// Register a feature. All instances of base::Feature within -// chromecast should be registered by calling this function. -void RegisterFeature(const base::Feature* feature); - -// Register all known features. For tests only. -void RegisterFeaturesForTesting(); - // Reset static state to ensure clean unittests. For tests only. void ResetCastFeaturesForTesting(); +// Set the response to GetFeatures(). Calls to this function should +// be cleaned up by a call to ResetCastFeaturesForTesting() otherwise +// your test will leak the overridden feature state. +void SetFeaturesForTest(std::vector<const base::Feature*> features); } // namespace chromecast #endif // CHROMECAST_BASE_CAST_FEATURES_H_
diff --git a/chromecast/base/cast_features_internal.cc b/chromecast/base/cast_features_internal.cc new file mode 100644 index 0000000..4ce667c --- /dev/null +++ b/chromecast/base/cast_features_internal.cc
@@ -0,0 +1,14 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +namespace base { +struct Feature; +} +namespace chromecast { +std::vector<const base::Feature*> GetInternalFeatures() { + return std::vector<const base::Feature*>(); +} +} // namespace chromecast
diff --git a/chromecast/base/cast_features_unittest.cc b/chromecast/base/cast_features_unittest.cc index 9ddf3ea..2755e9b 100644 --- a/chromecast/base/cast_features_unittest.cc +++ b/chromecast/base/cast_features_unittest.cc
@@ -30,6 +30,7 @@ // testing::Test implementation: void SetUp() override { ResetCastFeaturesForTesting(); } + void TearDown() override { ResetCastFeaturesForTesting(); } private: // A field trial list must be created before attempting to create FieldTrials. @@ -40,8 +41,6 @@ }; TEST_F(CastFeaturesTest, EnableDisableMultipleBooleanFeatures) { - chromecast::ClearFeaturesForTesting(); - // Declare several boolean features. base::Feature bool_feature{kTestBooleanFeatureName, base::FEATURE_DISABLED_BY_DEFAULT}; @@ -53,10 +52,8 @@ base::FEATURE_ENABLED_BY_DEFAULT}; // Properly register them - chromecast::RegisterFeature(&bool_feature); - chromecast::RegisterFeature(&bool_feature_2); - chromecast::RegisterFeature(&bool_feature_3); - chromecast::RegisterFeature(&bool_feature_4); + chromecast::SetFeaturesForTest( + {&bool_feature, &bool_feature_2, &bool_feature_3, &bool_feature_4}); // Override those features with DCS configs. auto experiments = std::make_unique<base::ListValue>(); @@ -77,11 +74,10 @@ } TEST_F(CastFeaturesTest, EnableSingleFeatureWithParams) { - chromecast::ClearFeaturesForTesting(); // Define a feature with params. base::Feature test_feature{kTestParamsFeatureName, base::FEATURE_DISABLED_BY_DEFAULT}; - chromecast::RegisterFeature(&test_feature); + chromecast::SetFeaturesForTest({&test_feature}); // Pass params via DCS. auto experiments = std::make_unique<base::ListValue>(); @@ -114,7 +110,6 @@ } TEST_F(CastFeaturesTest, CommandLineOverridesDcsAndDefault) { - chromecast::ClearFeaturesForTesting(); // Declare several boolean features. base::Feature bool_feature{kTestBooleanFeatureName, base::FEATURE_DISABLED_BY_DEFAULT}; @@ -125,12 +120,6 @@ base::Feature bool_feature_4{kTestBooleanFeatureName4, base::FEATURE_ENABLED_BY_DEFAULT}; - // Properly register them - chromecast::RegisterFeature(&bool_feature); - chromecast::RegisterFeature(&bool_feature_2); - chromecast::RegisterFeature(&bool_feature_3); - chromecast::RegisterFeature(&bool_feature_4); - // Override those features with DCS configs. auto experiments = std::make_unique<base::ListValue>(); auto features = std::make_unique<base::DictionaryValue>(); @@ -142,7 +131,9 @@ // Also override a param feature with DCS config. base::Feature params_feature{kTestParamsFeatureName, base::FEATURE_ENABLED_BY_DEFAULT}; - chromecast::RegisterFeature(¶ms_feature); + chromecast::SetFeaturesForTest({&bool_feature, &bool_feature_2, + &bool_feature_3, &bool_feature_4, + ¶ms_feature}); auto params = std::make_unique<base::DictionaryValue>(); params->SetString("foo_key", "foo"); @@ -175,7 +166,6 @@ } TEST_F(CastFeaturesTest, SetEmptyExperiments) { - chromecast::ClearFeaturesForTesting(); // Override those features with DCS configs. auto experiments = std::make_unique<base::ListValue>(); auto features = std::make_unique<base::DictionaryValue>(); @@ -201,7 +191,6 @@ } TEST_F(CastFeaturesTest, SetSomeGoodExperiments) { - chromecast::ClearFeaturesForTesting(); // Override those features with DCS configs. auto experiments = std::make_unique<base::ListValue>(); auto features = std::make_unique<base::DictionaryValue>(); @@ -220,7 +209,6 @@ } TEST_F(CastFeaturesTest, SetAllBadExperiments) { - chromecast::ClearFeaturesForTesting(); // Override those features with DCS configs. auto experiments = std::make_unique<base::ListValue>(); auto features = std::make_unique<base::DictionaryValue>();
diff --git a/chromecast/browser/test/cast_features_browsertest.cc b/chromecast/browser/test/cast_features_browsertest.cc index 1203f2e..0e2b181 100644 --- a/chromecast/browser/test/cast_features_browsertest.cc +++ b/chromecast/browser/test/cast_features_browsertest.cc
@@ -90,25 +90,25 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kTestFeat24{"test_feat_24", base::FEATURE_ENABLED_BY_DEFAULT}; -void RegisterFeatures() { - chromecast::RegisterFeaturesForTesting(); - chromecast::RegisterFeature(&kTestFeat1); - chromecast::RegisterFeature(&kTestFeat2); - chromecast::RegisterFeature(&kTestFeat3); - chromecast::RegisterFeature(&kTestFeat4); - chromecast::RegisterFeature(&kTestFeat11); - chromecast::RegisterFeature(&kTestFeat21); - chromecast::RegisterFeature(&kTestFeat22); - chromecast::RegisterFeature(&kTestFeat23); - chromecast::RegisterFeature(&kTestFeat24); + +// Extend the default features with test features only used in this browsertest. +void SetupFeatures() { + std::vector<const base::Feature*> features = { + &kTestFeat1, &kTestFeat2, &kTestFeat3, &kTestFeat4, &kTestFeat11, + &kTestFeat21, &kTestFeat22, &kTestFeat23, &kTestFeat24}; + std::vector<const base::Feature*> existing_features = + chromecast::GetFeatures(); + features.insert(features.end(), existing_features.begin(), + existing_features.end()); + chromecast::SetFeaturesForTest(std::move(features)); } } // namespace class CastFeaturesBrowserTest : public CastBrowserTest { public: - CastFeaturesBrowserTest() { chromecast::ClearFeaturesForTesting(); } - ~CastFeaturesBrowserTest() override {} + CastFeaturesBrowserTest() { SetupFeatures(); } + ~CastFeaturesBrowserTest() override { chromecast::ResetCastFeaturesForTesting(); } static PrefService* pref_service() { return CastBrowserProcess::GetInstance()->pref_service(); @@ -160,14 +160,12 @@ // Test that set features activate on the next boot. Part 1 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_PRE_TestFeaturesActivateOnBoot) { - RegisterFeatures(); ClearFeaturesFromPrefs({kTestFeat1, kTestFeat2, kTestFeat3, kTestFeat4}); } // Test that set features activate on the next boot. Part 2 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_TestFeaturesActivateOnBoot) { - RegisterFeatures(); // Default values should be returned. ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat1)); ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat2)); @@ -189,7 +187,6 @@ // Test that features activate on the next boot. Part 3 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestFeaturesActivateOnBoot) { - RegisterFeatures(); // Overriden values set in test case above should be set. ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat1)); ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat2)); @@ -200,13 +197,11 @@ // Test that features with params activate on boot. Part 1 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_PRE_TestParamsActivateOnBoot) { - RegisterFeatures(); ClearFeaturesFromPrefs({kTestFeat11}); } // Test that features with params activate on boot. Part 2 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_TestParamsActivateOnBoot) { - RegisterFeatures(); // Default value should be returned. ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat11)); @@ -227,7 +222,6 @@ // Test that features with params activate on boot. Part 3 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestParamsActivateOnBoot) { - RegisterFeatures(); // Check that the feature is now enabled. ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat11)); @@ -252,14 +246,12 @@ // Test that only well-formed features are persisted to disk. Part 1 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_PRE_TestOnlyWellFormedFeaturesPersisted) { - RegisterFeatures(); ClearFeaturesFromPrefs({kTestFeat21, kTestFeat22, kTestFeat23, kTestFeat24}); } // Test that only well-formed features are persisted to disk. Part 2 of 3. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, PRE_TestOnlyWellFormedFeaturesPersisted) { - RegisterFeatures(); // Default values should be returned. ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat21)); ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat22)); @@ -281,7 +273,6 @@ // Test that only well-formed features are persisted to disk. Part 2 of 2. IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestOnlyWellFormedFeaturesPersisted) { - RegisterFeatures(); // Only the well-formed parameters should be overriden. ASSERT_TRUE(chromecast::IsFeatureEnabled(kTestFeat21)); ASSERT_FALSE(chromecast::IsFeatureEnabled(kTestFeat24));
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 82998d4a..0d06ae7 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10600.0.0 \ No newline at end of file +10609.0.0 \ No newline at end of file
diff --git a/chromeos/dbus/fake_concierge_client.cc b/chromeos/dbus/fake_concierge_client.cc index cf6bc24a..2900977e 100644 --- a/chromeos/dbus/fake_concierge_client.cc +++ b/chromeos/dbus/fake_concierge_client.cc
@@ -30,8 +30,11 @@ const vm_tools::concierge::CreateDiskImageRequest& request, DBusMethodCallback<vm_tools::concierge::CreateDiskImageResponse> callback) { create_disk_image_called_ = true; + vm_tools::concierge::CreateDiskImageResponse response; + response.set_status(vm_tools::concierge::DISK_STATUS_CREATED); + response.set_disk_path("foo"); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::DestroyDiskImage( @@ -39,38 +42,50 @@ DBusMethodCallback<vm_tools::concierge::DestroyDiskImageResponse> callback) { destroy_disk_image_called_ = true; + vm_tools::concierge::DestroyDiskImageResponse response; + response.set_status(vm_tools::concierge::DISK_STATUS_DESTROYED); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::StartTerminaVm( const vm_tools::concierge::StartVmRequest& request, DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback) { start_termina_vm_called_ = true; + vm_tools::concierge::StartVmResponse response; + response.set_success(true); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::StopVm( const vm_tools::concierge::StopVmRequest& request, DBusMethodCallback<vm_tools::concierge::StopVmResponse> callback) { stop_vm_called_ = true; + vm_tools::concierge::StopVmResponse response; + response.set_success(true); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::StartContainer( const vm_tools::concierge::StartContainerRequest& request, DBusMethodCallback<vm_tools::concierge::StartContainerResponse> callback) { start_container_called_ = true; - std::move(callback).Run(base::nullopt); + vm_tools::concierge::StartContainerResponse response; + response.set_status(vm_tools::concierge::CONTAINER_STATUS_RUNNING); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::LaunchContainerApplication( const vm_tools::concierge::LaunchContainerApplicationRequest& request, DBusMethodCallback<vm_tools::concierge::LaunchContainerApplicationResponse> callback) { - std::move(callback).Run(base::nullopt); + vm_tools::concierge::LaunchContainerApplicationResponse response; + response.set_success(true); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(response))); } void FakeConciergeClient::WaitForServiceToBeAvailable(
diff --git a/chromeos/network/portal_detector/mock_network_portal_detector.h b/chromeos/network/portal_detector/mock_network_portal_detector.h index 7f2ad75..c84a3c2c 100644 --- a/chromeos/network/portal_detector/mock_network_portal_detector.h +++ b/chromeos/network/portal_detector/mock_network_portal_detector.h
@@ -26,10 +26,9 @@ const std::string& service_path)); MOCK_METHOD0(IsEnabled, bool()); MOCK_METHOD1(Enable, void(bool start_detection)); - MOCK_METHOD0(StartDetectionIfIdle, bool()); + MOCK_METHOD1(StartPortalDetection, bool(bool force)); MOCK_METHOD1(SetStrategy, void(chromeos::PortalDetectorStrategy::StrategyId id)); - MOCK_METHOD0(OnLockScreenRequest, void()); private: DISALLOW_COPY_AND_ASSIGN(MockNetworkPortalDetector);
diff --git a/chromeos/network/portal_detector/network_portal_detector.h b/chromeos/network/portal_detector/network_portal_detector.h index d20017b9..2bd5c488 100644 --- a/chromeos/network/portal_detector/network_portal_detector.h +++ b/chromeos/network/portal_detector/network_portal_detector.h
@@ -55,6 +55,9 @@ const NetworkState* network, const CaptivePortalState& state) = 0; + // Called on Shutdown, allows removal of observers. Primarly used in tests. + virtual void OnShutdown() {} + protected: virtual ~Observer() {} }; @@ -93,18 +96,16 @@ // initiated by this method. virtual void Enable(bool start_detection) = 0; - // Restarts portal detection for the default network if currently in - // the idle state. Returns true if new portal detection attempt was - // started. - virtual bool StartDetectionIfIdle() = 0; + // Starts or restarts portal detection for the default network. If not + // currently in the idle state, does nothing unless |force| is true in which + // case any current detection is stopped and a new attempt is started. Returns + // true if a new portal detection attempt was started. + virtual bool StartPortalDetection(bool force) = 0; // Sets current strategy according to |id|. If current detection id // doesn't equal to |id|, detection is restarted. virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) = 0; - // Closes portal login window before screen is locked. - virtual void OnLockScreenRequest() = 0; - // Returns non-localized string representation of |status|. static std::string CaptivePortalStatusString(CaptivePortalStatus status);
diff --git a/chromeos/network/portal_detector/network_portal_detector_stub.cc b/chromeos/network/portal_detector/network_portal_detector_stub.cc index d6aac35..bbeffda 100644 --- a/chromeos/network/portal_detector/network_portal_detector_stub.cc +++ b/chromeos/network/portal_detector/network_portal_detector_stub.cc
@@ -31,13 +31,11 @@ void NetworkPortalDetectorStub::Enable(bool start_detection) {} -bool NetworkPortalDetectorStub::StartDetectionIfIdle() { +bool NetworkPortalDetectorStub::StartPortalDetection(bool force) { return false; } void NetworkPortalDetectorStub::SetStrategy( PortalDetectorStrategy::StrategyId id) {} -void NetworkPortalDetectorStub::OnLockScreenRequest() {} - } // namespace chromeos
diff --git a/chromeos/network/portal_detector/network_portal_detector_stub.h b/chromeos/network/portal_detector/network_portal_detector_stub.h index 16e9fd0..3afb362 100644 --- a/chromeos/network/portal_detector/network_portal_detector_stub.h +++ b/chromeos/network/portal_detector/network_portal_detector_stub.h
@@ -24,9 +24,8 @@ const std::string& service_path) override; bool IsEnabled() override; void Enable(bool start_detection) override; - bool StartDetectionIfIdle() override; + bool StartPortalDetection(bool force) override; void SetStrategy(PortalDetectorStrategy::StrategyId id) override; - void OnLockScreenRequest() override; DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorStub); };
diff --git a/components/chrome_apps/webstore_widget/cws_widget/cws_widget_container_error_dialog.js b/components/chrome_apps/webstore_widget/cws_widget/cws_widget_container_error_dialog.js index 28efbb4..5ca0ffd9d1 100644 --- a/components/chrome_apps/webstore_widget/cws_widget/cws_widget_container_error_dialog.js +++ b/components/chrome_apps/webstore_widget/cws_widget/cws_widget_container_error_dialog.js
@@ -25,7 +25,7 @@ /** * One-time initialization of DOM. - * @private + * @protected */ CWSWidgetContainerErrorDialog.prototype.initDom_ = function() { cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this);
diff --git a/components/mirroring/service/fake_network_service.h b/components/mirroring/service/fake_network_service.h index 8237bef..b84b1687 100644 --- a/components/mirroring/service/fake_network_service.h +++ b/components/mirroring/service/fake_network_service.h
@@ -82,8 +82,12 @@ base::OnceClosure completion_callback) override {} void ClearHttpCache(base::Time start_time, base::Time end_time, - network::mojom::ClearCacheUrlFilterPtr filter, + network::mojom::ClearDataFilterPtr filter, ClearHttpCacheCallback callback) override {} + void ClearChannelIds(base::Time start_time, + base::Time end_time, + network::mojom::ClearDataFilterPtr filter, + ClearChannelIdsCallback callback) override {} void SetNetworkConditions( const std::string& profile_id, network::mojom::NetworkConditionsPtr conditions) override {}
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn index 4306a717..bd8d10f9 100644 --- a/components/offline_pages/core/BUILD.gn +++ b/components/offline_pages/core/BUILD.gn
@@ -44,6 +44,8 @@ "model/offline_page_model_utils.h", "model/offline_page_upgrade_types.cc", "model/offline_page_upgrade_types.h", + "model/persistent_page_consistency_check_task.cc", + "model/persistent_page_consistency_check_task.h", "model/start_offline_page_upgrade_task.cc", "model/start_offline_page_upgrade_task.h", "model/startup_maintenance_task.cc", @@ -167,6 +169,7 @@ "model/mark_page_accessed_task_unittest.cc", "model/offline_page_model_taskified_unittest.cc", "model/offline_page_model_utils_unittest.cc", + "model/persistent_page_consistency_check_task_unittest.cc", "model/start_offline_page_upgrade_task_unittest.cc", "model/startup_maintenance_task_unittest.cc", "model/store_thumbnail_task_unittest.cc",
diff --git a/components/offline_pages/core/model/offline_page_item_generator.cc b/components/offline_pages/core/model/offline_page_item_generator.cc index b6a936a..3cf48e6 100644 --- a/components/offline_pages/core/model/offline_page_item_generator.cc +++ b/components/offline_pages/core/model/offline_page_item_generator.cc
@@ -32,6 +32,10 @@ item.last_access_time = last_access_time_; item.access_count = access_count_; item.digest = digest_; + item.file_missing_time = file_missing_time_; + if (use_offline_id_as_system_download_id_) { + item.system_download_id = item.offline_id; + } return item; } @@ -95,4 +99,13 @@ digest_ = digest; } +void OfflinePageItemGenerator::SetFileMissingTime( + base::Time file_missing_time) { + file_missing_time_ = file_missing_time; +} + +void OfflinePageItemGenerator::SetUseOfflineIdAsSystemDownloadId(bool enable) { + use_offline_id_as_system_download_id_ = enable; +} + } // namespace offline_pages
diff --git a/components/offline_pages/core/model/offline_page_item_generator.h b/components/offline_pages/core/model/offline_page_item_generator.h index c9095b3..e8605bc 100644 --- a/components/offline_pages/core/model/offline_page_item_generator.h +++ b/components/offline_pages/core/model/offline_page_item_generator.h
@@ -36,6 +36,8 @@ void SetAccessCount(int access_count); void SetArchiveDirectory(const base::FilePath& archive_dir); void SetDigest(const std::string& digest); + void SetFileMissingTime(base::Time file_missing_time); + void SetUseOfflineIdAsSystemDownloadId(bool enable); private: std::string namespace_ = kDefaultNamespace; @@ -49,6 +51,9 @@ int access_count_ = 0; base::FilePath archive_dir_; std::string digest_; + base::Time file_missing_time_; + + bool use_offline_id_as_system_download_id_ = false; }; } // namespace offline_pages
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc index 19b951a..0c7605a 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -28,6 +28,7 @@ #include "components/offline_pages/core/model/get_thumbnail_task.h" #include "components/offline_pages/core/model/mark_page_accessed_task.h" #include "components/offline_pages/core/model/offline_page_model_utils.h" +#include "components/offline_pages/core/model/persistent_page_consistency_check_task.h" #include "components/offline_pages/core/model/startup_maintenance_task.h" #include "components/offline_pages/core/model/store_thumbnail_task.h" #include "components/offline_pages/core/model/update_file_path_task.h" @@ -715,6 +716,23 @@ store_.get(), archive_manager_.get(), policy_controller_.get(), now, base::BindOnce(&OfflinePageModelTaskified::OnClearCachedPagesDone, weak_ptr_factory_.GetWeakPtr()))); + + // TODO(https://crbug.com/834902) This might need a better execution plan. + task_queue_.AddTask(std::make_unique<PersistentPageConsistencyCheckTask>( + store_.get(), archive_manager_.get(), policy_controller_.get(), now, + base::BindOnce( + &OfflinePageModelTaskified::OnPersistentPageConsistencyCheckDone, + weak_ptr_factory_.GetWeakPtr()))); +} + +void OfflinePageModelTaskified::OnPersistentPageConsistencyCheckDone( + bool success, + const std::vector<int64_t>& pages_deleted) { + // If there's no persistent page expired, save some effort by exiting early. + // TODO(https://crbug.com/834909), use the temporary hidden bit in + // DownloadUIAdapter instead of calling remove directly. + if (pages_deleted.size() > 0) + download_manager_->Remove(pages_deleted); } void OfflinePageModelTaskified::OnClearCachedPagesDone(
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.h b/components/offline_pages/core/model/offline_page_model_taskified.h index be193313..52215f2a1 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.h +++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -205,6 +205,9 @@ void RunMaintenanceTasks(const base::Time now, bool first_run); void OnClearCachedPagesDone(size_t deleted_page_count, ClearStorageTask::ClearStorageResult result); + void OnPersistentPageConsistencyCheckDone( + bool success, + const std::vector<int64_t>& pages_deleted); // Method for upgrade to public storage. void PostSelectItemsMarkedForUpgrade();
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc index 453d801d..714f403b 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -23,6 +23,7 @@ #include "components/offline_pages/core/model/offline_page_item_generator.h" #include "components/offline_pages/core/model/offline_page_model_utils.h" #include "components/offline_pages/core/model/offline_page_test_utils.h" +#include "components/offline_pages/core/model/persistent_page_consistency_check_task.h" #include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_metadata_store_sql.h" @@ -829,7 +830,7 @@ EXPECT_EQ(2LL, store_test_util()->GetPageCount()); base::MockCallback<DeletePageCallback> callback; - EXPECT_CALL(callback, Run(testing::A<DeletePageResult>())); + EXPECT_CALL(callback, Run(A<DeletePageResult>())); CheckTaskQueueIdle(); model()->DeletePagesByOfflineId({page1.offline_id}, callback.Get()); @@ -1399,11 +1400,12 @@ // This test is affected by https://crbug.com/725685, which only affects windows // platform. #if defined(OS_WIN) -#define MAYBE_ConsistencyCheckExecuted DISABLED_ConsistencyCheckExecuted +#define MAYBE_StartupMaintenanceTaskExecuted \ + DISABLED_StartupMaintenanceTaskExecuted #else -#define MAYBE_ConsistencyCheckExecuted ConsistencyCheckExecuted +#define MAYBE_StartupMaintenanceTaskExecuted StartupMaintenanceTaskExecuted #endif -TEST_F(OfflinePageModelTaskifiedTest, MAYBE_ConsistencyCheckExecuted) { +TEST_F(OfflinePageModelTaskifiedTest, MAYBE_StartupMaintenanceTaskExecuted) { // Insert temporary pages page_generator()->SetArchiveDirectory(temporary_dir_path()); page_generator()->SetNamespace(kDefaultNamespace); @@ -1420,12 +1422,11 @@ // Insert persistent pages. page_generator()->SetNamespace(kDownloadNamespace); - // Page missing archive file in pesistent directory. + // Page missing archive file in private directory. OfflinePageItem persistent_page1 = page_generator()->CreateItem(); // Page missing metadata entry in database since it's not inserted into store. OfflinePageItem persistent_page2 = page_generator()->CreateItemWithTempFile(); - // Page in persistent namespace saved in persistent directory to simulate - // pages saved in legacy directory. + // Page in persistent namespace saved in private directory. OfflinePageItem persistent_page3 = page_generator()->CreateItemWithTempFile(); InsertPageIntoStore(persistent_page1); InsertPageIntoStore(persistent_page3); @@ -1438,7 +1439,7 @@ test_utils::GetFileCountInDirectory(private_archive_dir_path())); // Execute GetAllPages and move the clock forward to cover the delay, in order - // to trigger consistency checks. + // to trigger StartupMaintenanceTask execution. base::MockCallback<MultipleOfflinePageItemCallback> callback; model()->GetAllPages(callback.Get()); task_runner()->FastForwardBy( @@ -1446,7 +1447,7 @@ base::TimeDelta::FromMilliseconds(1)); PumpLoop(); - EXPECT_EQ(1LL, store_test_util()->GetPageCount()); + EXPECT_EQ(2LL, store_test_util()->GetPageCount()); EXPECT_EQ(0UL, test_utils::GetFileCountInDirectory(temporary_dir_path())); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(private_archive_dir_path())); @@ -1525,6 +1526,115 @@ 1); } +// This test is affected by https://crbug.com/725685, which only affects windows +// platform. +#if defined(OS_WIN) +#define MAYBE_PersistentPageConsistencyCheckExecuted \ + DISABLED_PersistentPageConsistencyCheckExecuted +#else +#define MAYBE_PersistentPageConsistencyCheckExecuted \ + PersistentPageConsistencyCheckExecuted +#endif +TEST_F(OfflinePageModelTaskifiedTest, PersistentPageConsistencyCheckExecuted) { + // The PersistentPageConsistencyCheckTask should not be executed based on time + // delays after launch (aka the model being built). + task_runner()->FastForwardBy(base::TimeDelta::FromDays(1)); + PumpLoop(); + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 0); + + // GetAllPages should schedule a delayed task that will eventually run + // PersistentPageConsistencyCheck. + base::MockCallback<MultipleOfflinePageItemCallback> callback; + model()->GetAllPages(callback.Get()); + PumpLoop(); + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 0); + + // Add a persistent page with file. + page_generator()->SetNamespace(kDownloadNamespace); + page_generator()->SetArchiveDirectory(public_archive_dir_path()); + OfflinePageItem page = page_generator()->CreateItemWithTempFile(); + page.system_download_id = kDownloadId; + InsertPageIntoStore(page); + EXPECT_EQ(1UL, + test_utils::GetFileCountInDirectory(public_archive_dir_path())); + EXPECT_EQ(1LL, store_test_util()->GetPageCount()); + + // After the delay (plus 1 millisecond just in case), the consistency check + // should be enqueued and executed. + const base::TimeDelta run_delay = + OfflinePageModelTaskified::kMaintenanceTasksDelay + + base::TimeDelta::FromMilliseconds(1); + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + // But nothing should change. + EXPECT_EQ(1UL, + test_utils::GetFileCountInDirectory(public_archive_dir_path())); + EXPECT_EQ(1LL, store_test_util()->GetPageCount()); + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 1); + + // Delete the file associated with |page|, so the next time when the + // consistency check is executed, the page will be marked as hidden. + base::DeleteFile(page.file_path, false); + + // Calling GetAllPages after only half of the enforced interval between + // consistency check runs should not schedule the task. + // Note: The previous elapsed delay is discounted from the clock advance here. + task_runner()->FastForwardBy( + OfflinePageModelTaskified::kClearStorageInterval / 2 - run_delay); + model()->GetAllPages(callback.Get()); + // And advance the delay too. + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + // Confirm no persistent page consistency check is executed. + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 1); + + // Forwarding by the full interval (plus 1 second just in case) should allow + // the task to be enqueued again and call GetAllPages again to enqueue the + // task. + task_runner()->FastForwardBy( + OfflinePageModelTaskified::kClearStorageInterval / 2 + + base::TimeDelta::FromSeconds(1)); + model()->GetAllPages(callback.Get()); + // And advance the delay too. + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + // Confirm persistent page consistency check is executed, and the page is + // marked as missing file. + EXPECT_EQ(0UL, + test_utils::GetFileCountInDirectory(public_archive_dir_path())); + EXPECT_EQ(1LL, store_test_util()->GetPageCount()); + auto actual_page = store_test_util()->GetPageByOfflineId(page.offline_id); + ASSERT_TRUE(actual_page); + EXPECT_NE(base::Time(), actual_page->file_missing_time); + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 2); + + // Forwarding by a long time that is enough for the page with missing file to + // get expired. + task_runner()->FastForwardBy(base::TimeDelta::FromDays(400)); + // Saving a page should also immediately enqueue the consistency check task. + auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); + SavePageWithExpectedResult(kTestUrl, kTestClientId1, kTestUrl2, + kEmptyRequestOrigin, std::move(archiver), + SavePageResult::SUCCESS); + // Advance the delay to activate task execution. + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + // Confirm persistent page consistency check is executed, and the page is + // deleted from database, also notified system download manager. + EXPECT_EQ(0UL, + test_utils::GetFileCountInDirectory(public_archive_dir_path())); + EXPECT_EQ(1LL, store_test_util()->GetPageCount()); + EXPECT_EQ(page.system_download_id, + download_manager_stub()->last_removed_id()); + histogram_tester()->ExpectTotalCount( + "OfflinePages.ConsistencyCheck.Persistent.Result", 3); +} + TEST_F(OfflinePageModelTaskifiedTest, MaintenanceTasksAreDisabled) { // The maintenance tasks should not be executed when disabled by tests. model()->DoNotRunMaintenanceTasksForTesting();
diff --git a/components/offline_pages/core/model/persistent_page_consistency_check_task.cc b/components/offline_pages/core/model/persistent_page_consistency_check_task.cc new file mode 100644 index 0000000..6efa18e --- /dev/null +++ b/components/offline_pages/core/model/persistent_page_consistency_check_task.cc
@@ -0,0 +1,254 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/model/persistent_page_consistency_check_task.h" + +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/metrics/histogram_macros.h" +#include "base/numerics/safe_conversions.h" +#include "components/offline_pages/core/archive_manager.h" +#include "components/offline_pages/core/client_policy_controller.h" +#include "components/offline_pages/core/offline_page_client_policy.h" +#include "components/offline_pages/core/offline_page_metadata_store_sql.h" +#include "components/offline_pages/core/offline_store_utils.h" +#include "sql/connection.h" +#include "sql/statement.h" +#include "sql/transaction.h" + +namespace base { +class Time; +} // namespace base + +namespace offline_pages { + +namespace { + +#define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" + +const base::TimeDelta kExpireThreshold = base::TimeDelta::FromDays(365); + +struct PageInfo { + int64_t offline_id; + base::FilePath file_path; + base::Time file_missing_time; + int64_t system_download_id; +}; + +std::vector<PageInfo> GetPageInfosByNamespaces( + const std::vector<std::string>& temp_namespaces, + sql::Connection* db) { + std::vector<PageInfo> result; + + static const char kSql[] = + "SELECT offline_id, file_path, file_missing_time, system_download_id" + " FROM " OFFLINE_PAGES_TABLE_NAME " WHERE client_namespace = ?"; + + for (const auto& temp_namespace : temp_namespaces) { + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindString(0, temp_namespace); + while (statement.Step()) { + result.push_back( + {statement.ColumnInt64(0), + store_utils::FromDatabaseFilePath(statement.ColumnString(1)), + store_utils::FromDatabaseTime(statement.ColumnInt64(2)), + statement.ColumnInt64(3)}); + } + } + + return result; +} + +bool DeletePagesByOfflineIds(const std::vector<int64_t>& offline_ids, + sql::Connection* db) { + static const char kSql[] = + "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id = ?"; + + for (const auto& offline_id : offline_ids) { + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, offline_id); + if (!statement.Run()) + return false; + } + return true; +} + +bool MarkPagesAsMissing(const std::vector<int64_t>& ids_of_missing_pages, + base::Time missing_time, + sql::Connection* db) { + static const char kSql[] = "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME + " SET file_missing_time = ?" + " WHERE offline_id = ?"; + + for (auto offline_id : ids_of_missing_pages) { + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, store_utils::ToDatabaseTime(missing_time)); + statement.BindInt64(1, offline_id); + if (!statement.Run()) + return false; + } + return true; +} + +bool MarkPagesAsReappeared(const std::vector<int64_t>& ids_of_reappeared_pages, + sql::Connection* db) { + static const char kSql[] = "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME + " SET file_missing_time = ?" + " WHERE offline_id = ?"; + + base::Time invalid_time; + for (auto offline_id : ids_of_reappeared_pages) { + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, store_utils::ToDatabaseTime(invalid_time)); + statement.BindInt64(1, offline_id); + if (!statement.Run()) + return false; + } + return true; +} + +PersistentPageConsistencyCheckTask::CheckResult +PersistentPageConsistencyCheckSync( + OfflinePageMetadataStoreSQL* store, + const base::FilePath& private_dir, + const base::FilePath& public_dir, + const std::vector<std::string>& persistent_namespaces, + base::Time check_time, + sql::Connection* db) { + std::vector<int64_t> download_ids_of_deleted_pages; + if (!db) + return {SyncOperationResult::INVALID_DB_CONNECTION, + download_ids_of_deleted_pages}; + + sql::Transaction transaction(db); + if (!transaction.Begin()) + return {SyncOperationResult::TRANSACTION_BEGIN_ERROR, + download_ids_of_deleted_pages}; + + std::vector<PageInfo> persistent_page_infos = + GetPageInfosByNamespaces(persistent_namespaces, db); + + std::vector<int64_t> pages_found_missing; + std::vector<int64_t> pages_reappeared; + std::vector<int64_t> page_ids_to_delete; + for (const auto& page_info : persistent_page_infos) { + if (base::PathExists(page_info.file_path)) { + if (page_info.file_missing_time != base::Time()) + pages_reappeared.push_back(page_info.offline_id); + } else { + if (page_info.file_missing_time == base::Time()) { + pages_found_missing.push_back(page_info.offline_id); + } else { + if (check_time - page_info.file_missing_time > kExpireThreshold) { + page_ids_to_delete.push_back(page_info.offline_id); + download_ids_of_deleted_pages.push_back(page_info.system_download_id); + } + } + } + } + + if (!DeletePagesByOfflineIds(page_ids_to_delete, db) || + !MarkPagesAsMissing(pages_found_missing, check_time, db) || + !MarkPagesAsReappeared(pages_reappeared, db)) { + return {SyncOperationResult::DB_OPERATION_ERROR, + download_ids_of_deleted_pages}; + } + + if (page_ids_to_delete.size() > 0) { + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Persistent.ExpiredEntryCount", + base::saturated_cast<int32_t>(page_ids_to_delete.size())); + } + if (pages_found_missing.size() > 0) { + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Persistent.MissingFileCount", + base::saturated_cast<int32_t>(pages_found_missing.size())); + } + if (pages_reappeared.size() > 0) { + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Persistent.ReappearedFileCount", + base::saturated_cast<int32_t>(pages_reappeared.size())); + } + + if (!transaction.Commit()) + return {SyncOperationResult::TRANSACTION_COMMIT_ERROR, + download_ids_of_deleted_pages}; + + return {SyncOperationResult::SUCCESS, download_ids_of_deleted_pages}; +} + +} // namespace + +PersistentPageConsistencyCheckTask::CheckResult::CheckResult() = default; + +PersistentPageConsistencyCheckTask::CheckResult::CheckResult( + SyncOperationResult result, + const std::vector<int64_t>& system_download_ids) + : result(result), download_ids_of_deleted_pages(system_download_ids) {} + +PersistentPageConsistencyCheckTask::CheckResult::CheckResult( + const CheckResult& other) = default; + +PersistentPageConsistencyCheckTask::CheckResult& +PersistentPageConsistencyCheckTask::CheckResult::operator=( + const CheckResult& other) = default; + +PersistentPageConsistencyCheckTask::CheckResult::~CheckResult() {} + +PersistentPageConsistencyCheckTask::PersistentPageConsistencyCheckTask( + OfflinePageMetadataStoreSQL* store, + ArchiveManager* archive_manager, + ClientPolicyController* policy_controller, + base::Time check_time, + PersistentPageConsistencyCheckCallback callback) + : store_(store), + archive_manager_(archive_manager), + policy_controller_(policy_controller), + check_time_(check_time), + callback_(std::move(callback)), + weak_ptr_factory_(this) { + DCHECK(store_); + DCHECK(archive_manager_); + DCHECK(policy_controller_); +} + +PersistentPageConsistencyCheckTask::~PersistentPageConsistencyCheckTask() = + default; + +void PersistentPageConsistencyCheckTask::Run() { + std::vector<std::string> namespaces = policy_controller_->GetAllNamespaces(); + std::vector<std::string> persistent_namespaces; + for (const auto& name_space : namespaces) { + if (!policy_controller_->IsRemovedOnCacheReset(name_space)) + persistent_namespaces.push_back(name_space); + } + + store_->Execute(base::BindOnce(&PersistentPageConsistencyCheckSync, store_, + archive_manager_->GetPrivateArchivesDir(), + archive_manager_->GetPublicArchivesDir(), + persistent_namespaces, check_time_), + base::BindOnce(&PersistentPageConsistencyCheckTask:: + OnPersistentPageConsistencyCheckDone, + weak_ptr_factory_.GetWeakPtr())); +} + +void PersistentPageConsistencyCheckTask::OnPersistentPageConsistencyCheckDone( + CheckResult check_result) { + UMA_HISTOGRAM_ENUMERATION("OfflinePages.ConsistencyCheck.Persistent.Result", + check_result.result, + SyncOperationResult::RESULT_COUNT); + // If sync operation failed, invoke the callback with an empty list of + // download ids. + if (check_result.result != SyncOperationResult::SUCCESS) { + std::move(callback_).Run(false, {}); + } else { + std::move(callback_).Run(true, check_result.download_ids_of_deleted_pages); + } + TaskComplete(); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/model/persistent_page_consistency_check_task.h b/components/offline_pages/core/model/persistent_page_consistency_check_task.h new file mode 100644 index 0000000..c98d9fa7 --- /dev/null +++ b/components/offline_pages/core/model/persistent_page_consistency_check_task.h
@@ -0,0 +1,73 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_OFFLINE_PAGES_CORE_MODEL_PERSISTENT_PAGE_CONSISTENCY_CHECK_TASK_H_ +#define COMPONENTS_OFFLINE_PAGES_CORE_MODEL_PERSISTENT_PAGE_CONSISTENCY_CHECK_TASK_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/offline_pages/core/offline_store_types.h" +#include "components/offline_pages/core/task.h" + +namespace offline_pages { + +class ArchiveManager; +class ClientPolicyController; +class OfflinePageMetadataStoreSQL; + +// This task is responsible for checking consistency of persistent pages, mark +// the expired ones with the file missing time and recover the previously +// missing entries back to normal. +class PersistentPageConsistencyCheckTask : public Task { + public: + using PersistentPageConsistencyCheckCallback = + base::OnceCallback<void(bool success, + const std::vector<int64_t>& pages_deleted)>; + + struct CheckResult { + CheckResult(); + CheckResult(SyncOperationResult result, + const std::vector<int64_t>& system_download_ids); + CheckResult(const CheckResult& other); + CheckResult& operator=(const CheckResult& other); + ~CheckResult(); + + SyncOperationResult result; + std::vector<int64_t> download_ids_of_deleted_pages; + }; + + PersistentPageConsistencyCheckTask( + OfflinePageMetadataStoreSQL* store, + ArchiveManager* archive_manager, + ClientPolicyController* policy_controller, + base::Time check_time, + PersistentPageConsistencyCheckCallback callback); + ~PersistentPageConsistencyCheckTask() override; + + // Task implementation: + void Run() override; + + private: + void OnPersistentPageConsistencyCheckDone(CheckResult result); + + // The store containing the offline pages. Not owned. + OfflinePageMetadataStoreSQL* store_; + // The archive manager storing archive directories. Not owned. + ArchiveManager* archive_manager_; + // The policy controller which is used to acquire names of namespaces. Not + // owned. + ClientPolicyController* policy_controller_; + base::Time check_time_; + // The callback for the task. + PersistentPageConsistencyCheckCallback callback_; + + base::WeakPtrFactory<PersistentPageConsistencyCheckTask> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(PersistentPageConsistencyCheckTask); +}; + +} // namespace offline_pages + +#endif // COMPONENTS_OFFLINE_PAGES_CORE_MODEL_PERSISTENT_PAGE_CONSISTENCY_CHECK_TASK_H_
diff --git a/components/offline_pages/core/model/persistent_page_consistency_check_task_unittest.cc b/components/offline_pages/core/model/persistent_page_consistency_check_task_unittest.cc new file mode 100644 index 0000000..df1b7df --- /dev/null +++ b/components/offline_pages/core/model/persistent_page_consistency_check_task_unittest.cc
@@ -0,0 +1,127 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/model/persistent_page_consistency_check_task.h" + +#include "base/bind.h" +#include "base/test/histogram_tester.h" +#include "base/test/mock_callback.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/model/model_task_test_base.h" +#include "components/offline_pages/core/model/offline_page_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::A; +using testing::Eq; +using testing::UnorderedElementsAre; + +namespace offline_pages { + +using PersistentPageConsistencyCheckCallback = + PersistentPageConsistencyCheckTask::PersistentPageConsistencyCheckCallback; + +class PersistentPageConsistencyCheckTaskTest : public ModelTaskTestBase { + public: + PersistentPageConsistencyCheckTaskTest(); + ~PersistentPageConsistencyCheckTaskTest() override; + + void SetUp() override; + bool IsPageMissingFile(const OfflinePageItem& page); + + base::HistogramTester* histogram_tester() { return histogram_tester_.get(); } + + private: + std::unique_ptr<base::HistogramTester> histogram_tester_; +}; + +PersistentPageConsistencyCheckTaskTest:: + PersistentPageConsistencyCheckTaskTest() {} + +PersistentPageConsistencyCheckTaskTest:: + ~PersistentPageConsistencyCheckTaskTest() {} + +void PersistentPageConsistencyCheckTaskTest::SetUp() { + ModelTaskTestBase::SetUp(); + histogram_tester_ = std::make_unique<base::HistogramTester>(); +} + +bool PersistentPageConsistencyCheckTaskTest::IsPageMissingFile( + const OfflinePageItem& page) { + auto actual_page = store_test_util()->GetPageByOfflineId(page.offline_id); + return (actual_page && actual_page->file_missing_time != base::Time()); +} + +// This test is affected by https://crbug.com/725685, which only affects windows +// platform. +#if defined(OS_WIN) +#define MAYBE_ClearExpiredPersistentPages DISABLED_ClearExpiredPersistentPages +#else +#define MAYBE_ClearExpiredPersistentPages ClearExpiredPersistentPages +#endif +TEST_F(PersistentPageConsistencyCheckTaskTest, + MAYBE_ClearExpiredPersistentPages) { + base::Time expire_time = base::Time::Now() - base::TimeDelta::FromDays(400); + + // |page{1,4}| will be marked as missing file. + // |page{2,5}| will be deleted from DB, since they've been expired for longer + // than threshold. + // |page{3,6}| will remove the file_missing_time from the entry, since + // they've been missing files but the files appeared again. + generator()->SetUseOfflineIdAsSystemDownloadId(true); + generator()->SetNamespace(kDownloadNamespace); + generator()->SetArchiveDirectory(PrivateDir()); + OfflinePageItem page1 = AddPageWithoutFile(); + generator()->SetFileMissingTime(expire_time); + OfflinePageItem page2 = AddPageWithoutFile(); + OfflinePageItem page3 = AddPage(); + + generator()->SetArchiveDirectory(PublicDir()); + generator()->SetFileMissingTime(base::Time()); + OfflinePageItem page4 = AddPageWithoutFile(); + generator()->SetFileMissingTime(expire_time); + OfflinePageItem page5 = AddPageWithoutFile(); + OfflinePageItem page6 = AddPage(); + + EXPECT_EQ(6LL, store_test_util()->GetPageCount()); + EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); + EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PublicDir())); + + base::MockCallback<PersistentPageConsistencyCheckCallback> callback; + EXPECT_CALL(callback, + Run(Eq(true), UnorderedElementsAre(page2.system_download_id, + page5.system_download_id))); + + auto task = std::make_unique<PersistentPageConsistencyCheckTask>( + store(), archive_manager(), policy_controller(), base::Time::Now(), + callback.Get()); + RunTask(std::move(task)); + + EXPECT_EQ(4LL, store_test_util()->GetPageCount()); + EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); + EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PublicDir())); + EXPECT_TRUE(store_test_util()->GetPageByOfflineId(page1.offline_id)); + EXPECT_TRUE(IsPageMissingFile(page1)); + EXPECT_FALSE(store_test_util()->GetPageByOfflineId(page2.offline_id)); + EXPECT_TRUE(store_test_util()->GetPageByOfflineId(page3.offline_id)); + EXPECT_FALSE(IsPageMissingFile(page3)); + EXPECT_TRUE(store_test_util()->GetPageByOfflineId(page4.offline_id)); + EXPECT_TRUE(IsPageMissingFile(page4)); + EXPECT_FALSE(store_test_util()->GetPageByOfflineId(page5.offline_id)); + EXPECT_TRUE(store_test_util()->GetPageByOfflineId(page6.offline_id)); + EXPECT_FALSE(IsPageMissingFile(page6)); + + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Persistent.ExpiredEntryCount", 2, 1); + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Persistent.MissingFileCount", 2, 1); + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Persistent.ReappearedFileCount", 2, 1); + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Persistent.Result", + static_cast<int>(SyncOperationResult::SUCCESS), 1); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/model/startup_maintenance_task.cc b/components/offline_pages/core/model/startup_maintenance_task.cc index 405b937..7e33a2a 100644 --- a/components/offline_pages/core/model/startup_maintenance_task.cc +++ b/components/offline_pages/core/model/startup_maintenance_task.cc
@@ -89,29 +89,51 @@ return result; } -SyncOperationResult ClearLegacyTempPagesSync( +// This method is clearing the private dir(the legacy dir). +// - For all files associated with temporary pages: +// The strategy is if any temporary page +// is still left behind in the legacy dir, delete them. +// - For all files associated with persistent pages: +// Leave them as-is, since they might be still in use. +// - For all files without any associated DB entry: +// Delete the files, since they're 'headless' and has no way to be accessed. +SyncOperationResult ClearLegacyPagesInPrivateDirSync( sql::Connection* db, - const std::vector<std::string>& namespaces, - const base::FilePath& legacy_archives_dir) { + const std::vector<std::string>& temporary_namespaces, + const std::vector<std::string>& persistent_namespaces, + const base::FilePath& private_dir) { // One large database transaction that will: // 1. Get temporary page infos from the database. - // 2. Decide which pages to delete (still in legacy archive directory). - // 3. Delete metadata entries from the database. + // 2. Get persistent page infos from the database, in case they're in private + // dir. + // 3. Get all file paths in private dir as a set F. + // 4. For each temporary page info: + // - If its file path is in F, record its offline id for deletion. + // 5. For each persistent page info: + // - If its file path is in F, remove it from F. + // 6. Delete page entries by recorded offline ids, and delete the remaining + // files in F. sql::Transaction transaction(db); if (!transaction.Begin()) return SyncOperationResult::TRANSACTION_BEGIN_ERROR; - std::vector<PageInfo> temp_page_infos = - GetPageInfosByNamespaces(namespaces, db); + std::vector<PageInfo> temporary_page_infos = + GetPageInfosByNamespaces(temporary_namespaces, db); + std::vector<PageInfo> persistent_page_infos = + GetPageInfosByNamespaces(persistent_namespaces, db); + std::map<base::FilePath, PageInfo> path_to_page_info; + std::set<base::FilePath> archive_paths = GetAllArchives(private_dir); std::vector<int64_t> offline_ids_to_delete; - std::vector<base::FilePath> files_to_delete; - for (const auto& page_info : temp_page_infos) { - // Get pages whose archive files are still in the legacy archives directory. - if (legacy_archives_dir.IsParent(page_info.file_path)) { + + for (const auto& page_info : temporary_page_infos) { + if (archive_paths.find(page_info.file_path) != archive_paths.end()) offline_ids_to_delete.push_back(page_info.offline_id); - files_to_delete.push_back(page_info.file_path); - } + } + for (const auto& page_info : persistent_page_infos) { + auto iter = archive_paths.find(page_info.file_path); + if (iter != archive_paths.end()) + archive_paths.erase(iter); } // Try to delete the pages by offline ids collected above. @@ -124,17 +146,26 @@ if (!transaction.Commit()) return SyncOperationResult::TRANSACTION_COMMIT_ERROR; + std::vector<base::FilePath> files_to_delete(archive_paths.begin(), + archive_paths.end()); if (!DeleteFiles(files_to_delete)) return SyncOperationResult::FILE_OPERATION_ERROR; + size_t headless_file_count = + files_to_delete.size() - offline_ids_to_delete.size(); + if (headless_file_count > 0) { + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Legacy.DeletedHeadlessFileCount", + headless_file_count); + } + return SyncOperationResult::SUCCESS; } -SyncOperationResult CheckConsistencySync( +SyncOperationResult CheckTemporaryPageConsistencySync( sql::Connection* db, const std::vector<std::string>& namespaces, - const base::FilePath& archives_dir, - const std::string& prefix_for_uma) { + const base::FilePath& archives_dir) { // One large database transaction that will: // 1. Get page infos by |namespaces| from the database. // 2. Decide which pages to delete. @@ -165,9 +196,8 @@ // committed. if (!DeletePagesByOfflineIds(offline_ids_to_delete, db)) return SyncOperationResult::DB_OPERATION_ERROR; - base::UmaHistogramCounts1M( - "OfflinePages.ConsistencyCheck." + prefix_for_uma + - ".PagesMissingArchiveFileCount", + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount", base::saturated_cast<int32_t>(offline_ids_to_delete.size())); } @@ -186,9 +216,9 @@ if (files_to_delete.size() > 0) { if (!DeleteFiles(files_to_delete)) return SyncOperationResult::FILE_OPERATION_ERROR; - base::UmaHistogramCounts1M("OfflinePages.ConsistencyCheck." + - prefix_for_uma + ".PagesMissingDbEntryCount", - static_cast<int32_t>(files_to_delete.size())); + UMA_HISTOGRAM_COUNTS_1M( + "OfflinePages.ConsistencyCheck.Temporary.PagesMissingDbEntryCount", + static_cast<int32_t>(files_to_delete.size())); } return SyncOperationResult::SUCCESS; @@ -232,25 +262,16 @@ // Clear temporary pages that are in legacy directory, which is also the // directory that serves as the 'private' directory. - SyncOperationResult result = ClearLegacyTempPagesSync( - db, temporary_namespaces, archive_manager->GetPrivateArchivesDir()); + SyncOperationResult result = ClearLegacyPagesInPrivateDirSync( + db, temporary_namespaces, persistent_namespaces, + archive_manager->GetPrivateArchivesDir()); // Clear temporary pages in cache directory. - result = CheckConsistencySync(db, temporary_namespaces, - archive_manager->GetTemporaryArchivesDir(), - "Temporary" /*prefix_for_uma*/); + result = CheckTemporaryPageConsistencySync( + db, temporary_namespaces, archive_manager->GetTemporaryArchivesDir()); UMA_HISTOGRAM_ENUMERATION("OfflinePages.ConsistencyCheck.Temporary.Result", result, SyncOperationResult::RESULT_COUNT); - // Clear persistent pages in private directory. - // TODO(romax): this can be merged with the legacy temporary pages clearing - // above. - result = CheckConsistencySync(db, persistent_namespaces, - archive_manager->GetPrivateArchivesDir(), - "Persistent" /*prefix_for_uma*/); - UMA_HISTOGRAM_ENUMERATION("OfflinePages.ConsistencyCheck.Persistent.Result", - result, SyncOperationResult::RESULT_COUNT); - // Report storage usage UMA. ReportStorageUsageSync(db, namespaces, archive_manager);
diff --git a/components/offline_pages/core/model/startup_maintenance_task.h b/components/offline_pages/core/model/startup_maintenance_task.h index dc9b809c..34c3b13 100644 --- a/components/offline_pages/core/model/startup_maintenance_task.h +++ b/components/offline_pages/core/model/startup_maintenance_task.h
@@ -16,8 +16,8 @@ class OfflinePageMetadataStoreSQL; // This task is responsible for executing maintenance sub-tasks during Chrome -// startup, including: consistency checks, legacy directory cleaning and report -// storage usage UMA. +// startup, including: temporary page consistency check, legacy directory +// cleaning and report storage usage UMA. class StartupMaintenanceTask : public Task { public: StartupMaintenanceTask(OfflinePageMetadataStoreSQL* store,
diff --git a/components/offline_pages/core/model/startup_maintenance_task_unittest.cc b/components/offline_pages/core/model/startup_maintenance_task_unittest.cc index 9921b6343..bbc1e53f 100644 --- a/components/offline_pages/core/model/startup_maintenance_task_unittest.cc +++ b/components/offline_pages/core/model/startup_maintenance_task_unittest.cc
@@ -80,18 +80,19 @@ TestDeletePageInLegacyArchivesDir #endif TEST_F(StartupMaintenanceTaskTest, MAYBE_TestDeletePageInLegacyArchivesDir) { + // |temporary_page| will be removed since it's temporary and its archive file + // is in private directory. + // |persistent_page| will not be affected by the maintenance task. generator()->SetArchiveDirectory(PrivateDir()); generator()->SetNamespace(kLastNNamespace); - OfflinePageItem temporary_page = AddPage(); + OfflinePageItem temporary_page1 = AddPage(); + OfflinePageItem temporary_page2 = AddPageWithoutDBEntry(); generator()->SetNamespace(kDownloadNamespace); - OfflinePageItem persistent_page = AddPage(); - EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, - CheckPagePresence(temporary_page)); - EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, - CheckPagePresence(persistent_page)); + OfflinePageItem persistent_page1 = AddPage(); + OfflinePageItem persistent_page2 = AddPageWithoutDBEntry(); EXPECT_EQ(2LL, store_test_util()->GetPageCount()); - EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(PrivateDir())); + EXPECT_EQ(4UL, test_utils::GetFileCountInDirectory(PrivateDir())); auto task = std::make_unique<StartupMaintenanceTask>( store(), archive_manager(), policy_controller()); @@ -99,8 +100,13 @@ EXPECT_EQ(1LL, store_test_util()->GetPageCount()); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); - EXPECT_FALSE( - store_test_util()->GetPageByOfflineId(temporary_page.offline_id)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page1)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page2)); + EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, + CheckPagePresence(persistent_page1)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(persistent_page2)); + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Legacy.DeletedHeadlessFileCount", 2, 1); } // This test is affected by https://crbug.com/725685, which only affects windows @@ -111,7 +117,12 @@ #define MAYBE_TestDeleteFileWithoutDbEntry TestDeleteFileWithoutDbEntry #endif TEST_F(StartupMaintenanceTaskTest, MAYBE_TestDeleteFileWithoutDbEntry) { - // Only the files without DB entries will be deleted. + // |temporary_page1| will not be affected. + // |temporary_page2| will have the file deleted since the file doesn't have a + // DB entry. + // |persistent_page1| will not be affected. + // |persistent_page2| will have its file deleted, since the file is in private + // directory and has no associated DB entry. generator()->SetNamespace(kLastNNamespace); generator()->SetArchiveDirectory(TemporaryDir()); OfflinePageItem temporary_page1 = AddPage(); @@ -141,6 +152,9 @@ EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, CheckPagePresence(persistent_page1)); EXPECT_EQ(PagePresence::NONE, CheckPagePresence(persistent_page2)); + + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Legacy.DeletedHeadlessFileCount", 1, 1); histogram_tester()->ExpectTotalCount( "OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount", 0); @@ -149,15 +163,6 @@ histogram_tester()->ExpectUniqueSample( "OfflinePages.ConsistencyCheck.Temporary.Result", static_cast<int>(SyncOperationResult::SUCCESS), 1); - histogram_tester()->ExpectTotalCount( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount", - 0); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount", 1, - 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.Result", - static_cast<int>(SyncOperationResult::SUCCESS), 1); } // This test is affected by https://crbug.com/725685, which only affects windows @@ -168,7 +173,10 @@ #define MAYBE_TestDeleteDbEntryWithoutFile TestDeleteDbEntryWithoutFile #endif TEST_F(StartupMaintenanceTaskTest, MAYBE_TestDeleteDbEntryWithoutFile) { - // Only the DB entries without associating files will be deleted. + // |temporary_page1| will not be affected. + // |temporary_page2| will be deleted from DB since it has no file associated. + // |persistent_page1| will not be affected. + // |persistent_page2| will be marked as file_missing. generator()->SetNamespace(kLastNNamespace); generator()->SetArchiveDirectory(TemporaryDir()); OfflinePageItem temporary_page1 = AddPage(); @@ -189,7 +197,7 @@ store(), archive_manager(), policy_controller()); RunTask(std::move(task)); - EXPECT_EQ(2LL, store_test_util()->GetPageCount()); + EXPECT_EQ(3LL, store_test_util()->GetPageCount()); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(TemporaryDir())); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, @@ -197,7 +205,8 @@ EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page2)); EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, CheckPagePresence(persistent_page1)); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(persistent_page2)); + EXPECT_EQ(PagePresence::DB_ONLY, CheckPagePresence(persistent_page2)); + histogram_tester()->ExpectTotalCount( "OfflinePages.ConsistencyCheck.Temporary.PagesMissingDbEntryCount", 0); histogram_tester()->ExpectUniqueSample( @@ -206,14 +215,6 @@ histogram_tester()->ExpectUniqueSample( "OfflinePages.ConsistencyCheck.Temporary.Result", static_cast<int>(SyncOperationResult::SUCCESS), 1); - histogram_tester()->ExpectTotalCount( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount", 0); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount", - 1, 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.Result", - static_cast<int>(SyncOperationResult::SUCCESS), 1); } // This test is affected by https://crbug.com/725685, which only affects windows @@ -225,27 +226,28 @@ #endif TEST_F(StartupMaintenanceTaskTest, MAYBE_CombinedTest) { // Adding a bunch of pages with different setups for temporary pages. - // After the consistency check, only page1 will exist. + // |temporary_page1| will not be affected. + // |temporary_page{2,3,4,5,6}| will be deleted. generator()->SetNamespace(kLastNNamespace); generator()->SetArchiveDirectory(TemporaryDir()); - OfflinePageItem page1 = AddPage(); - OfflinePageItem page2 = AddPageWithoutDBEntry(); - OfflinePageItem page3 = AddPageWithoutFile(); - // Adding a bunch of pages with different setups for persistent pages. - // After the consistency check, only page4 will exist. - generator()->SetNamespace(kDownloadNamespace); + OfflinePageItem temporary_page1 = AddPage(); + OfflinePageItem temporary_page2 = AddPageWithoutDBEntry(); + OfflinePageItem temporary_page3 = AddPageWithoutFile(); generator()->SetArchiveDirectory(PrivateDir()); - OfflinePageItem page4 = AddPage(); - OfflinePageItem page5 = AddPageWithoutDBEntry(); - OfflinePageItem page6 = AddPageWithoutFile(); + OfflinePageItem temporary_page4 = AddPage(); + OfflinePageItem temporary_page5 = AddPageWithoutDBEntry(); + OfflinePageItem temporary_page6 = AddPageWithoutFile(); + // Adding a bunch of pages with different setups for persistent pages. + // |persistent_page1| will not be affected. + // |persistent_page2| will be deleted from Filesystem, since it's in private + // directory. + generator()->SetNamespace(kDownloadNamespace); + OfflinePageItem persistent_page1 = AddPage(); + OfflinePageItem persistent_page2 = AddPageWithoutDBEntry(); - EXPECT_EQ(4LL, store_test_util()->GetPageCount()); + EXPECT_EQ(5LL, store_test_util()->GetPageCount()); EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(TemporaryDir())); - EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(PrivateDir())); - EXPECT_EQ(PagePresence::FILESYSTEM_ONLY, CheckPagePresence(page2)); - EXPECT_EQ(PagePresence::DB_ONLY, CheckPagePresence(page3)); - EXPECT_EQ(PagePresence::FILESYSTEM_ONLY, CheckPagePresence(page5)); - EXPECT_EQ(PagePresence::DB_ONLY, CheckPagePresence(page6)); + EXPECT_EQ(4UL, test_utils::GetFileCountInDirectory(PrivateDir())); auto task = std::make_unique<StartupMaintenanceTask>( store(), archive_manager(), policy_controller()); @@ -254,61 +256,53 @@ EXPECT_EQ(2LL, store_test_util()->GetPageCount()); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(TemporaryDir())); EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); - EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, CheckPagePresence(page1)); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(page2)); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(page3)); - EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, CheckPagePresence(page4)); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(page5)); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(page6)); + + EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, + CheckPagePresence(temporary_page1)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page2)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page3)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page4)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page5)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(temporary_page6)); + + EXPECT_EQ(PagePresence::BOTH_DB_AND_FILESYSTEM, + CheckPagePresence(persistent_page1)); + EXPECT_EQ(PagePresence::NONE, CheckPagePresence(persistent_page2)); + histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount", 1, + "OfflinePages.ConsistencyCheck.Legacy.DeletedHeadlessFileCount", 2, 1); + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount", 2, 1); histogram_tester()->ExpectUniqueSample( "OfflinePages.ConsistencyCheck.Temporary.PagesMissingDbEntryCount", 1, 1); histogram_tester()->ExpectUniqueSample( "OfflinePages.ConsistencyCheck.Temporary.Result", static_cast<int>(SyncOperationResult::SUCCESS), 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount", - 1, 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount", 1, - 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.Result", - static_cast<int>(SyncOperationResult::SUCCESS), 1); } TEST_F(StartupMaintenanceTaskTest, TestKeepingNonMhtmlFile) { - // Create an offline page with mhtml extension but has no DB entry. + // Create a persistent offline page with mhtml extension but has no DB entry. + // It will not be deleted since it's in public directory. generator()->SetNamespace(kDownloadNamespace); - generator()->SetArchiveDirectory(PrivateDir()); + generator()->SetArchiveDirectory(PublicDir()); OfflinePageItem page1 = AddPageWithoutDBEntry(); - // Create a file with non-mhtml extension. + // Create a file with non-mhtml extension. It should not be affected. base::FilePath path; - base::CreateTemporaryFileInDir(PrivateDir(), &path); + base::CreateTemporaryFileInDir(PublicDir(), &path); base::FilePath mp3_path = path.AddExtension(FILE_PATH_LITERAL("mp3")); EXPECT_TRUE(base::Move(path, mp3_path)); EXPECT_EQ(0LL, store_test_util()->GetPageCount()); - EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(PrivateDir())); + EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(PublicDir())); auto task = std::make_unique<StartupMaintenanceTask>( store(), archive_manager(), policy_controller()); RunTask(std::move(task)); EXPECT_EQ(0LL, store_test_util()->GetPageCount()); - EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(PrivateDir())); - EXPECT_EQ(PagePresence::NONE, CheckPagePresence(page1)); - histogram_tester()->ExpectTotalCount( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount", - 0); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount", 1, - 1); - histogram_tester()->ExpectUniqueSample( - "OfflinePages.ConsistencyCheck.Persistent.Result", - static_cast<int>(SyncOperationResult::SUCCESS), 1); + EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(PublicDir())); + EXPECT_EQ(PagePresence::FILESYSTEM_ONLY, CheckPagePresence(page1)); } TEST_F(StartupMaintenanceTaskTest, TestReportStorageUsage) {
diff --git a/components/services/heap_profiling/public/cpp/settings.cc b/components/services/heap_profiling/public/cpp/settings.cc index 1d4bbc2c..72525f4 100644 --- a/components/services/heap_profiling/public/cpp/settings.cc +++ b/components/services/heap_profiling/public/cpp/settings.cc
@@ -42,17 +42,15 @@ Mode GetModeForStartup() { const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); #if BUILDFLAG(USE_ALLOCATOR_SHIM) + if (cmdline->HasSwitch("enable-heap-profiling")) { + LOG(ERROR) << "--enable-heap-profiling is no longer supported. Use " + "--memlog instead. See documentation at " + "docs/memory/debugging_memory_issues.md"; + return Mode::kNone; + } + if (cmdline->HasSwitch(kMemlog) || base::FeatureList::IsEnabled(kOOPHeapProfilingFeature)) { - if (cmdline->HasSwitch(switches::kEnableHeapProfiling)) { - // PartitionAlloc doesn't support chained allocation hooks so we can't - // run both heap profilers at the same time. - LOG(ERROR) << "--" << switches::kEnableHeapProfiling - << " specified with --" << kMemlog - << "which are not compatible. Memlog will be disabled."; - return Mode::kNone; - } - std::string mode; // Respect the commandline switch above the field trial. if (cmdline->HasSwitch(kMemlog)) {
diff --git a/components/tracing/common/trace_startup.cc b/components/tracing/common/trace_startup.cc index 54b6aedd..6ad1aeae 100644 --- a/components/tracing/common/trace_startup.cc +++ b/components/tracing/common/trace_startup.cc
@@ -22,10 +22,6 @@ // https://crbug.com/764357 base::trace_event::TraceLog::GetInstance(); - // Enables heap profiling if "--enable-heap-profiling" flag is passed. - base::trace_event::MemoryDumpManager::GetInstance() - ->EnableHeapProfilingIfNeeded(); - if (command_line.HasSwitch(switches::kTraceStartup)) { base::trace_event::TraceConfig trace_config( command_line.GetSwitchValueASCII(switches::kTraceStartup),
diff --git a/components/tracing/docs/heap_profiler_internals.md b/components/tracing/docs/heap_profiler_internals.md deleted file mode 100644 index a54e7f3..0000000 --- a/components/tracing/docs/heap_profiler_internals.md +++ /dev/null
@@ -1,2 +0,0 @@ -This document has moved to [//docs/memory-infra/heap_profiler_internals.md](/docs/memory-infra/heap_profiler_internals.md). -
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index 030a9c5..3653ec1 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn
@@ -14,7 +14,7 @@ "business.icon", "check_circle.icon", "close.icon", - "close_16.icon", + "close_rounded.icon", "edit.icon", "folder.icon", "folder_managed.icon",
diff --git a/components/vector_icons/aggregate_vector_icons.py b/components/vector_icons/aggregate_vector_icons.py index 112cf7bb..cc7f0c6 100644 --- a/components/vector_icons/aggregate_vector_icons.py +++ b/components/vector_icons/aggregate_vector_icons.py
@@ -28,21 +28,29 @@ return "k" + "".join(words) + suffix -def GetPathName(name, append_1x=False): - return CamelCase(name, "Path1x" if append_1x else "Path") +def GetPathName(name, size=None): + return CamelCase(name, "{}Path".format(size) if size != None else "Path") -def GetRepName(name, append_1x=False): - return CamelCase(name, "Rep1x" if append_1x else "Rep") +def GetRepListName(name): + return CamelCase(name, "RepList") def GetIconName(name): return CamelCase(name, "Icon") +def AddIconToDictionary(icon_file, new_icon, icon_size, icon_index): + if icon_size in icon_index: + Error("Duplicate icon of size {} found in {}.".format(icon_size, icon_file)) + icon_index[icon_size] = "\n".join(new_icon) + return icon_index + + def ExtractIconReps(icon_file_name): - """Reads the contents of the given icon file and returns a list of vector - commands for different icon representations stored in that file. + """Reads the contents of the given icon file and returns a dictionary of icon + sizes to vector commands for different icon representations stored in that + file. Args: icon_file_name: The file path of the icon file to read. @@ -50,9 +58,10 @@ with open(icon_file_name, "r") as icon_file: icon_file_contents = icon_file.readlines() + current_icon_size = REFERENCE_SIZE_DIP icon_sizes = [] current_icon_representation = [] - icon_representation_list = [] + icon_representations = {} for line in icon_file_contents: # Strip comments and empty lines. line = line.partition(CPP_COMMENT_DELIMITER)[0].strip() @@ -63,28 +72,34 @@ if line.startswith(CANVAS_DIMENSIONS): sizes = re.findall(r"\d+", line) if len(sizes) != 1: - Error("Malformed {} line found in {} - it should only specify one size." + Error("Malformed {} line in {} - it should specify exactly one size." .format(CANVAS_DIMENSIONS, icon_file_name)) icon_sizes.append(int(sizes[0])) # All icons except the first / default icon must start with # "CANVAS_DIMENSIONS", so rely on it here as a icon delimiter. if current_icon_representation: - icon_representation_list.append("\n".join(current_icon_representation)) + icon_representations = AddIconToDictionary( + icon_file_name, current_icon_representation, current_icon_size, + icon_representations) current_icon_representation = [] + current_icon_size = icon_sizes[-1] + current_icon_representation.append(line) if current_icon_representation: - icon_representation_list.append("\n".join(current_icon_representation)) + icon_representations = AddIconToDictionary( + icon_file_name, current_icon_representation, current_icon_size, + icon_representations) - if not icon_representation_list: + if not icon_representations: Error("Didn't find any icons in {}.".format(icon_file_name)) - if len(icon_representation_list) != len(icon_sizes): + if len(icon_representations) != len(icon_sizes): icon_sizes.insert(0, REFERENCE_SIZE_DIP) if sorted(icon_sizes, reverse=True) != icon_sizes: Error("The icons in {} should be sorted in descending order of size." .format(icon_file_name)) - return icon_representation_list + return icon_representations def AggregateVectorIcons(working_directory, file_list, output_cc, output_h): @@ -157,34 +172,24 @@ (icon_name, extension) = os.path.splitext( os.path.basename(path_map[icon])) - # Store the vector-drawing commands for foo_bar.icon in the temporary - # variable kFooBarPath. - icon_representation_list = ExtractIconReps(path_map[icon]) - (vector_commands, vector_commands_1x) = None, None - if len(icon_representation_list) >= 1: - vector_commands = icon_representation_list[0] - if len(icon_representation_list) >= 2: - vector_commands_1x = icon_representation_list[1] - if len(icon_representation_list) >= 3: - print "Warning: " + path_map[icon] + " has more than two icon", \ - "representations. Support for this is still a WIP - see", \ - "crbug.com/647286. For now, only the first two will be used." - output_cc.write("VECTOR_ICON_REP_TEMPLATE({}, {}, {})\n".format( - GetPathName(icon_name), GetRepName(icon_name), vector_commands)) + icon_representations = ExtractIconReps(path_map[icon]) + icon_representation_strings = [] + for i, size in enumerate(sorted(icon_representations, reverse=True)): + vector_commands = icon_representations[size] + icon_path_name = GetPathName(icon_name, size if i != 0 else None) + # Store the vector-drawing commands for foo_bar.icon in the temporary + # variable kFooBarPath. + output_cc.write("VECTOR_ICON_REP_TEMPLATE({}, {})\n".format( + icon_path_name, vector_commands)) + icon_representation_strings.append( + "{{{0}, arraysize({0})}}".format(icon_path_name)) - # Store the vector-drawing commands for foo_bar.icon's 1x version in the - # temporary variable kFooBarPath1x, if it exists. - if vector_commands_1x: - output_cc.write("VECTOR_ICON_REP_TEMPLATE({}, {}, {})\n".format( - GetPathName(icon_name, True), GetRepName(icon_name, True), - vector_commands_1x)) - output_cc.write("VECTOR_ICON_TEMPLATE2({}, {}, {})\n".format( - GetIconName(icon_name), GetRepName(icon_name), - GetRepName(icon_name, True))) - else: - # Define the value of kFooBarIcon. - output_cc.write("VECTOR_ICON_TEMPLATE({}, {})\n".format( - GetIconName(icon_name), GetRepName(icon_name))) + # Another temporary variable kFooBarRepList is used to create all the + # VectorIconReps inline, with a pointer to it in the final VectorIcon. + output_cc.write("VECTOR_ICON_TEMPLATE_CC({}, {}, {})\n".format( + GetRepListName(icon_name), GetIconName(icon_name), + ", ".join(icon_representation_strings))) + output_cc.close()
diff --git a/components/vector_icons/cc_macros.h b/components/vector_icons/cc_macros.h index eba40a59..e51c4d4 100644 --- a/components/vector_icons/cc_macros.h +++ b/components/vector_icons/cc_macros.h
@@ -15,19 +15,14 @@ #define VECTOR_ICON_ID_PREFIX "" #endif -#define VECTOR_ICON_REP_TEMPLATE(path_name, rep_name, ...) \ - static constexpr gfx::PathElement path_name[] = {__VA_ARGS__}; \ - constexpr gfx::VectorIconRep rep_name = {path_name, arraysize(path_name)}; +#define VECTOR_ICON_REP_TEMPLATE(path_name, ...) \ + static constexpr gfx::PathElement path_name[] = {__VA_ARGS__}; -// The VectorIcon will be called kMyIcon, and the identifier for the icon might -// be "my_namespace::kMyIconId". -#define VECTOR_ICON_TEMPLATE(icon_name, rep_name) \ - const char icon_name##Id[] = VECTOR_ICON_ID_PREFIX #icon_name; \ - const gfx::VectorIcon icon_name = {&rep_name, nullptr, icon_name##Id}; - -#define VECTOR_ICON_TEMPLATE2(icon_name, rep_name, rep_name_1x) \ - const char icon_name##Id[] = VECTOR_ICON_ID_PREFIX #icon_name; \ - const gfx::VectorIcon icon_name = {&rep_name, &rep_name_1x, icon_name##Id}; +#define VECTOR_ICON_TEMPLATE_CC(rep_list_name, icon_name, ...) \ + constexpr char icon_name##Id[] = VECTOR_ICON_ID_PREFIX #icon_name; \ + static constexpr gfx::VectorIconRep rep_list_name[] = {__VA_ARGS__}; \ + const gfx::VectorIcon icon_name = {rep_list_name, arraysize(rep_list_name), \ + icon_name##Id}; #else // !COMPONENTS_VECTOR_ICONS_CC_MACROS_H_ #error This file should only be included once.
diff --git a/components/vector_icons/close_16.icon b/components/vector_icons/close_rounded.icon similarity index 100% rename from components/vector_icons/close_16.icon rename to components/vector_icons/close_rounded.icon
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 2de849a..7ca1d13f 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -818,6 +818,13 @@ } template <> +bool FuzzyForSoftwareOnlyPixelComparator<SkiaRenderer>::Compare( + const SkBitmap& actual_bmp, + const SkBitmap& expected_bmp) const { + return fuzzy_.Compare(actual_bmp, expected_bmp); +} + +template <> bool FuzzyForSoftwareOnlyPixelComparator< cc::SoftwareRendererWithExpandedViewport>:: Compare(const SkBitmap& actual_bmp, const SkBitmap& expected_bmp) const { @@ -1804,7 +1811,7 @@ cc::FuzzyPixelOffByOneComparator(true))); } -TYPED_TEST(NonSkiaRendererPixelTest, FastPassColorFilterAlpha) { +TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { gfx::Rect viewport_rect(this->device_viewport_size_); int root_pass_id = 1; @@ -1882,7 +1889,7 @@ FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); } -TYPED_TEST(NonSkiaRendererPixelTest, FastPassSaturateFilter) { +TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) { gfx::Rect viewport_rect(this->device_viewport_size_); int root_pass_id = 1; @@ -1942,7 +1949,7 @@ FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); } -TYPED_TEST(NonSkiaRendererPixelTest, FastPassFilterChain) { +TYPED_TEST(RendererPixelTest, FastPassFilterChain) { gfx::Rect viewport_rect(this->device_viewport_size_); int root_pass_id = 1; @@ -2004,7 +2011,7 @@ FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); } -TYPED_TEST(NonSkiaRendererPixelTest, FastPassColorFilterAlphaTranslation) { +TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { gfx::Rect viewport_rect(this->device_viewport_size_); int root_pass_id = 1;
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index f05f50d..060a293 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -114,7 +114,9 @@ std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread, scoped_refptr<base::SingleThreadTaskRunner> io_runner, const gpu::GpuFeatureInfo& gpu_feature_info, - const gpu::GpuPreferences& gpu_preferences) + const gpu::GpuPreferences& gpu_preferences, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) : main_runner_(base::ThreadTaskRunnerHandle::Get()), io_runner_(std::move(io_runner)), watchdog_thread_(std::move(watchdog_thread)), @@ -123,6 +125,8 @@ gpu_preferences_(gpu_preferences), gpu_info_(gpu_info), gpu_feature_info_(gpu_feature_info), + gpu_info_for_hardware_gpu_(gpu_info_for_hardware_gpu), + gpu_feature_info_for_hardware_gpu_(gpu_feature_info_for_hardware_gpu), bindings_(std::make_unique<mojo::BindingSet<mojom::GpuService>>()), weak_ptr_factory_(this) { DCHECK(!io_runner_->BelongsToCurrentThread()); @@ -190,7 +194,9 @@ gpu::SyncPointManager* sync_point_manager, base::WaitableEvent* shutdown_event) { DCHECK(main_runner_->BelongsToCurrentThread()); - gpu_host->DidInitialize(gpu_info_, gpu_feature_info_); + gpu_host->DidInitialize(gpu_info_, gpu_feature_info_, + gpu_info_for_hardware_gpu_, + gpu_feature_info_for_hardware_gpu_); gpu_host_ = mojom::ThreadSafeGpuHostPtr::Create(gpu_host.PassInterface(), io_runner_); if (!in_host_process()) {
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h index a29e320f..8abf60c 100644 --- a/components/viz/service/gl/gpu_service_impl.h +++ b/components/viz/service/gl/gpu_service_impl.h
@@ -62,7 +62,9 @@ std::unique_ptr<gpu::GpuWatchdogThread> watchdog, scoped_refptr<base::SingleThreadTaskRunner> io_runner, const gpu::GpuFeatureInfo& gpu_feature_info, - const gpu::GpuPreferences& gpu_preferences); + const gpu::GpuPreferences& gpu_preferences, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu); ~GpuServiceImpl() override; @@ -226,6 +228,11 @@ // Information about general chrome feature support for the GPU. gpu::GpuFeatureInfo gpu_feature_info_; + // What we would have gotten if we haven't fallen back to SwiftShader or + // pure software (in the viz case). + gpu::GPUInfo gpu_info_for_hardware_gpu_; + gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu_; + scoped_refptr<mojom::ThreadSafeGpuHostPtr> gpu_host_; std::unique_ptr<gpu::GpuChannelManager> gpu_channel_manager_; std::unique_ptr<media::MediaGpuChannelManager> media_gpu_channel_manager_;
diff --git a/components/viz/service/gl/gpu_service_impl_unittest.cc b/components/viz/service/gl/gpu_service_impl_unittest.cc index c36a072f..db04e5f2 100644 --- a/components/viz/service/gl/gpu_service_impl_unittest.cc +++ b/components/viz/service/gl/gpu_service_impl_unittest.cc
@@ -51,7 +51,8 @@ ASSERT_TRUE(io_thread_.Start()); gpu_service_ = std::make_unique<GpuServiceImpl>( gpu::GPUInfo(), nullptr /* watchdog_thread */, io_thread_.task_runner(), - gpu::GpuFeatureInfo(), gpu::GpuPreferences()); + gpu::GpuFeatureInfo(), gpu::GpuPreferences(), gpu::GPUInfo(), + gpu::GpuFeatureInfo()); } void TearDown() override {
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index 7738314c..df94129 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -143,7 +143,9 @@ gpu_service_ = std::make_unique<GpuServiceImpl>( gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), io_task_runner(), - gpu_init_->gpu_feature_info(), gpu_init_->gpu_preferences()); + gpu_init_->gpu_feature_info(), gpu_init_->gpu_preferences(), + gpu_init_->gpu_info_for_hardware_gpu(), + gpu_init_->gpu_feature_info_for_hardware_gpu()); } VizMainImpl::~VizMainImpl() {
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 07b04a9..672e288 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -279,7 +279,6 @@ // to the zygote/renderers. static const char* const kForwardSwitches[] = { switches::kAndroidFontsPath, switches::kClearKeyCdmPathForTesting, - switches::kEnableHeapProfiling, switches::kEnableLogging, // Support, e.g., --enable-logging=stderr. // Need to tell the zygote that it is headless so that we don't try to use // the wrong type of main delegate.
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 7e20243..2bd827526 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -160,7 +160,6 @@ #endif #if defined(OS_MACOSX) -#include "base/allocator/allocator_interception_mac.h" #include "base/memory/memory_pressure_monitor_mac.h" #include "content/browser/cocoa/system_hotkey_helper_mac.h" #include "content/browser/mach_broker_mac.h" @@ -774,14 +773,6 @@ InitializeMemoryManagementComponent(); -#if defined(OS_MACOSX) - if (base::CommandLine::InitializedForCurrentProcess() && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableHeapProfiling)) { - base::allocator::PeriodicallyShimNewMallocZones(); - } -#endif - #if BUILDFLAG(ENABLE_PLUGINS) // Prior to any processing happening on the IO thread, we create the // plugin service as it is predominantly used from the IO thread,
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index dab07a8c..36344ef 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -175,11 +175,14 @@ browser_plugin_instance_id_)); } -void BrowserPluginGuest::ResizeDueToAutoResize(const gfx::Size& new_size, - uint64_t sequence_number) { +void BrowserPluginGuest::ResizeDueToAutoResize( + const gfx::Size& new_size, + uint64_t sequence_number, + const viz::LocalSurfaceId& child_allocated_surface_id) { SendMessageToEmbedder( std::make_unique<BrowserPluginMsg_ResizeDueToAutoResize>( - browser_plugin_instance_id_, sequence_number)); + browser_plugin_instance_id_, sequence_number, + child_allocated_surface_id)); } void BrowserPluginGuest::SizeContents(const gfx::Size& new_size) { @@ -1038,7 +1041,8 @@ const FrameResizeParams& resize_params) { if (local_surface_id_ > local_surface_id || ((frame_rect_.size() != resize_params.screen_space_rect.size() || - screen_info_ != resize_params.screen_info) && + screen_info_ != resize_params.screen_info || + capture_sequence_number_ != resize_params.capture_sequence_number) && local_surface_id_ == local_surface_id)) { SiteInstance* owner_site_instance = delegate_->GetOwnerSiteInstance(); bad_message::ReceivedBadMessage( @@ -1051,11 +1055,22 @@ frame_rect_ = resize_params.screen_space_rect; GetWebContents()->SendScreenRects(); local_surface_id_ = local_surface_id; + bool capture_sequence_number_changed = + capture_sequence_number_ != resize_params.capture_sequence_number; + capture_sequence_number_ = resize_params.capture_sequence_number; RenderWidgetHostView* view = web_contents()->GetRenderWidgetHostView(); if (!view) return; + // We could add functionality to set a specific capture sequence number on the + // |view|, but knowing that it's changed is sufficient for us simply request + // that our RenderWidgetHostView synchronizes its surfaces. Note that this + // should only happen during layout tests, since that is the only call that + // should trigger the capture sequence number to change. + if (capture_sequence_number_changed) + view->EnsureSurfaceSynchronizedForLayoutTest(); + RenderWidgetHostImpl* render_widget_host = RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); DCHECK(render_widget_host);
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index 50b3c014..c6df5805 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -30,6 +30,7 @@ #include "base/values.h" #include "build/build_config.h" #include "components/viz/common/surfaces/local_surface_id.h" +#include "components/viz/common/surfaces/scoped_surface_id_allocator.h" #include "content/common/edit_command.h" #include "content/public/browser/browser_plugin_guest_delegate.h" #include "content/public/browser/guest_host.h" @@ -181,8 +182,10 @@ void EnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size); void DisableAutoResize(); - void ResizeDueToAutoResize(const gfx::Size& new_size, - uint64_t sequence_number); + void ResizeDueToAutoResize( + const gfx::Size& new_size, + uint64_t sequence_number, + const viz::LocalSurfaceId& child_allocated_surface_id); // WebContentsObserver implementation. void DidFinishNavigation(NavigationHandle* navigation_handle) override; @@ -450,6 +453,7 @@ viz::LocalSurfaceId local_surface_id_; ScreenInfo screen_info_; + uint32_t capture_sequence_number_ = 0u; // Weak pointer used to ask GeolocationPermissionContext about geolocation // permission.
diff --git a/content/browser/browser_plugin/browser_plugin_message_filter.cc b/content/browser/browser_plugin/browser_plugin_message_filter.cc index fec9859..93bf2a1 100644 --- a/content/browser/browser_plugin/browser_plugin_message_filter.cc +++ b/content/browser/browser_plugin/browser_plugin_message_filter.cc
@@ -28,6 +28,11 @@ bool BrowserPluginMessageFilter::OnMessageReceived( const IPC::Message& message) { + if (sub_filter_for_testing_ && + sub_filter_for_testing_->OnMessageReceived(message)) { + return true; + } + // Any message requested by a BrowserPluginGuest should be routed through // a BrowserPluginGuestManager. if (BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(message)) { @@ -82,4 +87,9 @@ ->OnMessageReceivedFromEmbedder(message); } +void BrowserPluginMessageFilter::SetSubFilterForTesting( + scoped_refptr<BrowserMessageFilter> sub_filter) { + sub_filter_for_testing_ = sub_filter; +} + } // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_message_filter.h b/content/browser/browser_plugin/browser_plugin_message_filter.h index 646f4248..7c03bd3 100644 --- a/content/browser/browser_plugin/browser_plugin_message_filter.h +++ b/content/browser/browser_plugin/browser_plugin_message_filter.h
@@ -23,6 +23,9 @@ bool OnMessageReceived(const IPC::Message& message) override; void OnDestruct() const override; + // Test-only functions: + void SetSubFilterForTesting(scoped_refptr<BrowserMessageFilter> sub_filter); + private: friend class BrowserThread; friend class base::DeleteHelper<BrowserPluginMessageFilter>; @@ -33,6 +36,8 @@ const int render_process_id_; + scoped_refptr<BrowserMessageFilter> sub_filter_for_testing_; + DISALLOW_COPY_AND_ASSIGN(BrowserPluginMessageFilter); };
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl.cc b/content/browser/browsing_data/browsing_data_filter_builder_impl.cc index 74ba9ff..dd806b36 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl.cc +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl.cc
@@ -56,17 +56,6 @@ (mode == BrowsingDataFilterBuilder::WHITELIST)); } -// True if none of the supplied domains matches this Channel ID's server ID -// and we're a blacklist, or one of them does and we're a whitelist. -// The whitelist or blacklist is represented as |domains_and_ips| and |mode|. -bool MatchesChannelIDForRegisterableDomainsAndIPs( - const std::set<std::string>& domains_and_ips, - BrowsingDataFilterBuilder::Mode mode, - const std::string& channel_id_server_id) { - return ((mode == BrowsingDataFilterBuilder::WHITELIST) == - (domains_and_ips.find(channel_id_server_id) != domains_and_ips.end())); -} - // True if none of the supplied domains matches this plugin's |site| and we're // a blacklist, or one of them does and we're a whitelist. The whitelist or // blacklist is represented by |domains_and_ips| and |mode|. @@ -138,13 +127,13 @@ return base::BindRepeating(&MatchesURL, origins_, domains_, mode_); } -network::mojom::ClearCacheUrlFilterPtr -BrowsingDataFilterBuilderImpl::BuildClearCacheUrlFilter() const { - network::mojom::ClearCacheUrlFilterPtr filter = - network::mojom::ClearCacheUrlFilter::New(); +network::mojom::ClearDataFilterPtr +BrowsingDataFilterBuilderImpl::BuildNetworkServiceFilter() const { + network::mojom::ClearDataFilterPtr filter = + network::mojom::ClearDataFilter::New(); filter->type = (mode_ == Mode::WHITELIST) - ? network::mojom::ClearCacheUrlFilter::Type::DELETE_MATCHES - : network::mojom::ClearCacheUrlFilter::Type::KEEP_MATCHES; + ? network::mojom::ClearDataFilter::Type::DELETE_MATCHES + : network::mojom::ClearDataFilter::Type::KEEP_MATCHES; filter->origins.insert(filter->origins.begin(), origins_.begin(), origins_.end()); filter->domains.insert(filter->domains.begin(), domains_.begin(), @@ -172,15 +161,6 @@ return delete_info; } -base::RepeatingCallback<bool(const std::string& channel_id_server_id)> -BrowsingDataFilterBuilderImpl::BuildChannelIDFilter() const { - DCHECK(origins_.empty()) << - "Origin-based deletion is not suitable for channel IDs. Please use " - "different scoping, such as RegistrableDomainFilterBuilder."; - return base::BindRepeating(&MatchesChannelIDForRegisterableDomainsAndIPs, - domains_, mode_); -} - base::RepeatingCallback<bool(const std::string& site)> BrowsingDataFilterBuilderImpl::BuildPluginFilter() const { DCHECK(origins_.empty()) <<
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl.h b/content/browser/browsing_data/browsing_data_filter_builder_impl.h index 0eb04b8a..43aeac9 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl.h +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl.h
@@ -24,11 +24,8 @@ bool IsEmptyBlacklist() const override; base::RepeatingCallback<bool(const GURL&)> BuildGeneralFilter() const override; - network::mojom::ClearCacheUrlFilterPtr BuildClearCacheUrlFilter() - const override; + network::mojom::ClearDataFilterPtr BuildNetworkServiceFilter() const override; net::CookieStore::CookieDeletionInfo BuildCookieDeletionInfo() const override; - base::RepeatingCallback<bool(const std::string& server_id)> - BuildChannelIDFilter() const override; base::RepeatingCallback<bool(const std::string& site)> BuildPluginFilter() const override; Mode GetMode() const override;
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc index 7e9cfb0..549b57f 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "net/cookies/canonical_cookie.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -301,68 +302,42 @@ RunTestCase(test_case, builder.BuildCookieDeletionInfo()); } -TEST(BrowsingDataFilterBuilderImplTest, - RegistrableDomainMatchesChannelIDsWhitelist) { +TEST(BrowsingDataFilterBuilderImplTest, NetworkServiceFilterWhitelist) { BrowsingDataFilterBuilderImpl builder( BrowsingDataFilterBuilderImpl::WHITELIST); + ASSERT_EQ(BrowsingDataFilterBuilderImpl::WHITELIST, builder.GetMode()); builder.AddRegisterableDomain(std::string(kGoogleDomain)); builder.AddRegisterableDomain(std::string(kLongETLDDomain)); builder.AddRegisterableDomain(std::string(kIPAddress)); builder.AddRegisterableDomain(std::string(kUnknownRegistryDomain)); builder.AddRegisterableDomain(std::string(kInternalHostname)); - base::Callback<bool(const std::string&)> filter = - builder.BuildChannelIDFilter(); + network::mojom::ClearDataFilterPtr filter = + builder.BuildNetworkServiceFilter(); - TestCase test_cases[] = { - // Channel ID server identifiers can be second level domains, ... - {"google.com", true}, - {"website.sp.nom.br", true}, - {"second-level-domain.fileserver", true}, - - // ... IP addresses, or internal hostnames. - {"192.168.1.1", true}, - {"fileserver", true}, - - // Channel IDs not in the whitelist are not matched. - {"example.com", false}, - {"192.168.1.2", false}, - {"website.fileserver", false}, - }; - - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + EXPECT_EQ(network::mojom::ClearDataFilter_Type::DELETE_MATCHES, filter->type); + EXPECT_THAT(filter->domains, testing::UnorderedElementsAre( + kGoogleDomain, kLongETLDDomain, kIPAddress, + kUnknownRegistryDomain, kInternalHostname)); + EXPECT_TRUE(filter->origins.empty()); } -TEST(BrowsingDataFilterBuilderImplTest, - RegistrableDomainMatchesChannelIDsBlacklist) { +TEST(BrowsingDataFilterBuilderImplTest, NetworkServiceFilterBlacklist) { BrowsingDataFilterBuilderImpl builder( BrowsingDataFilterBuilderImpl::BLACKLIST); + ASSERT_EQ(BrowsingDataFilterBuilderImpl::BLACKLIST, builder.GetMode()); builder.AddRegisterableDomain(std::string(kGoogleDomain)); builder.AddRegisterableDomain(std::string(kLongETLDDomain)); builder.AddRegisterableDomain(std::string(kIPAddress)); builder.AddRegisterableDomain(std::string(kUnknownRegistryDomain)); builder.AddRegisterableDomain(std::string(kInternalHostname)); - base::Callback<bool(const std::string&)> filter = - builder.BuildChannelIDFilter(); + network::mojom::ClearDataFilterPtr filter = + builder.BuildNetworkServiceFilter(); - TestCase test_cases[] = { - // Channel ID server identifiers can be second level domains, ... - {"google.com", false}, - {"website.sp.nom.br", false}, - {"second-level-domain.fileserver", false}, - - // ...IP addresses, or internal hostnames. - {"192.168.1.1", false}, - {"fileserver", false}, - - // Channel IDs that are not blacklisted are matched. - {"example.com", true}, - {"192.168.1.2", true}, - {"website.fileserver", true}, - }; - - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + EXPECT_EQ(network::mojom::ClearDataFilter_Type::KEEP_MATCHES, filter->type); + EXPECT_THAT(filter->domains, testing::UnorderedElementsAre( + kGoogleDomain, kLongETLDDomain, kIPAddress, + kUnknownRegistryDomain, kInternalHostname)); + EXPECT_TRUE(filter->origins.empty()); } TEST(BrowsingDataFilterBuilderImplTest,
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc index 5ded314..02f81bec 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -119,34 +119,31 @@ http_session->CloseAllConnections(); } -void OnClearedChannelIDsOnIOThread(net::URLRequestContextGetter* rq_context, - base::OnceClosure callback) { +void OnClearedChannelIDsOnIOThread( + net::URLRequestContextGetter* request_context, + base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Need to close open SSL connections which may be using the channel ids we // are deleting. // TODO(mattm): http://crbug.com/166069 Make the server bound cert // service/store have observers that can notify relevant things directly. - rq_context->GetURLRequestContext() + // TODO(ericorth): http://crbug.com/824970 Move this over to the network + // service and handle within ClearChannelIds(). + request_context->GetURLRequestContext() ->ssl_config_service() ->NotifySSLConfigChange(); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback)); } -void ClearChannelIDsOnIOThread( - const base::Callback<bool(const std::string&)>& domain_predicate, - base::Time delete_begin, - base::Time delete_end, +void OnClearedChannelIDs( scoped_refptr<net::URLRequestContextGetter> request_context, base::OnceClosure callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::ChannelIDService* channel_id_service = - request_context->GetURLRequestContext()->channel_id_service(); - channel_id_service->GetChannelIDStore()->DeleteForDomainsCreatedBetween( - domain_predicate, delete_begin, delete_end, - base::Bind(&OnClearedChannelIDsOnIOThread, - base::RetainedRef(std::move(request_context)), - base::Passed(std::move(callback)))); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&OnClearedChannelIDsOnIOThread, + base::RetainedRef(std::move(request_context)), + std::move(callback))); } } // namespace @@ -353,16 +350,22 @@ !(remove_mask & DATA_TYPE_AVOID_CLOSING_CONNECTIONS) && origin_type_mask_ & ORIGIN_TYPE_UNPROTECTED_WEB) { base::RecordAction(UserMetricsAction("ClearBrowsingData_ChannelIDs")); + + network::mojom::ClearDataFilterPtr service_filter = + filter_builder.BuildNetworkServiceFilter(); + DCHECK(service_filter->origins.empty()) + << "Origin-based deletion is not suitable for channel IDs."; + // Since we are running on the UI thread don't call GetURLRequestContext(). scoped_refptr<net::URLRequestContextGetter> request_context = BrowserContext::GetDefaultStoragePartition(browser_context_) ->GetURLRequestContext(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&ClearChannelIDsOnIOThread, - filter_builder.BuildChannelIDFilter(), delete_begin_, - delete_end_, std::move(request_context), - CreatePendingTaskCompletionClosure())); + BrowserContext::GetDefaultStoragePartition(browser_context_) + ->GetNetworkContext() + ->ClearChannelIds( + delete_begin, delete_end, std::move(service_filter), + base::BindOnce(&OnClearedChannelIDs, std::move(request_context), + CreatePendingTaskCompletionClosureForMojo())); } ////////////////////////////////////////////////////////////////////////////// @@ -469,7 +472,7 @@ // The clearing of the HTTP cache happens in the network service process // when enabled. network_context->ClearHttpCache( - delete_begin, delete_end, filter_builder.BuildClearCacheUrlFilter(), + delete_begin, delete_end, filter_builder.BuildNetworkServiceFilter(), CreatePendingTaskCompletionClosureForMojo()); }
diff --git a/content/browser/devtools/protocol/system_info_handler.cc b/content/browser/devtools/protocol/system_info_handler.cc index 3a90a35d..ca7da4d 100644 --- a/content/browser/devtools/protocol/system_info_handler.cc +++ b/content/browser/devtools/protocol/system_info_handler.cc
@@ -184,7 +184,8 @@ // TODO(zmo): CHECK everywhere once https://crbug.com/796386 is fixed. gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfoWithHardwareAccelerationDisabled(); - GpuDataManagerImpl::GetInstance()->UpdateGpuFeatureInfo(gpu_feature_info); + GpuDataManagerImpl::GetInstance()->UpdateGpuFeatureInfo( + gpu_feature_info, gpu::GpuFeatureInfo()); UnregisterAndSendResponse(); #else CHECK(false) << "Gathering system GPU info took more than 5 seconds.";
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index 5f115f0..33b531e 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -276,7 +276,8 @@ // If the |screen_space_rect| or |screen_info| of the frame has changed, then // the viz::LocalSurfaceId must also change. if ((last_received_local_frame_size_ != resize_params.local_frame_size || - screen_info_ != resize_params.screen_info) && + screen_info_ != resize_params.screen_info || + capture_sequence_number() != resize_params.capture_sequence_number) && local_surface_id_ == surface_id.local_surface_id()) { bad_message::ReceivedBadMessage( frame_proxy_in_parent_renderer_->GetProcess(), @@ -404,15 +405,12 @@ } #endif -void CrossProcessFrameConnector::BeginResizeDueToAutoResize() { - frame_proxy_in_parent_renderer_->Send(new FrameMsg_BeginResizeDueToAutoResize( - frame_proxy_in_parent_renderer_->GetRoutingID())); -} - -void CrossProcessFrameConnector::EndResizeDueToAutoResize( - uint64_t sequence_number) { - frame_proxy_in_parent_renderer_->Send(new FrameMsg_EndResizeDueToAutoResize( - frame_proxy_in_parent_renderer_->GetRoutingID(), sequence_number)); +void CrossProcessFrameConnector::ResizeDueToAutoResize( + uint64_t sequence_number, + const viz::LocalSurfaceId& child_allocated_surface_id) { + frame_proxy_in_parent_renderer_->Send(new FrameMsg_ResizeDueToAutoResize( + frame_proxy_in_parent_renderer_->GetRoutingID(), sequence_number, + child_allocated_surface_id)); } void CrossProcessFrameConnector::SetVisibilityForChildViews(
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index 422a1ec..0990cbdf 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -111,8 +111,9 @@ void EmbedRendererWindowTreeClientInParent( ui::mojom::WindowTreeClientPtr window_tree_client) override; #endif - void BeginResizeDueToAutoResize() override; - void EndResizeDueToAutoResize(uint64_t sequence_number) override; + void ResizeDueToAutoResize( + uint64_t sequence_number, + const viz::LocalSurfaceId& child_allocated_surface_id) override; // Set the visibility of immediate child views, i.e. views whose parent view // is |view_|.
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index 20d0922..f7f5a6ce 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -693,13 +693,9 @@ const gfx::Size& new_size, uint64_t sequence_number, const viz::LocalSurfaceId& local_surface_id) { - // TODO(cblume): This doesn't currently suppress allocation. - // It maintains existing behavior while using the suppression style. - // This will be addressed in a follow-up patch. - // See https://crbug.com/805073 base::OnceCallback<void()> allocation_task = base::BindOnce(&BrowserPluginGuest::ResizeDueToAutoResize, guest_, - new_size, sequence_number); + new_size, sequence_number, local_surface_id); return viz::ScopedSurfaceIdAllocator(std::move(allocation_task)); }
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 741a816..5946d9f5 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -26,6 +26,9 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" +#include "gpu/config/gpu_blacklist.h" +#include "gpu/config/gpu_driver_bug_list.h" +#include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/config/gpu_feature_type.h" #include "gpu/config/gpu_finch_features.h" #include "gpu/config/gpu_switches.h" @@ -42,6 +45,8 @@ const int kMinMSAASampleCount = 0; +enum class GpuFeatureInfoType { kCurrent, kForHardwareGpu }; + struct GpuFeatureData { std::string name; gpu::GpuFeatureStatus status; @@ -56,80 +61,96 @@ return command_line->HasSwitch(switches::kForceGpuRasterization); } -gpu::GpuFeatureStatus SafeGetFeatureStatus(GpuDataManagerImpl* manager, - gpu::GpuFeatureType feature) { - if (!manager->IsGpuFeatureInfoAvailable()) { +gpu::GpuFeatureStatus SafeGetFeatureStatus( + const gpu::GpuFeatureInfo& gpu_feature_info, + gpu::GpuFeatureType feature) { + if (!gpu_feature_info.IsInitialized()) { // The GPU process probably crashed during startup, but we can't // assert this as the test bots are slow, and recording the crash // is racy. Be robust and just say that all features are disabled. return gpu::kGpuFeatureStatusDisabled; } - return manager->GetFeatureStatus(feature); + DCHECK(feature >= 0 && feature < gpu::NUMBER_OF_GPU_FEATURE_TYPES); + return gpu_feature_info.status_values[feature]; } -gpu::GpuFeatureStatus GetGpuCompositingStatus() { +gpu::GpuFeatureStatus GetGpuCompositingStatus( + const gpu::GpuFeatureInfo& gpu_feature_info, + GpuFeatureInfoType type) { gpu::GpuFeatureStatus status = SafeGetFeatureStatus( - GpuDataManagerImpl::GetInstance(), gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING); + gpu_feature_info, gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING); #if defined(USE_AURA) || defined(OS_MACOSX) - if (status == gpu::kGpuFeatureStatusEnabled && + if (type == GpuFeatureInfoType::kCurrent && + status == gpu::kGpuFeatureStatusEnabled && ImageTransportFactory::GetInstance()->IsGpuCompositingDisabled()) { + // We only adjust the status for kCurrent, because compositing status + // affects other feature status, and we want to preserve the kHardwareGpu + // feature status and don't want them to be modified by the current + // compositing status. status = gpu::kGpuFeatureStatusDisabled; } #endif return status; } -const GpuFeatureData GetGpuFeatureData(size_t index, bool* eof) { +const GpuFeatureData GetGpuFeatureData( + const gpu::GpuFeatureInfo& gpu_feature_info, + GpuFeatureInfoType type, + size_t index, + bool* eof) { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); const GpuFeatureData kGpuFeatureData[] = { {"2d_canvas", - SafeGetFeatureStatus(manager, + SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS), command_line.HasSwitch(switches::kDisableAccelerated2dCanvas), - "Accelerated 2D canvas is unavailable: either disabled via blacklist or " - "the command line.", + "Accelerated 2D canvas is unavailable: either disabled via blacklist or" + " the command line.", true, true}, - {"gpu_compositing", GetGpuCompositingStatus(), + {"gpu_compositing", GetGpuCompositingStatus(gpu_feature_info, type), command_line.HasSwitch(switches::kDisableGpuCompositing), "Gpu compositing has been disabled, either via blacklist, about:flags " "or the command line. The browser will fall back to software " "compositing and hardware acceleration will be unavailable.", true, true}, {"webgl", - SafeGetFeatureStatus(manager, gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL), + SafeGetFeatureStatus(gpu_feature_info, + gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL), command_line.HasSwitch(switches::kDisableWebGL), "WebGL has been disabled via blacklist or the command line.", false, true}, - {"flash_3d", SafeGetFeatureStatus(manager, gpu::GPU_FEATURE_TYPE_FLASH3D), + {"flash_3d", + SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_FLASH3D), command_line.HasSwitch(switches::kDisableFlash3d), "Using 3d in flash has been disabled, either via blacklist, about:flags " "or the command line.", true, true}, {"flash_stage3d", - SafeGetFeatureStatus(manager, gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D), + SafeGetFeatureStatus(gpu_feature_info, + gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D), command_line.HasSwitch(switches::kDisableFlashStage3d), "Using Stage3d in Flash has been disabled, either via blacklist, " "about:flags or the command line.", true, true}, {"flash_stage3d_baseline", - SafeGetFeatureStatus(manager, + SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE), command_line.HasSwitch(switches::kDisableFlashStage3d), "Using Stage3d Baseline profile in Flash has been disabled, either via " "blacklist, about:flags or the command line.", true, true}, {"video_decode", - SafeGetFeatureStatus(manager, + SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE), command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), "Accelerated video decode has been disabled, either via blacklist, " "about:flags or the command line.", true, true}, {"rasterization", - SafeGetFeatureStatus(manager, gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION), + SafeGetFeatureStatus(gpu_feature_info, + gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION), (command_line.HasSwitch(switches::kDisableGpuRasterization) && !IsForceGpuRasterizationEnabled()), "Accelerated rasterization has been disabled, either via blacklist, " @@ -149,7 +170,8 @@ "line.", false, false}, {"webgl2", - SafeGetFeatureStatus(manager, gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2), + SafeGetFeatureStatus(gpu_feature_info, + gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2), (command_line.HasSwitch(switches::kDisableWebGL) || command_line.HasSwitch(switches::kDisableWebGL2)), "WebGL2 has been disabled via blacklist or the command line.", false, @@ -168,6 +190,142 @@ return kGpuFeatureData[index]; } +std::unique_ptr<base::DictionaryValue> GetFeatureStatusImpl( + GpuFeatureInfoType type) { + GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); + std::string gpu_access_blocked_reason; + bool gpu_access_blocked = + !manager->GpuAccessAllowed(&gpu_access_blocked_reason); + const gpu::GpuFeatureInfo gpu_feature_info = + type == GpuFeatureInfoType::kCurrent + ? manager->GetGpuFeatureInfo() + : manager->GetGpuFeatureInfoForHardwareGpu(); + + auto feature_status_dict = std::make_unique<base::DictionaryValue>(); + + bool eof = false; + for (size_t i = 0; !eof; ++i) { + const GpuFeatureData gpu_feature_data = + GetGpuFeatureData(gpu_feature_info, type, i, &eof); + std::string status; + if (gpu_feature_data.disabled || gpu_access_blocked || + gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) { + status = "disabled"; + if (gpu_feature_data.fallback_to_software) + status += "_software"; + else + status += "_off"; + } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusBlacklisted) { + status = "unavailable_off"; + } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusSoftware) { + status = "unavailable_software"; + } else { + status = "enabled"; + if ((gpu_feature_data.name == "webgl" || + gpu_feature_data.name == "webgl2") && + (GetGpuCompositingStatus(gpu_feature_info, type) != + gpu::kGpuFeatureStatusEnabled)) + status += "_readback"; + if (gpu_feature_data.name == "rasterization") { + if (IsForceGpuRasterizationEnabled()) + status += "_force"; + } + if (gpu_feature_data.name == "multiple_raster_threads") { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kNumRasterThreads)) + status += "_force"; + status += "_on"; + } + if (gpu_feature_data.name == "checker_imaging") { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(cc::switches::kEnableCheckerImaging)) + status += "_force"; + status += "_on"; + } + if (gpu_feature_data.name == "surface_synchronization") { + if (features::IsSurfaceSynchronizationEnabled()) + status += "_on"; + } + if (gpu_feature_data.name == "viz_display_compositor") { + if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) + status += "_on"; + } + } + feature_status_dict->SetString(gpu_feature_data.name, status); + } + return feature_status_dict; +} + +std::unique_ptr<base::ListValue> GetProblemsImpl(GpuFeatureInfoType type) { + GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); + std::string gpu_access_blocked_reason; + bool gpu_access_blocked = + !manager->GpuAccessAllowed(&gpu_access_blocked_reason); + const gpu::GpuFeatureInfo gpu_feature_info = + type == GpuFeatureInfoType::kCurrent + ? manager->GetGpuFeatureInfo() + : manager->GetGpuFeatureInfoForHardwareGpu(); + + auto problem_list = std::make_unique<base::ListValue>(); + if (!gpu_feature_info.applied_gpu_blacklist_entries.empty()) { + std::unique_ptr<gpu::GpuBlacklist> blacklist(gpu::GpuBlacklist::Create()); + blacklist->GetReasons(problem_list.get(), "disabledFeatures", + gpu_feature_info.applied_gpu_blacklist_entries); + } + if (!gpu_feature_info.applied_gpu_driver_bug_list_entries.empty()) { + std::unique_ptr<gpu::GpuDriverBugList> bug_list( + gpu::GpuDriverBugList::Create()); + bug_list->GetReasons(problem_list.get(), "workarounds", + gpu_feature_info.applied_gpu_driver_bug_list_entries); + } + + if (gpu_access_blocked) { + auto problem = std::make_unique<base::DictionaryValue>(); + problem->SetString("description", "GPU process was unable to boot: " + + gpu_access_blocked_reason); + problem->Set("crBugs", std::make_unique<base::ListValue>()); + auto disabled_features = std::make_unique<base::ListValue>(); + disabled_features->AppendString("all"); + problem->Set("affectedGpuSettings", std::move(disabled_features)); + problem->SetString("tag", "disabledFeatures"); + problem_list->Insert(0, std::move(problem)); + } + + bool eof = false; + for (size_t i = 0; !eof; ++i) { + const GpuFeatureData gpu_feature_data = + GetGpuFeatureData(gpu_feature_info, type, i, &eof); + if (gpu_feature_data.disabled) { + auto problem = std::make_unique<base::DictionaryValue>(); + problem->SetString("description", gpu_feature_data.disabled_description); + problem->Set("crBugs", std::make_unique<base::ListValue>()); + auto disabled_features = std::make_unique<base::ListValue>(); + disabled_features->AppendString(gpu_feature_data.name); + problem->Set("affectedGpuSettings", std::move(disabled_features)); + problem->SetString("tag", "disabledFeatures"); + problem_list->Append(std::move(problem)); + } + } + return problem_list; +} + +std::vector<std::string> GetDriverBugWorkaroundsImpl(GpuFeatureInfoType type) { + GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); + const gpu::GpuFeatureInfo gpu_feature_info = + type == GpuFeatureInfoType::kCurrent + ? manager->GetGpuFeatureInfo() + : manager->GetGpuFeatureInfoForHardwareGpu(); + + std::vector<std::string> workarounds; + for (auto workaround : gpu_feature_info.enabled_gpu_driver_bug_workarounds) { + workarounds.push_back(gpu::GpuDriverBugWorkaroundTypeToString( + static_cast<gpu::GpuDriverBugWorkaroundType>(workaround))); + } + return workarounds; +} + } // namespace int NumberOfRendererRasterThreads() { @@ -296,106 +454,27 @@ } std::unique_ptr<base::DictionaryValue> GetFeatureStatus() { - GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); - bool gpu_access_blocked = !manager->GpuAccessAllowed(nullptr); - - auto feature_status_dict = std::make_unique<base::DictionaryValue>(); - - bool eof = false; - for (size_t i = 0; !eof; ++i) { - const GpuFeatureData gpu_feature_data = GetGpuFeatureData(i, &eof); - std::string status; - if (gpu_feature_data.disabled || - (gpu_feature_data.needs_gpu_access && gpu_access_blocked) || - gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) { - status = "disabled"; - if (gpu_feature_data.fallback_to_software) - status += "_software"; - else - status += "_off"; - } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusBlacklisted) { - status = "unavailable_off"; - } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusSoftware) { - status = "unavailable_software"; - } else { - status = "enabled"; - if ((gpu_feature_data.name == "webgl" || - gpu_feature_data.name == "webgl2") && - (manager->GetFeatureStatus(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING) != - gpu::kGpuFeatureStatusEnabled)) - status += "_readback"; - if (gpu_feature_data.name == "rasterization") { - if (IsForceGpuRasterizationEnabled()) - status += "_force"; - } - if (gpu_feature_data.name == "multiple_raster_threads") { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kNumRasterThreads)) - status += "_force"; - status += "_on"; - } - if (gpu_feature_data.name == "checker_imaging") { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(cc::switches::kEnableCheckerImaging)) - status += "_force"; - status += "_on"; - } - if (gpu_feature_data.name == "surface_synchronization") { - if (features::IsSurfaceSynchronizationEnabled()) - status += "_on"; - } - if (gpu_feature_data.name == "viz_display_compositor") { - if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) - status += "_on"; - } - } - feature_status_dict->SetString(gpu_feature_data.name, status); - } - return feature_status_dict; + return GetFeatureStatusImpl(GpuFeatureInfoType::kCurrent); } std::unique_ptr<base::ListValue> GetProblems() { - GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance(); - std::string gpu_access_blocked_reason; - bool gpu_access_blocked = - !manager->GpuAccessAllowed(&gpu_access_blocked_reason); - - auto problem_list = std::make_unique<base::ListValue>(); - manager->GetBlacklistReasons(problem_list.get()); - - if (gpu_access_blocked) { - auto problem = std::make_unique<base::DictionaryValue>(); - problem->SetString("description", "GPU was unable to initialize: " + - gpu_access_blocked_reason); - problem->Set("crBugs", std::make_unique<base::ListValue>()); - auto disabled_features = std::make_unique<base::ListValue>(); - disabled_features->AppendString("all"); - problem->Set("affectedGpuSettings", std::move(disabled_features)); - problem->SetString("tag", "disabledFeatures"); - problem_list->Insert(0, std::move(problem)); - } - - bool eof = false; - for (size_t i = 0; !eof; ++i) { - const GpuFeatureData gpu_feature_data = GetGpuFeatureData(i, &eof); - if (gpu_feature_data.disabled) { - auto problem = std::make_unique<base::DictionaryValue>(); - problem->SetString("description", gpu_feature_data.disabled_description); - problem->Set("crBugs", std::make_unique<base::ListValue>()); - auto disabled_features = std::make_unique<base::ListValue>(); - disabled_features->AppendString(gpu_feature_data.name); - problem->Set("affectedGpuSettings", std::move(disabled_features)); - problem->SetString("tag", "disabledFeatures"); - problem_list->Append(std::move(problem)); - } - } - return problem_list; + return GetProblemsImpl(GpuFeatureInfoType::kCurrent); } std::vector<std::string> GetDriverBugWorkarounds() { - return GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(); + return GetDriverBugWorkaroundsImpl(GpuFeatureInfoType::kCurrent); +} + +std::unique_ptr<base::DictionaryValue> GetFeatureStatusForHardwareGpu() { + return GetFeatureStatusImpl(GpuFeatureInfoType::kForHardwareGpu); +} + +std::unique_ptr<base::ListValue> GetProblemsForHardwareGpu() { + return GetProblemsImpl(GpuFeatureInfoType::kForHardwareGpu); +} + +std::vector<std::string> GetDriverBugWorkaroundsForHardwareGpu() { + return GetDriverBugWorkaroundsImpl(GpuFeatureInfoType::kForHardwareGpu); } std::vector<gfx::BufferUsageAndFormat>
diff --git a/content/browser/gpu/compositor_util.h b/content/browser/gpu/compositor_util.h index d31715e..2535f08a 100644 --- a/content/browser/gpu/compositor_util.h +++ b/content/browser/gpu/compositor_util.h
@@ -47,6 +47,11 @@ CONTENT_EXPORT std::unique_ptr<base::ListValue> GetProblems(); CONTENT_EXPORT std::vector<std::string> GetDriverBugWorkarounds(); +CONTENT_EXPORT std::unique_ptr<base::DictionaryValue> +GetFeatureStatusForHardwareGpu(); +CONTENT_EXPORT std::unique_ptr<base::ListValue> GetProblemsForHardwareGpu(); +CONTENT_EXPORT std::vector<std::string> GetDriverBugWorkaroundsForHardwareGpu(); + // Populate a list of buffer usage/format for which a per platform specific // texture target must be used instead of GL_TEXTURE_2D. CONTENT_EXPORT std::vector<gfx::BufferUsageAndFormat>
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index 13f75be6..47dfcfa 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -94,12 +94,6 @@ return private_->HardwareAccelerationEnabled(); } -void GpuDataManagerImpl::GetDisabledExtensions( - std::string* disabled_extensions) const { - base::AutoLock auto_lock(lock_); - private_->GetDisabledExtensions(disabled_extensions); -} - void GpuDataManagerImpl::RequestGpuSupportedRuntimeVersion() const { base::AutoLock auto_lock(lock_); private_->RequestGpuSupportedRuntimeVersion(); @@ -110,21 +104,19 @@ return private_->GpuProcessStartAllowed(); } -void GpuDataManagerImpl::GetDisabledWebGLExtensions( - std::string* disabled_webgl_extensions) const { +void GpuDataManagerImpl::UpdateGpuInfo( + const gpu::GPUInfo& gpu_info, + const gpu::GPUInfo* optional_gpu_info_for_hardware_gpu) { base::AutoLock auto_lock(lock_); - private_->GetDisabledWebGLExtensions(disabled_webgl_extensions); -} - -void GpuDataManagerImpl::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) { - base::AutoLock auto_lock(lock_); - private_->UpdateGpuInfo(gpu_info); + private_->UpdateGpuInfo(gpu_info, optional_gpu_info_for_hardware_gpu); } void GpuDataManagerImpl::UpdateGpuFeatureInfo( - const gpu::GpuFeatureInfo& gpu_feature_info) { + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) { base::AutoLock auto_lock(lock_); - private_->UpdateGpuFeatureInfo(gpu_feature_info); + private_->UpdateGpuFeatureInfo(gpu_feature_info, + gpu_feature_info_for_hardware_gpu); } gpu::GpuFeatureInfo GpuDataManagerImpl::GetGpuFeatureInfo() const { @@ -132,6 +124,17 @@ return private_->GetGpuFeatureInfo(); } +gpu::GPUInfo GpuDataManagerImpl::GetGPUInfoForHardwareGpu() const { + base::AutoLock auto_lock(lock_); + return private_->GetGPUInfoForHardwareGpu(); +} + +gpu::GpuFeatureInfo GpuDataManagerImpl::GetGpuFeatureInfoForHardwareGpu() + const { + base::AutoLock auto_lock(lock_); + return private_->GetGpuFeatureInfoForHardwareGpu(); +} + void GpuDataManagerImpl::AppendGpuCommandLine( base::CommandLine* command_line) const { base::AutoLock auto_lock(lock_); @@ -144,16 +147,6 @@ private_->UpdateGpuPreferences(gpu_preferences); } -void GpuDataManagerImpl::GetBlacklistReasons(base::ListValue* reasons) const { - base::AutoLock auto_lock(lock_); - private_->GetBlacklistReasons(reasons); -} - -std::vector<std::string> GpuDataManagerImpl::GetDriverBugWorkarounds() const { - base::AutoLock auto_lock(lock_); - return private_->GetDriverBugWorkarounds(); -} - void GpuDataManagerImpl::AddLogMessage(int level, const std::string& header, const std::string& message) { @@ -218,6 +211,11 @@ private_->OnGpuProcessInitFailure(); } +bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const { + base::AutoLock auto_lock(lock_); + return private_->IsGpuProcessUsingHardwareGpu(); +} + GpuDataManagerImpl::GpuDataManagerImpl() : private_(GpuDataManagerImplPrivate::Create(this)) { }
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index b775788..6b6714d5 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -81,41 +81,35 @@ void RemoveObserver(GpuDataManagerObserver* observer) override; void DisableHardwareAcceleration() override; bool HardwareAccelerationEnabled() const override; - void GetDisabledExtensions(std::string* disabled_extensions) const override; void RequestGpuSupportedRuntimeVersion() const; bool GpuProcessStartAllowed() const; - void GetDisabledWebGLExtensions(std::string* disabled_webgl_extensions) const; - bool IsGpuFeatureInfoAvailable() const; gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) const; // Only update if the current GPUInfo is not finalized. If blacklist is // loaded, run through blacklist and update blacklisted features. - void UpdateGpuInfo(const gpu::GPUInfo& gpu_info); + void UpdateGpuInfo(const gpu::GPUInfo& gpu_info, + const gpu::GPUInfo* optional_gpu_info_for_hardware_gpu); // Update the GPU feature info. This updates the blacklist and enabled status // of GPU rasterization. In the future this will be used for more features. - void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info); + void UpdateGpuFeatureInfo( + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu); gpu::GpuFeatureInfo GetGpuFeatureInfo() const; + gpu::GPUInfo GetGPUInfoForHardwareGpu() const; + gpu::GpuFeatureInfo GetGpuFeatureInfoForHardwareGpu() const; + // Insert switches into gpu process command line: kUseGL, etc. void AppendGpuCommandLine(base::CommandLine* command_line) const; // Update GpuPreferences based on blacklisting decisions. void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences) const; - // Returns the reasons for the latest run of blacklisting decisions. - // For the structure of returned value, see documentation for - // GpuBlacklist::GetBlacklistedReasons(). - void GetBlacklistReasons(base::ListValue* reasons) const; - - // Returns the workarounds that are applied to the current system as - // a vector of strings. - std::vector<std::string> GetDriverBugWorkarounds() const; - void AddLogMessage(int level, const std::string& header, const std::string& message); @@ -160,6 +154,10 @@ void BlockSwiftShader(); bool SwiftShaderAllowed() const; + // Returns false if the latest GPUInfo gl_renderer is from SwiftShader or + // Disabled (in the viz case). + bool IsGpuProcessUsingHardwareGpu() const; + private: friend class GpuDataManagerImplPrivate; friend class GpuDataManagerImplPrivateTest;
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 66b30c3..f1e9a9c 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -16,6 +16,7 @@ #include "base/metrics/field_trial.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/version.h" @@ -255,7 +256,7 @@ base::BindOnce( [](const gpu::GPUInfo& gpu_info) { TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected"); - GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info); + GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info, nullptr); }, gpu_info)); } @@ -273,7 +274,7 @@ else gpu_feature_info.status_values[ii] = gpu::kGpuFeatureStatusEnabled; } - UpdateGpuFeatureInfo(gpu_feature_info); + UpdateGpuFeatureInfo(gpu_feature_info, gpu::GpuFeatureInfo()); NotifyGpuInfoUpdate(); } @@ -281,6 +282,10 @@ return gpu_info_; } +gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const { + return gpu_info_for_hardware_gpu_; +} + bool GpuDataManagerImplPrivate::GpuAccessAllowed( std::string* reason) const { bool swiftshader_available = false; @@ -421,13 +426,23 @@ timestamps_of_gpu_resets_.clear(); } -void GpuDataManagerImplPrivate::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) { +void GpuDataManagerImplPrivate::UpdateGpuInfo( + const gpu::GPUInfo& gpu_info, + const gpu::GPUInfo* optional_gpu_info_for_hardware_gpu) { bool sandboxed = gpu_info_.sandboxed; #if defined(OS_WIN) uint32_t d3d12_feature_level = gpu_info_.d3d12_feature_level; uint32_t vulkan_version = gpu_info_.vulkan_version; #endif gpu_info_ = gpu_info; + if (optional_gpu_info_for_hardware_gpu && + !gpu_info_for_hardware_gpu_.IsInitialized()) { + if (optional_gpu_info_for_hardware_gpu->IsInitialized()) { + gpu_info_for_hardware_gpu_ = *optional_gpu_info_for_hardware_gpu; + } else { + gpu_info_for_hardware_gpu_ = gpu_info; + } + } #if defined(OS_WIN) // On Windows, complete GPUInfo is collected through an unsandboxed // GPU process. If the regular GPU process is sandboxed, it should @@ -457,8 +472,16 @@ } void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo( - const gpu::GpuFeatureInfo& gpu_feature_info) { + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) { gpu_feature_info_ = gpu_feature_info; + if (!gpu_feature_info_for_hardware_gpu_.IsInitialized()) { + if (gpu_feature_info_for_hardware_gpu.IsInitialized()) { + gpu_feature_info_for_hardware_gpu_ = gpu_feature_info_for_hardware_gpu; + } else { + gpu_feature_info_for_hardware_gpu_ = gpu_feature_info; + } + } if (update_histograms_) { UpdateFeatureStats(gpu_feature_info); UpdateDriverBugListStats(gpu_feature_info); @@ -469,6 +492,11 @@ return gpu_feature_info_; } +gpu::GpuFeatureInfo GpuDataManagerImplPrivate::GetGpuFeatureInfoForHardwareGpu() + const { + return gpu_feature_info_for_hardware_gpu_; +} + void GpuDataManagerImplPrivate::AppendGpuCommandLine( base::CommandLine* command_line) const { DCHECK(command_line); @@ -553,38 +581,14 @@ } void GpuDataManagerImplPrivate::OnGpuBlocked() { + gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu = gpu_feature_info_; gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfoWithNoGpu(); - UpdateGpuFeatureInfo(gpu_feature_info); + UpdateGpuFeatureInfo(gpu_feature_info, gpu_feature_info_for_hardware_gpu); // Some observers might be waiting. NotifyGpuInfoUpdate(); } -void GpuDataManagerImplPrivate::GetBlacklistReasons( - base::ListValue* reasons) const { - if (!gpu_feature_info_.applied_gpu_blacklist_entries.empty()) { - std::unique_ptr<gpu::GpuBlacklist> blacklist(gpu::GpuBlacklist::Create()); - blacklist->GetReasons(reasons, "disabledFeatures", - gpu_feature_info_.applied_gpu_blacklist_entries); - } - if (!gpu_feature_info_.applied_gpu_driver_bug_list_entries.empty()) { - std::unique_ptr<gpu::GpuDriverBugList> bug_list( - gpu::GpuDriverBugList::Create()); - bug_list->GetReasons(reasons, "workarounds", - gpu_feature_info_.applied_gpu_driver_bug_list_entries); - } -} - -std::vector<std::string> -GpuDataManagerImplPrivate::GetDriverBugWorkarounds() const { - std::vector<std::string> workarounds; - for (auto workaround : gpu_feature_info_.enabled_gpu_driver_bug_workarounds) { - workarounds.push_back(gpu::GpuDriverBugWorkaroundTypeToString( - static_cast<gpu::GpuDriverBugWorkaroundType>(workaround))); - } - return workarounds; -} - void GpuDataManagerImplPrivate::AddLogMessage( int level, const std::string& header, const std::string& message) { // Some clients emit many log messages. This has been observed to consume GBs @@ -671,18 +675,6 @@ return true; } -void GpuDataManagerImplPrivate::GetDisabledExtensions( - std::string* disabled_extensions) const { - DCHECK(disabled_extensions); - *disabled_extensions = gpu_feature_info_.disabled_extensions; -} - -void GpuDataManagerImplPrivate::GetDisabledWebGLExtensions( - std::string* disabled_webgl_extensions) const { - DCHECK(disabled_webgl_extensions); - *disabled_webgl_extensions = gpu_feature_info_.disabled_webgl_extensions; -} - void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs( const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) { BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now()); @@ -746,6 +738,15 @@ observer_list_->Notify(FROM_HERE, &GpuDataManagerObserver::OnGpuInfoUpdate); } +bool GpuDataManagerImplPrivate::IsGpuProcessUsingHardwareGpu() const { + if (base::StartsWith(gpu_info_.gl_renderer, "Google SwiftShader", + base::CompareCase::SENSITIVE)) + return false; + if (gpu_info_.gl_renderer == "Disabled") + return false; + return true; +} + std::string GpuDataManagerImplPrivate::GetDomainFromURL( const GURL& url) const { // For the moment, we just use the host, or its IP address, as the
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index 08b4cae..44e3ba9 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -41,6 +41,7 @@ void BlacklistWebGLForTesting(); gpu::GPUInfo GetGPUInfo() const; + gpu::GPUInfo GetGPUInfoForHardwareGpu() const; bool GpuAccessAllowed(std::string* reason) const; bool GpuProcessStartAllowed() const; void RequestCompleteGpuInfoIfNeeded(); @@ -59,18 +60,18 @@ void BlockSwiftShader(); bool SwiftShaderAllowed() const; - void UpdateGpuInfo(const gpu::GPUInfo& gpu_info); - void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info); + void UpdateGpuInfo(const gpu::GPUInfo& gpu_info, + const gpu::GPUInfo* optional_gpu_info_for_hardware_gpu); + void UpdateGpuFeatureInfo( + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu); gpu::GpuFeatureInfo GetGpuFeatureInfo() const; + gpu::GpuFeatureInfo GetGpuFeatureInfoForHardwareGpu() const; void AppendGpuCommandLine(base::CommandLine* command_line) const; void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences) const; - void GetBlacklistReasons(base::ListValue* reasons) const; - - std::vector<std::string> GetDriverBugWorkarounds() const; - void AddLogMessage(int level, const std::string& header, const std::string& message); @@ -81,9 +82,6 @@ void HandleGpuSwitch(); - void GetDisabledExtensions(std::string* disabled_extensions) const; - void GetDisabledWebGLExtensions(std::string* disabled_webgl_extensions) const; - void BlockDomainFrom3DAPIs( const GURL& url, GpuDataManagerImpl::DomainGuilt guilt); bool Are3DAPIsBlocked(const GURL& top_origin_url, @@ -105,6 +103,8 @@ // Notify all observers whenever there is a GPU info update. void NotifyGpuInfoUpdate(); + bool IsGpuProcessUsingHardwareGpu() const; + virtual ~GpuDataManagerImplPrivate(); private: @@ -171,11 +171,14 @@ bool complete_gpu_info_already_requested_; - // Eventually |blacklisted_features_| should be folded in to this. gpu::GpuFeatureInfo gpu_feature_info_; - gpu::GPUInfo gpu_info_; + // What we would have gotten if we haven't fallen back to SwiftShader or + // pure software (in the viz case). + gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu_; + gpu::GPUInfo gpu_info_for_hardware_gpu_; + const scoped_refptr<GpuDataManagerObserverList> observer_list_; // Contains the 1000 most recent log messages.
diff --git a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc index 252ca41c..d445e5b 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -140,7 +140,7 @@ EXPECT_FALSE(observer.gpu_info_updated()); gpu::GPUInfo gpu_info; - manager->UpdateGpuInfo(gpu_info); + manager->UpdateGpuInfo(gpu_info, nullptr); { base::RunLoop run_loop; run_loop.RunUntilIdle();
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index 09ffa77..f476572 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -144,8 +144,9 @@ vendor.c_str(), device.c_str(), gpu.active ? " *ACTIVE*" : ""); } -std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() { - gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); +std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue( + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info) { auto basic_info = std::make_unique<base::ListValue>(); basic_info->Append(NewDescriptionValuePair( "Initialization time", @@ -206,14 +207,6 @@ VulkanVersionToString(gpu_info.vulkan_version))); #endif - std::string disabled_extensions; - GpuDataManagerImpl::GetInstance()->GetDisabledExtensions( - &disabled_extensions); - - std::string disabled_webgl_extensions; - GpuDataManagerImpl::GetInstance()->GetDisabledWebGLExtensions( - &disabled_webgl_extensions); - basic_info->Append( NewDescriptionValuePair("Driver vendor", gpu_info.driver_vendor)); basic_info->Append(NewDescriptionValuePair("Driver version", @@ -238,10 +231,10 @@ gpu_info.gl_version)); basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS", gpu_info.gl_extensions)); - basic_info->Append(NewDescriptionValuePair("Disabled Extensions", - disabled_extensions)); - basic_info->Append(NewDescriptionValuePair("Disabled WebGL Extensions", - disabled_webgl_extensions)); + basic_info->Append(NewDescriptionValuePair( + "Disabled Extensions", gpu_feature_info.disabled_extensions)); + basic_info->Append(NewDescriptionValuePair( + "Disabled WebGL Extensions", gpu_feature_info.disabled_webgl_extensions)); basic_info->Append(NewDescriptionValuePair("Window system binding vendor", gpu_info.gl_ws_vendor)); basic_info->Append(NewDescriptionValuePair("Window system binding version", @@ -278,8 +271,25 @@ "GPU process crash count", std::make_unique<base::Value>(GpuProcessHost::GetGpuCrashCount()))); +#if defined(USE_X11) + basic_info->Append(NewDescriptionValuePair( + "System visual ID", base::NumberToString(gpu_info.system_visual))); + basic_info->Append(NewDescriptionValuePair( + "RGBA visual ID", base::NumberToString(gpu_info.rgba_visual))); +#endif + + return basic_info; +} + +std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() { auto info = std::make_unique<base::DictionaryValue>(); + const gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); + const gpu::GpuFeatureInfo gpu_feature_info = + GpuDataManagerImpl::GetInstance()->GetGpuFeatureInfo(); + auto basic_info = BasicGpuInfoAsListValue(gpu_info, gpu_feature_info); + info->Set("basicInfo", std::move(basic_info)); + #if defined(OS_WIN) auto dx_info = std::make_unique<base::Value>(); if (gpu_info.dx_diagnostics.children.size()) @@ -287,14 +297,6 @@ info->Set("diagnostics", std::move(dx_info)); #endif -#if defined(USE_X11) - basic_info->Append(NewDescriptionValuePair( - "System visual ID", base::NumberToString(gpu_info.system_visual))); - basic_info->Append(NewDescriptionValuePair( - "RGBA visual ID", base::NumberToString(gpu_info.rgba_visual))); -#endif - - info->Set("basic_info", std::move(basic_info)); return info; } @@ -625,18 +627,41 @@ void GpuMessageHandler::OnGpuInfoUpdate() { // Get GPU Info. - std::unique_ptr<base::DictionaryValue> gpu_info_val( - GpuInfoAsDictionaryValue()); + const gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo(); + auto gpu_info_val = GpuInfoAsDictionaryValue(); // Add in blacklisting features auto feature_status = std::make_unique<base::DictionaryValue>(); feature_status->Set("featureStatus", GetFeatureStatus()); feature_status->Set("problems", GetProblems()); auto workarounds = std::make_unique<base::ListValue>(); - for (const std::string& workaround : GetDriverBugWorkarounds()) + for (const auto& workaround : GetDriverBugWorkarounds()) workarounds->AppendString(workaround); feature_status->Set("workarounds", std::move(workarounds)); gpu_info_val->Set("featureStatus", std::move(feature_status)); + if (!GpuDataManagerImpl::GetInstance()->IsGpuProcessUsingHardwareGpu()) { + auto feature_status_for_hardware_gpu = + std::make_unique<base::DictionaryValue>(); + feature_status_for_hardware_gpu->Set("featureStatus", + GetFeatureStatusForHardwareGpu()); + feature_status_for_hardware_gpu->Set("problems", + GetProblemsForHardwareGpu()); + auto workarounds_for_hardware_gpu = std::make_unique<base::ListValue>(); + for (const auto& workaround : GetDriverBugWorkaroundsForHardwareGpu()) + workarounds_for_hardware_gpu->AppendString(workaround); + feature_status_for_hardware_gpu->Set( + "workarounds", std::move(workarounds_for_hardware_gpu)); + gpu_info_val->Set("featureStatusForHardwareGpu", + std::move(feature_status_for_hardware_gpu)); + const gpu::GPUInfo gpu_info_for_hardware_gpu = + GpuDataManagerImpl::GetInstance()->GetGPUInfoForHardwareGpu(); + const gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu = + GpuDataManagerImpl::GetInstance()->GetGpuFeatureInfoForHardwareGpu(); + auto gpu_info_for_hardware_gpu_val = BasicGpuInfoAsListValue( + gpu_info_for_hardware_gpu, gpu_feature_info_for_hardware_gpu); + gpu_info_val->Set("basicInfoForHardwareGpu", + std::move(gpu_info_for_hardware_gpu_val)); + } gpu_info_val->Set("compositorInfo", CompositorInfo()); gpu_info_val->Set("gpuMemoryBufferInfo", GpuMemoryBufferInfo()); gpu_info_val->Set("displayInfo", getDisplayInfo());
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 130bf011..716f9176 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -117,6 +117,57 @@ namespace { +// This matches base::TerminationStatus. +// These values are persisted to logs. Entries (except MAX_ENUM) should not be +// renumbered and numeric values should never be reused. Should also avoid +// OS-defines in this enum to keep the values consistent on all platforms. +enum class GpuTerminationStatus { + NORMAL_TERMINATION = 0, + ABNORMAL_TERMINATION = 1, + PROCESS_WAS_KILLED = 2, + PROCESS_CRASHED = 3, + STILL_RUNNING = 4, + PROCESS_WAS_KILLED_BY_OOM = 5, + OOM_PROTECTED = 6, + LAUNCH_FAILED = 7, + OOM = 8, + MAX_ENUM = 9, +}; + +GpuTerminationStatus ConvertToGpuTerminationStatus( + base::TerminationStatus status) { + switch (status) { + case base::TERMINATION_STATUS_NORMAL_TERMINATION: + return GpuTerminationStatus::NORMAL_TERMINATION; + case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + return GpuTerminationStatus::ABNORMAL_TERMINATION; + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: + return GpuTerminationStatus::PROCESS_WAS_KILLED; + case base::TERMINATION_STATUS_PROCESS_CRASHED: + return GpuTerminationStatus::PROCESS_CRASHED; + case base::TERMINATION_STATUS_STILL_RUNNING: + return GpuTerminationStatus::STILL_RUNNING; +#if defined(OS_CHROMEOS) + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: + return GpuTerminationStatus::PROCESS_WAS_KILLED_BY_OOM; +#endif +#if defined(OS_ANDROID) + case base::TERMINATION_STATUS_OOM_PROTECTED: + return GpuTerminationStatus::OOM_PROTECTED; +#endif + case base::TERMINATION_STATUS_LAUNCH_FAILED: + return GpuTerminationStatus::LAUNCH_FAILED; + case base::TERMINATION_STATUS_OOM: + return GpuTerminationStatus::OOM; + case base::TERMINATION_STATUS_MAX_ENUM: + NOTREACHED(); + return GpuTerminationStatus::MAX_ENUM; + // Do not add default. + } + NOTREACHED(); + return GpuTerminationStatus::ABNORMAL_TERMINATION; +} + // Command-line switches to propagate to the GPU process. static const char* const kSwitchNames[] = { service_manager::switches::kDisableSeccompFilterSandbox, @@ -142,7 +193,6 @@ switches::kEnableAcceleratedVpxDecode, #endif switches::kEnableGpuRasterization, - switches::kEnableHeapProfiling, switches::kEnableLogging, switches::kEnableOOPRasterization, switches::kEnableVizDevTools, @@ -633,8 +683,9 @@ if (!in_process_ && process_launched_) { ChildProcessTerminationInfo info = process_->GetTerminationInfo(false /* known_dead */); - UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus", info.status, - base::TERMINATION_STATUS_MAX_ENUM); + UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus2", + ConvertToGpuTerminationStatus(info.status), + GpuTerminationStatus::MAX_ENUM); if (info.status == base::TERMINATION_STATUS_NORMAL_TERMINATION || info.status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION || @@ -1030,7 +1081,9 @@ void GpuProcessHost::DidInitialize( const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info) { + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) { UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true); status_ = SUCCESS; @@ -1046,8 +1099,9 @@ GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); // Update GpuFeatureInfo first, because UpdateGpuInfo() will notify all // listeners. - gpu_data_manager->UpdateGpuFeatureInfo(gpu_feature_info); - gpu_data_manager->UpdateGpuInfo(gpu_info); + gpu_data_manager->UpdateGpuFeatureInfo(gpu_feature_info, + gpu_feature_info_for_hardware_gpu); + gpu_data_manager->UpdateGpuInfo(gpu_info, &gpu_info_for_hardware_gpu); RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo()); }
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 51b57b6..b5a0b46 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h
@@ -203,8 +203,11 @@ void OnProcessCrashed(int exit_code) override; // viz::mojom::GpuHost: - void DidInitialize(const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info) override; + void DidInitialize( + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) override; void DidFailInitialize() override; void DidCreateContextSuccessfully() override; void DidCreateOffscreenContext(const GURL& url) override;
diff --git a/content/browser/picture_in_picture/overlay_surface_embedder.cc b/content/browser/picture_in_picture/overlay_surface_embedder.cc index 0e9780b..1e7d2a0 100644 --- a/content/browser/picture_in_picture/overlay_surface_embedder.cc +++ b/content/browser/picture_in_picture/overlay_surface_embedder.cc
@@ -19,8 +19,6 @@ surface_layer_->SetFillsBoundsOpaquely(false); // |surface_layer_| bounds are set with the (0, 0) origin point. The // positioning of |window_| is dictated by itself. - // TODO(apacible): Update |surface_layer_| size when the window is resized. - // http://crbug.com/726621 surface_layer_->SetBounds( gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size())); window_->GetLayer()->Add(surface_layer_.get());
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h index 36fd7ef..d33a85a 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.h +++ b/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -213,6 +213,8 @@ } repaint_state_ = RepaintState::None; bool repaint_auto_resize_enabled_ = false; + uint32_t capture_sequence_number_ = 0; + base::WeakPtrFactory<BrowserCompositorMac> weak_factory_; };
diff --git a/content/browser/renderer_host/frame_connector_delegate.cc b/content/browser/renderer_host/frame_connector_delegate.cc index 9ec6c75..af4f44c 100644 --- a/content/browser/renderer_host/frame_connector_delegate.cc +++ b/content/browser/renderer_host/frame_connector_delegate.cc
@@ -30,6 +30,7 @@ const FrameResizeParams& resize_params) { screen_info_ = resize_params.screen_info; local_surface_id_ = surface_id.local_surface_id(); + capture_sequence_number_ = resize_params.capture_sequence_number; SetScreenSpaceRect(resize_params.screen_space_rect); SetLocalFrameSize(resize_params.local_frame_size);
diff --git a/content/browser/renderer_host/frame_connector_delegate.h b/content/browser/renderer_host/frame_connector_delegate.h index 0f8cf97..bc8fbaa 100644 --- a/content/browser/renderer_host/frame_connector_delegate.h +++ b/content/browser/renderer_host/frame_connector_delegate.h
@@ -77,28 +77,31 @@ const FrameResizeParams& resize_params); // Return the size of the CompositorFrame to use in the child renderer. - const gfx::Size& local_frame_size_in_pixels() { + const gfx::Size& local_frame_size_in_pixels() const { return local_frame_size_in_pixels_; } // Return the size of the CompositorFrame to use in the child renderer in DIP. // This is used to set the layout size of the child renderer. - const gfx::Size& local_frame_size_in_dip() { + const gfx::Size& local_frame_size_in_dip() const { return local_frame_size_in_dip_; } // Return the rect in DIP that the RenderWidgetHostViewChildFrame's content // will render into. - const gfx::Rect& screen_space_rect_in_dip() { + const gfx::Rect& screen_space_rect_in_dip() const { return screen_space_rect_in_dip_; } // Return the rect in pixels that the RenderWidgetHostViewChildFrame's content // will render into. - const gfx::Rect& screen_space_rect_in_pixels() { + const gfx::Rect& screen_space_rect_in_pixels() const { return screen_space_rect_in_pixels_; } + // Return the latest capture sequence number of this delegate. + uint32_t capture_sequence_number() const { return capture_sequence_number_; } + // Request that the platform change the mouse cursor when the mouse is // positioned over this view's content. virtual void UpdateCursor(const WebCursor& cursor) {} @@ -226,14 +229,12 @@ ui::mojom::WindowTreeClientPtr window_tree_client) {} #endif - // Called by RenderWidgetHostViewChildFrame when an auto-resize transaction - // starts. - virtual void BeginResizeDueToAutoResize() {} - // Called by RenderWidgetHostViewChildFrame when the child frame has finished - // an auto-resize transaction. Causes allocation of a new LocalSurfaceID - // associated with the new size. - virtual void EndResizeDueToAutoResize(uint64_t sequence_number) {} + // an auto-resize transaction. Provides the viz::LocalSurfaceId and sequence + // number to use for the transaction. + virtual void ResizeDueToAutoResize( + uint64_t sequence_number, + const viz::LocalSurfaceId& child_allocated_surface_id) {} bool has_size() const { return has_size_; } @@ -262,6 +263,8 @@ bool has_size_ = false; const bool use_zoom_for_device_scale_factor_; + uint32_t capture_sequence_number_ = 0u; + FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewChildFrameZoomForDSFTest, CompositorViewportPixelSize); };
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc index 419ea74f..58404d6 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -37,12 +37,10 @@ using AudioOutputStream = media::mojom::AudioOutputStream; using AudioOutputStreamPtr = mojo::InterfacePtr<AudioOutputStream>; using AudioOutputStreamRequest = mojo::InterfaceRequest<AudioOutputStream>; -using AudioOutputStreamProviderClient = - media::mojom::AudioOutputStreamProviderClient; -using AudioOutputStreamProviderClientPtr = - mojo::InterfacePtr<AudioOutputStreamProviderClient>; -using AudioOutputStreamProviderClientRequest = - mojo::InterfaceRequest<AudioOutputStreamProviderClient>; +using AudioOutputStreamClient = media::mojom::AudioOutputStreamClient; +using AudioOutputStreamClientPtr = mojo::InterfacePtr<AudioOutputStreamClient>; +using AudioOutputStreamClientRequest = + mojo::InterfaceRequest<AudioOutputStreamClient>; using AudioOutputStreamProvider = media::mojom::AudioOutputStreamProvider; using AudioOutputStreamProviderPtr = mojo::InterfacePtr<AudioOutputStreamProvider>; @@ -168,21 +166,13 @@ DISALLOW_COPY_AND_ASSIGN(MockContext); }; -class MockClient : public AudioOutputStreamProviderClient { +class MockClient : public AudioOutputStreamClient { public: - MockClient() : provider_client_binding_(this) {} + MockClient() {} ~MockClient() override {} - AudioOutputStreamProviderClientPtr MakeProviderClientPtr() { - AudioOutputStreamProviderClientPtr p; - provider_client_binding_.Bind(mojo::MakeRequest(&p)); - return p; - } - - void Created(AudioOutputStreamPtr stream, - media::mojom::AudioDataPipePtr data_pipe) { + void StreamCreated(media::mojom::AudioDataPipePtr data_pipe) { was_called_ = true; - stream_ = std::move(stream); } bool was_called() { return was_called_; } @@ -190,8 +180,6 @@ MOCK_METHOD0(OnError, void()); private: - mojo::Binding<AudioOutputStreamProviderClient> provider_client_binding_; - AudioOutputStreamPtr stream_; bool was_called_ = false; DISALLOW_COPY_AND_ASSIGN(MockClient); @@ -211,13 +199,17 @@ } // namespace // This test authorizes and creates a stream, and checks that -// 1. the ProviderClient callback is called with appropriate parameters. +// 1. the authorization callback is called with appropriate parameters. // 2. the AudioOutputDelegate is created. // 3. when the delegate calls OnStreamCreated, this is propagated to the client. TEST(RenderFrameAudioOutputStreamFactoryTest, CreateStream) { content::TestBrowserThreadBundle thread_bundle; AudioOutputStreamProviderPtr provider; + AudioOutputStreamPtr output_stream; MockClient client; + AudioOutputStreamClientPtr client_ptr; + mojo::Binding<AudioOutputStreamClient> client_binding( + &client, mojo::MakeRequest(&client_ptr)); media::AudioOutputDelegate::EventHandler* event_handler = nullptr; auto factory_context = std::make_unique<MockContext>(true); factory_context->PrepareDelegateForCreation( @@ -237,7 +229,9 @@ GetTestAudioParameters().AsHumanReadableString()); EXPECT_TRUE(id.empty()); - provider->Acquire(params, client.MakeProviderClientPtr()); + provider->Acquire( + mojo::MakeRequest(&output_stream), std::move(client_ptr), params, + base::BindOnce(&MockClient::StreamCreated, base::Unretained(&client))); base::RunLoop().RunUntilIdle(); ASSERT_NE(event_handler, nullptr); @@ -276,7 +270,11 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, ConnectionError_DeletesStream) { content::TestBrowserThreadBundle thread_bundle; AudioOutputStreamProviderPtr provider; + AudioOutputStreamPtr output_stream; MockClient client; + AudioOutputStreamClientPtr client_ptr; + mojo::Binding<AudioOutputStreamClient> client_binding( + &client, mojo::MakeRequest(&client_ptr)); bool delegate_is_destructed = false; media::AudioOutputDelegate::EventHandler* event_handler = nullptr; auto factory_context = std::make_unique<MockContext>(true); @@ -294,11 +292,14 @@ const std::string& id) {})); base::RunLoop().RunUntilIdle(); - provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr()); + provider->Acquire( + mojo::MakeRequest(&output_stream), std::move(client_ptr), + GetTestAudioParameters(), + base::BindOnce(&MockClient::StreamCreated, base::Unretained(&client))); base::RunLoop().RunUntilIdle(); ASSERT_NE(event_handler, nullptr); EXPECT_FALSE(delegate_is_destructed); - provider.reset(); + output_stream.reset(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(delegate_is_destructed); } @@ -306,7 +307,11 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, DelegateError_DeletesStream) { content::TestBrowserThreadBundle thread_bundle; AudioOutputStreamProviderPtr provider; + AudioOutputStreamPtr output_stream; MockClient client; + AudioOutputStreamClientPtr client_ptr; + mojo::Binding<AudioOutputStreamClient> client_binding( + &client, mojo::MakeRequest(&client_ptr)); bool delegate_is_destructed = false; media::AudioOutputDelegate::EventHandler* event_handler = nullptr; auto factory_context = std::make_unique<MockContext>(true); @@ -324,7 +329,10 @@ const std::string& id) {})); base::RunLoop().RunUntilIdle(); - provider->Acquire(GetTestAudioParameters(), client.MakeProviderClientPtr()); + provider->Acquire( + mojo::MakeRequest(&output_stream), std::move(client_ptr), + GetTestAudioParameters(), + base::BindOnce(&MockClient::StreamCreated, base::Unretained(&client))); base::RunLoop().RunUntilIdle(); ASSERT_NE(event_handler, nullptr); EXPECT_FALSE(delegate_is_destructed);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8e4198a..825349bd 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1787,9 +1787,8 @@ MediaInternals* media_internals = MediaInternals::GetInstance(); // Add BrowserPluginMessageFilter to ensure it gets the first stab at messages // from guests. - scoped_refptr<BrowserPluginMessageFilter> bp_message_filter( - new BrowserPluginMessageFilter(GetID())); - AddFilter(bp_message_filter.get()); + bp_message_filter_ = new BrowserPluginMessageFilter(GetID()); + AddFilter(bp_message_filter_.get()); scoped_refptr<net::URLRequestContextGetter> request_context( storage_partition_impl_->GetURLRequestContext()); @@ -2698,7 +2697,6 @@ switches::kDomAutomationController, switches::kEnableAutomation, switches::kEnableExperimentalWebPlatformFeatures, - switches::kEnableHeapProfiling, switches::kEnableGPUClientLogging, switches::kEnableGpuClientTracing, switches::kEnableGpuMemoryBufferVideoFrames, @@ -4398,4 +4396,9 @@ std::move(callback).Run(histogram_json); } +void RenderProcessHostImpl::SetBrowserPluginMessageFilterSubFilterForTesting( + scoped_refptr<BrowserMessageFilter> message_filter) const { + bp_message_filter_->SetSubFilterForTesting(std::move(message_filter)); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 0ea859f1..c4168e4 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -70,6 +70,7 @@ } namespace content { +class BrowserPluginMessageFilter; class ChildConnection; class GpuClient; class IndexedDBDispatcherHost; @@ -337,6 +338,9 @@ return notification_message_filter_.get(); } + void SetBrowserPluginMessageFilterSubFilterForTesting( + scoped_refptr<BrowserMessageFilter> message_filter) const; + void set_is_for_guests_only_for_testing(bool is_for_guests_only) { is_for_guests_only_ = is_for_guests_only; } @@ -683,6 +687,9 @@ // closure per notification that must be freed when the notification closes. scoped_refptr<NotificationMessageFilter> notification_message_filter_; + // The filter for messages coming from the browser plugin. + scoped_refptr<BrowserPluginMessageFilter> bp_message_filter_; + // Used in single-process mode. std::unique_ptr<base::Thread> in_process_renderer_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 45bae40..f3d461d 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -767,6 +767,7 @@ if (view_) { resize_params->new_size = view_->GetRequestedRendererSize(); + resize_params->capture_sequence_number = view_->GetCaptureSequenceNumber(); resize_params->compositor_viewport_pixel_size = view_->GetCompositorViewportPixelSize(); resize_params->top_controls_height = view_->GetTopControlsHeight(); @@ -834,7 +835,10 @@ old_resize_params_->content_source_id != resize_params->content_source_id) || (enable_surface_synchronization_ && - old_resize_params_->local_surface_id != resize_params->local_surface_id); + old_resize_params_->local_surface_id != + resize_params->local_surface_id) || + old_resize_params_->capture_sequence_number != + resize_params->capture_sequence_number; // We don't expect to receive an ACK when the requested size or the physical // backing size is empty, or when the main viewport size didn't change.
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index fd8f53fa..9e0a1f91 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -830,6 +830,15 @@ std::move(callback), start_time)); } +void RenderWidgetHostViewAndroid::EnsureSurfaceSynchronizedForLayoutTest() { + ++latest_capture_sequence_number_; + WasResized(); +} + +uint32_t RenderWidgetHostViewAndroid::GetCaptureSequenceNumber() const { + return latest_capture_sequence_number_; +} + void RenderWidgetHostViewAndroid::ShowDisambiguationPopup( const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) { if (!tap_disambiguator_) @@ -2007,7 +2016,6 @@ void RenderWidgetHostViewAndroid::OnDetachedFromWindow() { StopObservingRootWindow(); OnDetachCompositor(); - view_.set_event_handler(nullptr); } void RenderWidgetHostViewAndroid::OnAttachCompositor() {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 2486b30ab..82aa4bcc 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -120,6 +120,8 @@ const gfx::Rect& src_rect, const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) override; + void EnsureSurfaceSynchronizedForLayoutTest() override; + uint32_t GetCaptureSequenceNumber() const override; bool DoBrowserControlsShrinkBlinkSize() const override; float GetTopControlsHeight() const override; float GetBottomControlsHeight() const override; @@ -491,6 +493,7 @@ base::ObserverList<DestructionObserver> destruction_observers_; MouseWheelPhaseHandler mouse_wheel_phase_handler_; + uint32_t latest_capture_sequence_number_ = 0u; base::WeakPtrFactory<RenderWidgetHostViewAndroid> weak_ptr_factory_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index e106d42..8480ce8 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -637,6 +637,11 @@ return delegated_frame_host_->CanCopyFromCompositingSurface(); } +void RenderWidgetHostViewAura::EnsureSurfaceSynchronizedForLayoutTest() { + ++latest_capture_sequence_number_; + WasResized(cc::DeadlinePolicy::UseInfiniteDeadline(), base::nullopt); +} + bool RenderWidgetHostViewAura::IsShowing() { return window_->IsVisible(); } @@ -844,6 +849,10 @@ : RenderWidgetHostViewBase::GetRequestedRendererSize(); } +uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const { + return latest_capture_sequence_number_; +} + void RenderWidgetHostViewAura::CopyFromSurface( const gfx::Rect& src_subrect, const gfx::Size& dst_size,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index af0b2e6c..957c8ffed 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -140,11 +140,13 @@ void SetTooltipText(const base::string16& tooltip_text) override; void DisplayTooltipText(const base::string16& tooltip_text) override; gfx::Size GetRequestedRendererSize() const override; + uint32_t GetCaptureSequenceNumber() const override; bool IsSurfaceAvailableForCopy() const override; void CopyFromSurface( const gfx::Rect& src_rect, const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) override; + void EnsureSurfaceSynchronizedForLayoutTest() override; gfx::Vector2d GetOffsetFromRootSurface() override; gfx::Rect GetBoundsInRootWindow() override; void WheelEventAck(const blink::WebMouseWheelEvent& event, @@ -660,6 +662,11 @@ std::unique_ptr<CursorManager> cursor_manager_; int tab_show_sequence_ = 0; + // Latest capture sequence number which is incremented when the caller + // requests surfaces be synchronized via + // EnsureSurfaceSynchronizedForLayoutTest(). + uint32_t latest_capture_sequence_number_ = 0u; + base::WeakPtrFactory<RenderWidgetHostViewAura> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAura);
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index ca70db5..0ebd7f5 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -154,6 +154,12 @@ return GetViewBounds().size(); } +uint32_t RenderWidgetHostViewBase::GetCaptureSequenceNumber() const { + // TODO(vmpstr): Implement this for overrides other than aura and child frame. + NOTIMPLEMENTED(); + return 0u; +} + ui::TextInputClient* RenderWidgetHostViewBase::GetTextInputClient() { NOTREACHED(); return nullptr;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 84d4c01..f226d2f 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -197,6 +197,9 @@ // when the view requires additional throttling. virtual gfx::Size GetRequestedRendererSize() const; + // Returns the current capture sequence number. + virtual uint32_t GetCaptureSequenceNumber() const; + // The size of the view's backing surface in non-DPI-adjusted pixels. virtual gfx::Size GetCompositorViewportPixelSize() const;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc index 7d23113..cde2ec2 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -241,6 +241,17 @@ return has_frame_; } +void RenderWidgetHostViewChildFrame::EnsureSurfaceSynchronizedForLayoutTest() { + // The capture sequence number which would normally be updated here is + // actually retrieved from the frame connector. +} + +uint32_t RenderWidgetHostViewChildFrame::GetCaptureSequenceNumber() const { + if (!frame_connector_) + return 0u; + return frame_connector_->capture_sequence_number(); +} + void RenderWidgetHostViewChildFrame::Show() { if (!host()->is_hidden()) return; @@ -1039,12 +1050,9 @@ const gfx::Size& new_size, uint64_t sequence_number, const viz::LocalSurfaceId& local_surface_id) { - if (frame_connector_) - frame_connector_->BeginResizeDueToAutoResize(); - base::OnceCallback<void()> allocation_task = base::BindOnce( &RenderWidgetHostViewChildFrame::OnResizeDueToAutoResizeComplete, - weak_factory_.GetWeakPtr(), sequence_number); + weak_factory_.GetWeakPtr(), sequence_number, local_surface_id); return viz::ScopedSurfaceIdAllocator(std::move(allocation_task)); } @@ -1128,9 +1136,10 @@ } void RenderWidgetHostViewChildFrame::OnResizeDueToAutoResizeComplete( - uint64_t sequence_number) { + uint64_t sequence_number, + viz::LocalSurfaceId local_surface_id) { if (frame_connector_) - frame_connector_->EndResizeDueToAutoResize(sequence_number); + frame_connector_->ResizeDueToAutoResize(sequence_number, local_surface_id); } void RenderWidgetHostViewChildFrame::DidNavigate() {
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h index a29772f2..9e6a5dd 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.h +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -96,6 +96,8 @@ const gfx::Rect& src_rect, const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) override; + void EnsureSurfaceSynchronizedForLayoutTest() override; + uint32_t GetCaptureSequenceNumber() const override; void Show() override; void Hide() override; bool IsShowing() override; @@ -296,7 +298,8 @@ // using CSS. bool CanBecomeVisible(); - void OnResizeDueToAutoResizeComplete(uint64_t sequence_number); + void OnResizeDueToAutoResizeComplete(uint64_t sequence_number, + viz::LocalSurfaceId local_surface_id); std::vector<base::OnceClosure> frame_swapped_callbacks_;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc index 1936d4e4..287d600 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
@@ -191,55 +191,4 @@ base::Unretained(this))); } -// Test that auto-resize messages only trigger a single allocation/response -// from the child. -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, - ChildFrameAutoResizeMessages) { - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(b)"))); - - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetFrameTree() - ->root(); - - // Create our message filter to intercept messages. - scoped_refptr<UpdateResizeParamsMessageFilter> message_filter = - new UpdateResizeParamsMessageFilter(); - root->current_frame_host()->GetProcess()->AddFilter(message_filter.get()); - - // Load cross-site page into iframe. - GURL cross_site_url( - embedded_test_server()->GetURL("foo.com", "/title2.html")); - // The child frame is created during this blocking call, on the UI thread. - // This is racing the IPC we are testing for, which arrives on the IO thread. - // Due to this we cannot get the pre-IPC value of the viz::FrameSinkId. - NavigateFrameToURL(root->child_at(0), cross_site_url); - - RenderWidgetHostImpl* child_frame_impl = - root->child_at(0)->current_frame_host()->GetRenderWidgetHost(); - child_frame_impl->SetAutoResize(true, gfx::Size(10, 10), gfx::Size(100, 100)); - - // Fake an auto-resize update from the parent renderer. - int routing_id = root->child_at(0) - ->current_frame_host() - ->GetRenderWidgetHost() - ->GetRoutingID(); - ViewHostMsg_ResizeOrRepaint_ACK_Params params; - params.view_size = gfx::Size(75, 75); - params.flags = 0; - params.sequence_number = 7; - viz::LocalSurfaceId current_id = - child_frame_impl->GetView()->GetLocalSurfaceId(); - params.child_allocated_local_surface_id = viz::LocalSurfaceId( - current_id.parent_sequence_number(), - current_id.child_sequence_number() + 1, current_id.embed_token()); - child_frame_impl->OnMessageReceived( - ViewHostMsg_ResizeOrRepaint_ACK(routing_id, params)); - - // The first UpdateResizeParams message received should have our new sequence - // number. - EXPECT_EQ(params.sequence_number, message_filter->WaitForSequenceNumber()); -} - } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index 7a55f92..d9d839a 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -355,6 +355,7 @@ resize_params.screen_space_rect = screen_space_rect; resize_params.local_frame_size = compositor_viewport_pixel_size; resize_params.auto_resize_sequence_number = 1u; + resize_params.capture_sequence_number = 123u; test_frame_connector_->UpdateResizeParams(surface_id, resize_params); ASSERT_EQ(1u, process->sink().message_count()); @@ -368,6 +369,7 @@ std::get<0>(params).compositor_viewport_pixel_size); EXPECT_EQ(screen_space_rect.size(), std::get<0>(params).new_size); EXPECT_EQ(local_surface_id, std::get<0>(params).local_surface_id); + EXPECT_EQ(123u, std::get<0>(params).capture_sequence_number); } } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 1385498..65337d2 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -131,6 +131,7 @@ const gfx::Rect& src_rect, const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) override; + void EnsureSurfaceSynchronizedForLayoutTest() override; void FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen) override; void DidCreateNewRendererCompositorFrameSink(
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index cd7ae59..4cfeb1e 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -683,6 +683,10 @@ src_subrect, dst_size, std::move(callback)); } +void RenderWidgetHostViewMac::EnsureSurfaceSynchronizedForLayoutTest() { + // TODO(vmpstr): Figure out what needs to be done here. +} + void RenderWidgetHostViewMac::SetNeedsBeginFrames(bool needs_begin_frames) { needs_begin_frames_ = needs_begin_frames; UpdateNeedsBeginFramesInternal();
diff --git a/content/browser/resources/gpu/browser_bridge.js b/content/browser/resources/gpu/browser_bridge.js index c2ad051..24e4b07 100644 --- a/content/browser/resources/gpu/browser_bridge.js +++ b/content/browser/resources/gpu/browser_bridge.js
@@ -143,8 +143,8 @@ * Returns the value of the "Sandboxed" row. */ isSandboxedForTesting : function() { - for (i = 0; i < this.gpuInfo_.basic_info.length; ++i) { - var info = this.gpuInfo_.basic_info[i]; + for (i = 0; i < this.gpuInfo_.basicInfo.length; ++i) { + var info = this.gpuInfo_.basicInfo[i]; if (info.description == "Sandboxed") return info.value; }
diff --git a/content/browser/resources/gpu/info_view.html b/content/browser/resources/gpu/info_view.html index 288f402d..1d44f6c 100644 --- a/content/browser/resources/gpu/info_view.html +++ b/content/browser/resources/gpu/info_view.html
@@ -61,6 +61,29 @@ <div id="diagnostics-table">None</div> </div> + <div class='basic-info-for-hardware-gpu-div'> + <h3>Driver Information for Hardware GPU</h3> + <div id="basic-info-for-hardware-gpu"></div> + </div> + + <div class='feature-status-for-hardware-gpu-div'> + <h3>Graphics Feature Status for Hardware GPU</h3> + <ul class="feature-status-for-hardware-gpu-list"> + </ul> + </div> + + <div class='workarounds-for-hardware-gpu-div'> + <h3>Driver Bug Workarounds for Hardware GPU</h3> + <ul class="workarounds-for-hardware-gpu-list"> + </ul> + </div> + + <div class='problems-for-hardware-gpu-div'> + <h3>Problems Detected for Hardware GPU</h3> + <ul class="problems-for-hardware-gpu-list"> + </ul> + </div> + <div id="log-messages" jsdisplay="values.length"> <h3>Log Messages</h3> <ul>
diff --git a/content/browser/resources/gpu/info_view.js b/content/browser/resources/gpu/info_view.js index eca2b710..bb8498b7e 100644 --- a/content/browser/resources/gpu/info_view.js +++ b/content/browser/resources/gpu/info_view.js
@@ -99,6 +99,125 @@ this.setText_('client-info', '... loading...'); } + + // GPU info, basic + var diagnosticsDiv = this.querySelector('.diagnostics'); + var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading'); + var featureStatusList = this.querySelector('.feature-status-list'); + var problemsDiv = this.querySelector('.problems-div'); + var problemsList = this.querySelector('.problems-list'); + var workaroundsDiv = this.querySelector('.workarounds-div'); + var workaroundsList = this.querySelector('.workarounds-list'); + + var basicInfoForHardwareGpuDiv = + this.querySelector('.basic-info-for-hardware-gpu-div'); + var featureStatusForHardwareGpuDiv = + this.querySelector('.feature-status-for-hardware-gpu-div'); + var featureStatusForHardwareGpuList = + this.querySelector('.feature-status-for-hardware-gpu-list'); + var problemsForHardwareGpuDiv = + this.querySelector('.problems-for-hardware-gpu-div'); + var problemsForHardwareGpuList = + this.querySelector('.problems-for-hardware-gpu-list'); + var workaroundsForHardwareGpuDiv = + this.querySelector('.workarounds-for-hardware-gpu-div'); + var workaroundsForHardwareGpuList = + this.querySelector('.workarounds-for-hardware-gpu-list'); + + var gpuInfo = browserBridge.gpuInfo; + var i; + if (gpuInfo) { + // Not using jstemplate here for blacklist status because we construct + // href from data, which jstemplate can't seem to do. + if (gpuInfo.featureStatus) { + this.appendFeatureInfo_(gpuInfo.featureStatus, featureStatusList, + problemsDiv, problemsList, + workaroundsDiv, workaroundsList); + } else { + featureStatusList.textContent = ''; + problemsList.hidden = true; + workaroundsList.hidden = true; + } + + if (gpuInfo.featureStatusForHardwareGpu) { + basicInfoForHardwareGpuDiv.hidden = false; + featureStatusForHardwareGpuDiv.hidden = false; + problemsForHardwareGpuDiv.hidden = false; + workaroundsForHardwareGpuDiv.hidden = false; + this.appendFeatureInfo_(gpuInfo.featureStatusForHardwareGpu, + featureStatusForHardwareGpuList, + problemsForHardwareGpuDiv, + problemsForHardwareGpuList, + workaroundsForHardwareGpuDiv, + workaroundsForHardwareGpuList); + if (gpuInfo.basicInfoForHardwareGpu) { + this.setTable_('basic-info-for-hardware-gpu', + gpuInfo.basicInfoForHardwareGpu); + } else { + this.setTable_('basic-info-for-hardware-gpu', []); + } + } else { + basicInfoForHardwareGpuDiv.hidden = true; + featureStatusForHardwareGpuDiv.hidden = true; + problemsForHardwareGpuDiv.hidden = true; + workaroundsForHardwareGpuDiv.hidden = true; + } + + if (gpuInfo.basicInfo) + this.setTable_('basic-info', gpuInfo.basicInfo); + else + this.setTable_('basic-info', []); + + if (gpuInfo.compositorInfo) + this.setTable_('compositor-info', gpuInfo.compositorInfo); + else + this.setTable_('compositor-info', []); + + if (gpuInfo.gpuMemoryBufferInfo) + this.setTable_('gpu-memory-buffer-info', gpuInfo.gpuMemoryBufferInfo); + else + this.setTable_('gpu-memory-buffer-info', []); + + if (gpuInfo.displayInfo) + this.setTable_('display-info', gpuInfo.displayInfo); + else + this.setTable_('display-info', []); + + if (gpuInfo.videoAcceleratorsInfo) { + this.setTable_( + 'video-acceleration-info', gpuInfo.videoAcceleratorsInfo); + } else { + this.setTable_('video-acceleration-info', []); + } + + if (gpuInfo.diagnostics) { + diagnosticsDiv.hidden = false; + diagnosticsLoadingDiv.hidden = true; + $('diagnostics-table').hidden = false; + this.setTable_('diagnostics-table', gpuInfo.diagnostics); + } else if (gpuInfo.diagnostics === null) { + // gpu_internals.cc sets diagnostics to null when it is being loaded + diagnosticsDiv.hidden = false; + diagnosticsLoadingDiv.hidden = false; + $('diagnostics-table').hidden = true; + } else { + diagnosticsDiv.hidden = true; + } + } else { + this.setText_('basic-info', '... loading ...'); + diagnosticsDiv.hidden = true; + featureStatusList.textContent = ''; + problemsDiv.hidden = true; + } + + // Log messages + jstProcess(new JsEvalContext({values: browserBridge.logMessages}), + $('log-messages')); + }, + + appendFeatureInfo_: function(featureInfo, featureStatusList, + problemsDiv, problemsList, + workaroundsDiv, workaroundsList) { // Feature map var featureLabelMap = { '2d_canvas': 'Canvas', @@ -167,130 +286,58 @@ }, }; - // GPU info, basic - var diagnosticsDiv = this.querySelector('.diagnostics'); - var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading'); - var featureStatusList = this.querySelector('.feature-status-list'); - var problemsDiv = this.querySelector('.problems-div'); - var problemsList = this.querySelector('.problems-list'); - var workaroundsDiv = this.querySelector('.workarounds-div'); - var workaroundsList = this.querySelector('.workarounds-list'); - var gpuInfo = browserBridge.gpuInfo; - var i; - if (gpuInfo) { - // Not using jstemplate here for blacklist status because we construct - // href from data, which jstemplate can't seem to do. - if (gpuInfo.featureStatus) { - // feature status list - featureStatusList.textContent = ''; - for (var featureName in gpuInfo.featureStatus.featureStatus) { - var featureStatus = - gpuInfo.featureStatus.featureStatus[featureName]; - var featureEl = document.createElement('li'); + // feature status list + featureStatusList.textContent = ''; + for (var featureName in featureInfo.featureStatus) { + var featureStatus = featureInfo.featureStatus[featureName]; + var featureEl = document.createElement('li'); - var nameEl = document.createElement('span'); - if (!featureLabelMap[featureName]) - console.log('Missing featureLabel for', featureName); - nameEl.textContent = featureLabelMap[featureName] + ': '; - featureEl.appendChild(nameEl); + var nameEl = document.createElement('span'); + if (!featureLabelMap[featureName]) + console.log('Missing featureLabel for', featureName); + nameEl.textContent = featureLabelMap[featureName] + ': '; + featureEl.appendChild(nameEl); - var statusEl = document.createElement('span'); - var statusInfo = statusMap[featureStatus]; - if (!statusInfo) { - console.log('Missing status for ', featureStatus); - statusEl.textContent = 'Unknown'; - statusEl.className = 'feature-red'; - } else { - statusEl.textContent = statusInfo['label']; - statusEl.className = statusInfo['class']; - } - featureEl.appendChild(statusEl); - - featureStatusList.appendChild(featureEl); - } - - // problems list - if (gpuInfo.featureStatus.problems.length) { - problemsDiv.hidden = false; - problemsList.textContent = ''; - for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) { - var problem = gpuInfo.featureStatus.problems[i]; - var problemEl = this.createProblemEl_(problem); - problemsList.appendChild(problemEl); - } - } else { - problemsDiv.hidden = true; - } - - // driver bug workarounds list - if (gpuInfo.featureStatus.workarounds.length) { - workaroundsDiv.hidden = false; - workaroundsList.textContent = ''; - for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) { - var workaroundEl = document.createElement('li'); - workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i]; - workaroundsList.appendChild(workaroundEl); - } - } else { - workaroundsDiv.hidden = true; - } - + var statusEl = document.createElement('span'); + var statusInfo = statusMap[featureStatus]; + if (!statusInfo) { + console.log('Missing status for ', featureStatus); + statusEl.textContent = 'Unknown'; + statusEl.className = 'feature-red'; } else { - featureStatusList.textContent = ''; - problemsList.hidden = true; - workaroundsList.hidden = true; + statusEl.textContent = statusInfo['label']; + statusEl.className = statusInfo['class']; } + featureEl.appendChild(statusEl); - if (gpuInfo.basic_info) - this.setTable_('basic-info', gpuInfo.basic_info); - else - this.setTable_('basic-info', []); + featureStatusList.appendChild(featureEl); + } - if (gpuInfo.compositorInfo) - this.setTable_('compositor-info', gpuInfo.compositorInfo); - else - this.setTable_('compositor-info', []); - - if (gpuInfo.gpuMemoryBufferInfo) - this.setTable_('gpu-memory-buffer-info', gpuInfo.gpuMemoryBufferInfo); - else - this.setTable_('gpu-memory-buffer-info', []); - - if (gpuInfo.displayInfo) - this.setTable_('display-info', gpuInfo.displayInfo); - else - this.setTable_('display-info', []); - - if (gpuInfo.videoAcceleratorsInfo) { - this.setTable_( - 'video-acceleration-info', gpuInfo.videoAcceleratorsInfo); - } else { - this.setTable_('video-acceleration-info', []); - } - - if (gpuInfo.diagnostics) { - diagnosticsDiv.hidden = false; - diagnosticsLoadingDiv.hidden = true; - $('diagnostics-table').hidden = false; - this.setTable_('diagnostics-table', gpuInfo.diagnostics); - } else if (gpuInfo.diagnostics === null) { - // gpu_internals.cc sets diagnostics to null when it is being loaded - diagnosticsDiv.hidden = false; - diagnosticsLoadingDiv.hidden = false; - $('diagnostics-table').hidden = true; - } else { - diagnosticsDiv.hidden = true; + // problems list + if (featureInfo.problems.length) { + problemsDiv.hidden = false; + problemsList.textContent = ''; + for (i = 0; i < featureInfo.problems.length; i++) { + var problem = featureInfo.problems[i]; + var problemEl = this.createProblemEl_(problem); + problemsList.appendChild(problemEl); } } else { - this.setText_('basic-info', '... loading ...'); - diagnosticsDiv.hidden = true; - featureStatusList.textContent = ''; problemsDiv.hidden = true; } - // Log messages - jstProcess(new JsEvalContext({values: browserBridge.logMessages}), - $('log-messages')); + // driver bug workarounds list + if (featureInfo.workarounds.length) { + workaroundsDiv.hidden = false; + workaroundsList.textContent = ''; + for (i = 0; i < featureInfo.workarounds.length; i++) { + var workaroundEl = document.createElement('li'); + workaroundEl.textContent = featureInfo.workarounds[i]; + workaroundsList.appendChild(workaroundEl); + } + } else { + workaroundsDiv.hidden = true; + } }, createProblemEl_: function(problem) {
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 2663268b..752f5e7 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -74,10 +74,6 @@ #include "content/public/common/content_descriptors.h" #endif -#if defined(OS_MACOSX) -#include "base/allocator/allocator_interception_mac.h" -#endif - namespace content { namespace { @@ -562,14 +558,6 @@ connection_timeout = temp; } -#if defined(OS_MACOSX) - if (base::CommandLine::InitializedForCurrentProcess() && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableHeapProfiling)) { - base::allocator::PeriodicallyShimNewMallocZones(); - } -#endif - message_loop_->task_runner()->PostDelayedTask( FROM_HERE, base::BindOnce(&ChildThreadImpl::EnsureConnected,
diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index 8799191..1d6c41d 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h
@@ -187,11 +187,12 @@ int /* browser_plugin_instance_id */, bool /* reverse */) -// When a guest resizes due to auto-resize, this message informs the -// BrowserPlugin to request a new viz::LocalSurfaceId. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_ResizeDueToAutoResize, +// Informs the BrowserPlugin that the guest's auto-resize transaction is +// complete and it should update with the provided viz::LocalSurfaceId. +IPC_MESSAGE_CONTROL3(BrowserPluginMsg_ResizeDueToAutoResize, int /* browser_plugin_instance_id */, - uint64_t /* sequence_number */) + uint64_t /* sequence_number */, + viz::LocalSurfaceId /* child_allocated_surface_id */) // Requests a viz::LocalSurfaceId to enable auto-resize mode from the parent // renderer.
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index d8ac388..da691e7 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -243,6 +243,7 @@ IPC_STRUCT_TRAITS_MEMBER(auto_resize_sequence_number) IPC_STRUCT_TRAITS_MEMBER(screen_space_rect) IPC_STRUCT_TRAITS_MEMBER(local_frame_size) + IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(blink::FramePolicy) @@ -995,15 +996,11 @@ // Tells the RenderFrame to clear the focused element (if any). IPC_MESSAGE_ROUTED0(FrameMsg_ClearFocusedElement) -// Informs the parent renderer that the child is beginning an autoresize -// transaction. -IPC_MESSAGE_ROUTED(FrameMsg_BeginResizeDueToAutoResize) - // Informs the parent renderer that the child has completed an autoresize -// transaction and that the child can now allocate a new viz::LocalSurfaceId -// for its new size. -IPC_MESSAGE_ROUTED1(FrameMsg_EndResizeDueToAutoResize, - uint64_t /* sequence_number */) +// transaction and should update with the provided viz::LocalSurfaceId. +IPC_MESSAGE_ROUTED2(FrameMsg_ResizeDueToAutoResize, + uint64_t /* sequence_number */, + viz::LocalSurfaceId /* child_allocated_surface_id */) // Requests a viz::LocalSurfaceId to enable auto-resize mode from the parent // renderer.
diff --git a/content/common/frame_resize_params.cc b/content/common/frame_resize_params.cc index fc5059d..39a7791 100644 --- a/content/common/frame_resize_params.cc +++ b/content/common/frame_resize_params.cc
@@ -6,12 +6,9 @@ namespace content { -FrameResizeParams::FrameResizeParams() - : auto_resize_enabled(false), auto_resize_sequence_number(0u) {} - +FrameResizeParams::FrameResizeParams() = default; FrameResizeParams::FrameResizeParams(const FrameResizeParams& other) = default; - -FrameResizeParams::~FrameResizeParams() {} +FrameResizeParams::~FrameResizeParams() = default; FrameResizeParams& FrameResizeParams::operator=( const FrameResizeParams& other) = default;
diff --git a/content/common/frame_resize_params.h b/content/common/frame_resize_params.h index 4255907..50c09d9 100644 --- a/content/common/frame_resize_params.h +++ b/content/common/frame_resize_params.h
@@ -24,7 +24,7 @@ ScreenInfo screen_info; // Whether or not blink should be in auto-resize mode. - bool auto_resize_enabled; + bool auto_resize_enabled = false; // The minimum size for Blink if auto-resize is enabled. gfx::Size min_size_for_auto_resize; @@ -35,11 +35,13 @@ // This variable is increased after each auto-resize. If the // renderer receives a ResizeParams with stale auto_resize_seqence_number, // then the resize request is dropped. - uint64_t auto_resize_sequence_number; + uint64_t auto_resize_sequence_number = 0u; gfx::Rect screen_space_rect; gfx::Size local_frame_size; + + uint32_t capture_sequence_number = 0u; }; } // namespace content
diff --git a/content/common/resize_params.cc b/content/common/resize_params.cc index 5e1fd102..eeb4d67 100644 --- a/content/common/resize_params.cc +++ b/content/common/resize_params.cc
@@ -6,20 +6,10 @@ namespace content { -ResizeParams::ResizeParams() - : auto_resize_enabled(false), - auto_resize_sequence_number(0u), - browser_controls_shrink_blink_size(false), - scroll_focused_node_into_view(false), - top_controls_height(0.f), - bottom_controls_height(0.f), - is_fullscreen_granted(false), - display_mode(blink::kWebDisplayModeUndefined), - needs_resize_ack(false), - content_source_id(0u) {} - +ResizeParams::ResizeParams() = default; ResizeParams::ResizeParams(const ResizeParams& other) = default; +ResizeParams::~ResizeParams() = default; -ResizeParams::~ResizeParams() {} +ResizeParams& ResizeParams::operator=(const ResizeParams& other) = default; } // namespace content
diff --git a/content/common/resize_params.h b/content/common/resize_params.h index 51c472d..5abe35ec 100644 --- a/content/common/resize_params.h +++ b/content/common/resize_params.h
@@ -19,11 +19,13 @@ ResizeParams(const ResizeParams& other); ~ResizeParams(); + ResizeParams& operator=(const ResizeParams& other); + // Information about the screen (dpi, depth, etc..). ScreenInfo screen_info; // Whether or not blink should be in auto-resize mode. - bool auto_resize_enabled; + bool auto_resize_enabled = false; // The minimum size for Blink if auto-resize is enabled. gfx::Size min_size_for_auto_resize; @@ -34,7 +36,7 @@ // This variable is increased after each auto-resize. If the // renderer receives a ResizeParams with stale auto_resize_seqence_number, // then the resize request is dropped. - uint64_t auto_resize_sequence_number; + uint64_t auto_resize_sequence_number = 0u; // The size for the widget in DIPs. gfx::Size new_size; @@ -46,18 +48,18 @@ // Whether or not Blink's viewport size should be shrunk by the height of the // URL-bar (always false on platforms where URL-bar hiding isn't supported). - bool browser_controls_shrink_blink_size; + bool browser_controls_shrink_blink_size = false; // Whether or not the focused node should be scrolled into view after the // resize. - bool scroll_focused_node_into_view; + bool scroll_focused_node_into_view = false; // The height of the top controls (always 0 on platforms where URL-bar hiding // isn't supported). - float top_controls_height; + float top_controls_height = 0.f; // The height of the bottom controls. - float bottom_controls_height; + float bottom_controls_height = 0.f; // The local surface ID to use (if valid). base::Optional<viz::LocalSurfaceId> local_surface_id; @@ -68,20 +70,25 @@ gfx::Size visible_viewport_size; // Indicates whether tab-initiated fullscreen was granted. - bool is_fullscreen_granted; + bool is_fullscreen_granted = false; // The display mode. - blink::WebDisplayMode display_mode; + blink::WebDisplayMode display_mode = blink::kWebDisplayModeUndefined; // If set, requests the renderer to reply with a // ViewHostMsg_ResizeOrRepaint_ACK with the // ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK bit set in flags. - bool needs_resize_ack; + bool needs_resize_ack = false; // This variable is increased after each cross-document navigation. If the // renderer receives a ResizeParams with stale content_source_id, it still // performs the resize but doesn't use the given LocalSurfaceId. - uint32_t content_source_id; + uint32_t content_source_id = 0u; + + // This represents the latest capture sequence number requested. When this is + // incremented, that means the caller wants to synchronize surfaces which + // should cause a new LocalSurfaceId to be generated. + uint32_t capture_sequence_number = 0u; }; } // namespace content
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index d2881f98..1d5f2b9e 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -179,6 +179,7 @@ IPC_STRUCT_TRAITS_MEMBER(display_mode) IPC_STRUCT_TRAITS_MEMBER(needs_resize_ack) IPC_STRUCT_TRAITS_MEMBER(content_source_id) + IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::MenuItem)
diff --git a/content/public/browser/browsing_data_filter_builder.h b/content/public/browser/browsing_data_filter_builder.h index b4ffa39..84035ad 100644 --- a/content/public/browser/browsing_data_filter_builder.h +++ b/content/public/browser/browsing_data_filter_builder.h
@@ -67,9 +67,11 @@ virtual base::RepeatingCallback<bool(const GURL&)> BuildGeneralFilter() const = 0; - // Builds a filter that can be used with the network service, more precisely - // with NetworkContext.ClearHttpCache(). - virtual network::mojom::ClearCacheUrlFilterPtr BuildClearCacheUrlFilter() + // Builds a filter that can be used with the network service. This uses a Mojo + // struct rather than a predicate function (as used by the rest of the filters + // built by this class) because we need to be able to pass the filter to the + // network service via IPC. + virtual network::mojom::ClearDataFilterPtr BuildNetworkServiceFilter() const = 0; // Builds a CookieDeletionInfo object that matches cookies whose sources are @@ -77,11 +79,6 @@ virtual net::CookieStore::CookieDeletionInfo BuildCookieDeletionInfo() const = 0; - // Builds a filter that matches channel IDs whose server identifiers are in - // the whitelist, or aren't in the blacklist. - virtual base::RepeatingCallback<bool(const std::string& server_id)> - BuildChannelIDFilter() const = 0; - // Builds a filter that matches the |site| of a plugin. virtual base::RepeatingCallback<bool(const std::string& site)> BuildPluginFilter() const = 0;
diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h index ebe6ba5..481bf03 100644 --- a/content/public/browser/gpu_data_manager.h +++ b/content/public/browser/gpu_data_manager.h
@@ -61,10 +61,6 @@ // Whether a GPU is in use (as opposed to a software renderer). virtual bool HardwareAccelerationEnabled() const = 0; - // Extensions that are currently disabled. - virtual void GetDisabledExtensions( - std::string* disabled_extensions) const = 0; - protected: virtual ~GpuDataManager() {} };
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h index 1ced1c48..3b9d912 100644 --- a/content/public/browser/render_widget_host_view.h +++ b/content/public/browser/render_widget_host_view.h
@@ -184,8 +184,7 @@ // visible viewport. virtual void SetInsets(const gfx::Insets& insets) = 0; - // Returns true if the current display surface is available, a prerequisite - // for CopyFromSurface() to succeed. + // Returns true if the current display surface is available. virtual bool IsSurfaceAvailableForCopy() const = 0; // Copies the given subset of the view's surface, optionally scales it, and @@ -214,6 +213,10 @@ const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) = 0; + // Ensures that all surfaces are synchronized for the next call to + // CopyFromSurface. This is used by LayoutTests. + virtual void EnsureSurfaceSynchronizedForLayoutTest() = 0; + // Creates a video capturer, which will allow the caller to receive a stream // of media::VideoFrames captured from this view. The capturer is configured // to target this view, so there is no need to call ChangeTarget() before
diff --git a/content/public/browser/site_isolation_policy.cc b/content/public/browser/site_isolation_policy.cc index aa1599d..0a75907 100644 --- a/content/public/browser/site_isolation_policy.cc +++ b/content/public/browser/site_isolation_policy.cc
@@ -72,11 +72,6 @@ if (UseDedicatedProcessesForAllSites()) return false; - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableSiteIsolationTrials)) { - return false; - } - // The feature needs to be checked last, because checking the feature // activates the field trial and assigns the client either to a control or an // experiment group - such assignment should be final.
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index d377a68..decf99d 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -37,20 +37,24 @@ #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/browser_plugin/browser_plugin_guest.h" +#include "content/browser/browser_plugin/browser_plugin_message_filter.h" #include "content/browser/compositor/surface_utils.h" #include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" #include "content/browser/service_manager/service_manager_context.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_view.h" +#include "content/common/browser_plugin/browser_plugin_messages.h" #include "content/common/fileapi/file_system_messages.h" #include "content/common/fileapi/webblob_messages.h" #include "content/common/frame_messages.h" +#include "content/common/frame_resize_params.h" #include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" @@ -73,6 +77,7 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/service_names.mojom.h" +#include "content/public/common/use_zoom_for_dsf_policy.h" #include "content/public/test/simple_url_loader_test_helper.h" #include "content/public/test/test_fileapi_operation_waiter.h" #include "content/public/test/test_navigation_observer.h" @@ -2539,4 +2544,181 @@ process_group_name); } +bool TestChildOrGuestAutoresize(bool is_guest, + RenderProcessHost* embedder_rph, + RenderWidgetHost* guest_rwh) { + RenderProcessHostImpl* embedder_rph_impl = + static_cast<RenderProcessHostImpl*>(embedder_rph); + RenderWidgetHostImpl* guest_rwh_impl = + static_cast<RenderWidgetHostImpl*>(guest_rwh); + + scoped_refptr<UpdateResizeParamsMessageFilter> filter( + new UpdateResizeParamsMessageFilter()); + + // Register the message filter for the guest or child. For guest, we must use + // a special hook, as there are already message filters installed which will + // supercede us. + if (is_guest) { + embedder_rph_impl->SetBrowserPluginMessageFilterSubFilterForTesting( + filter.get()); + } else { + embedder_rph_impl->AddFilter(filter.get()); + } + + viz::LocalSurfaceId current_id = + guest_rwh_impl->GetView()->GetLocalSurfaceId(); + // The guest may not yet be fully attached / initted. If not, |current_id| + // will be invalid, and we should wait for an ID before proceeding. + if (!current_id.is_valid()) + current_id = filter->WaitForSurfaceId(); + + // Enable auto-resize. + guest_rwh_impl->SetAutoResize(true, gfx::Size(10, 10), gfx::Size(100, 100)); + + // Fake an auto-resize update. + int routing_id = guest_rwh_impl->GetRoutingID(); + ViewHostMsg_ResizeOrRepaint_ACK_Params params; + params.view_size = gfx::Size(75, 75); + params.flags = 0; + params.sequence_number = 7; + params.child_allocated_local_surface_id = viz::LocalSurfaceId( + current_id.parent_sequence_number(), + current_id.child_sequence_number() + 1, current_id.embed_token()); + guest_rwh_impl->OnMessageReceived( + ViewHostMsg_ResizeOrRepaint_ACK(routing_id, params)); + + // Get the first delivered surface id and ensure it has the surface id which + // we expect. + return filter->WaitForSurfaceId() == params.child_allocated_local_surface_id; +} + +const uint32_t UpdateResizeParamsMessageFilter::kMessageClassesToFilter[2] = { + FrameMsgStart, BrowserPluginMsgStart}; + +UpdateResizeParamsMessageFilter::UpdateResizeParamsMessageFilter() + : content::BrowserMessageFilter(kMessageClassesToFilter, + arraysize(kMessageClassesToFilter)), + screen_space_rect_run_loop_(std::make_unique<base::RunLoop>()), + screen_space_rect_received_(false) {} + +void UpdateResizeParamsMessageFilter::WaitForRect() { + screen_space_rect_run_loop_->Run(); +} + +void UpdateResizeParamsMessageFilter::ResetRectRunLoop() { + last_rect_ = gfx::Rect(); + screen_space_rect_run_loop_.reset(new base::RunLoop); + screen_space_rect_received_ = false; +} + +viz::FrameSinkId UpdateResizeParamsMessageFilter::GetOrWaitForId() { + // No-op if already quit. + frame_sink_id_run_loop_.Run(); + return frame_sink_id_; +} + +viz::LocalSurfaceId UpdateResizeParamsMessageFilter::WaitForSurfaceId() { + surface_id_run_loop_.reset(new base::RunLoop); + surface_id_run_loop_->Run(); + return last_surface_id_; +} + +UpdateResizeParamsMessageFilter::~UpdateResizeParamsMessageFilter() {} + +void UpdateResizeParamsMessageFilter::OnUpdateFrameHostResizeParams( + const viz::SurfaceId& surface_id, + const FrameResizeParams& resize_params) { + OnUpdateResizeParams(surface_id.local_surface_id(), + surface_id.frame_sink_id(), resize_params); +} + +void UpdateResizeParamsMessageFilter::OnUpdateBrowserPluginResizeParams( + int browser_plugin_guest_instance_id, + viz::LocalSurfaceId surface_id, + FrameResizeParams resize_params) { + OnUpdateResizeParams(surface_id, viz::FrameSinkId(), resize_params); +} + +void UpdateResizeParamsMessageFilter::OnUpdateResizeParams( + const viz::LocalSurfaceId& local_surface_id, + const viz::FrameSinkId& frame_sink_id, + const FrameResizeParams& resize_params) { + gfx::Rect screen_space_rect_in_dip = resize_params.screen_space_rect; + if (IsUseZoomForDSFEnabled()) { + screen_space_rect_in_dip = + gfx::Rect(gfx::ScaleToFlooredPoint( + resize_params.screen_space_rect.origin(), + 1.f / resize_params.screen_info.device_scale_factor), + gfx::ScaleToCeiledSize( + resize_params.screen_space_rect.size(), + 1.f / resize_params.screen_info.device_scale_factor)); + } + // Track each rect updates. + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&UpdateResizeParamsMessageFilter::OnUpdatedFrameRectOnUI, + this, screen_space_rect_in_dip)); + + // Track each surface id update. + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&UpdateResizeParamsMessageFilter::OnUpdatedSurfaceIdOnUI, + this, local_surface_id)); + + // Record the received value. We cannot check the current state of the child + // frame, as it can only be processed on the UI thread, and we cannot block + // here. + frame_sink_id_ = frame_sink_id; + + // There can be several updates before a valid viz::FrameSinkId is ready. Do + // not quit |run_loop_| until after we receive a valid one. + if (!frame_sink_id_.is_valid()) + return; + + // We can't nest on the IO thread. So tests will wait on the UI thread, so + // post there to exit the nesting. + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) + ->PostTask(FROM_HERE, + base::BindOnce( + &UpdateResizeParamsMessageFilter::OnUpdatedFrameSinkIdOnUI, + this)); +} + +void UpdateResizeParamsMessageFilter::OnUpdatedFrameRectOnUI( + const gfx::Rect& rect) { + last_rect_ = rect; + if (!screen_space_rect_received_) { + screen_space_rect_received_ = true; + // Tests looking at the rect currently expect all received input to finish + // processing before the test continutes. + screen_space_rect_run_loop_->QuitWhenIdle(); + } +} + +void UpdateResizeParamsMessageFilter::OnUpdatedFrameSinkIdOnUI() { + frame_sink_id_run_loop_.Quit(); +} + +void UpdateResizeParamsMessageFilter::OnUpdatedSurfaceIdOnUI( + viz::LocalSurfaceId surface_id) { + last_surface_id_ = surface_id; + if (surface_id_run_loop_) { + surface_id_run_loop_->QuitWhenIdle(); + } +} + +bool UpdateResizeParamsMessageFilter::OnMessageReceived( + const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(UpdateResizeParamsMessageFilter, message) + IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateResizeParams, + OnUpdateFrameHostResizeParams) + IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateResizeParams, + OnUpdateBrowserPluginResizeParams) + IPC_END_MESSAGE_MAP() + + // We do not consume the message, so that we can verify the effects of it + // being processed. + return false; +} + } // namespace content
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 7bdc7185..a8eb280 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -71,6 +71,7 @@ namespace content { class BrowserContext; +struct FrameResizeParams; class InterstitialPage; class MessageLoopRunner; class NavigationHandle; @@ -1143,6 +1144,65 @@ // called on the IO thread. bool HasValidProcessForProcessGroup(const std::string& process_group_name); +// Performs a simple auto-resize flow and ensures that the embedder gets a +// single response messages back from the guest, with the expected values. +bool TestChildOrGuestAutoresize(bool is_guest, + RenderProcessHost* embedder_rph, + RenderWidgetHost* guest_rwh); + +// Class to sniff incoming IPCs for either FrameHostMsg_UpdateResizeParams or +// BrowserPluginHostMsg_UpdateResizeParams messages. This allows the message to +// continue to the target child so that processing can be verified by tests. +class UpdateResizeParamsMessageFilter : public content::BrowserMessageFilter { + public: + UpdateResizeParamsMessageFilter(); + + gfx::Rect last_rect() const { return last_rect_; } + + void WaitForRect(); + void ResetRectRunLoop(); + + // Returns the new viz::FrameSinkId immediately if the IPC has been received. + // Otherwise this will block the UI thread until it has been received, then it + // will return the new viz::FrameSinkId. + viz::FrameSinkId GetOrWaitForId(); + + // Waits for the next viz::LocalSurfaceId be received and returns it. + viz::LocalSurfaceId WaitForSurfaceId(); + + protected: + ~UpdateResizeParamsMessageFilter() override; + + private: + void OnUpdateFrameHostResizeParams(const viz::SurfaceId& surface_id, + const FrameResizeParams& resize_params); + void OnUpdateBrowserPluginResizeParams(int browser_plugin_guest_instance_id, + viz::LocalSurfaceId surface_id, + FrameResizeParams resize_params); + void OnUpdateResizeParams(const viz::LocalSurfaceId& surface_id, + const viz::FrameSinkId& frame_sink_id, + const FrameResizeParams& resize_params); + // |rect| is in DIPs. + void OnUpdatedFrameRectOnUI(const gfx::Rect& rect); + void OnUpdatedFrameSinkIdOnUI(); + void OnUpdatedSurfaceIdOnUI(viz::LocalSurfaceId surface_id); + + bool OnMessageReceived(const IPC::Message& message) override; + + static const uint32_t kMessageClassesToFilter[2]; + viz::FrameSinkId frame_sink_id_; + base::RunLoop frame_sink_id_run_loop_; + + std::unique_ptr<base::RunLoop> screen_space_rect_run_loop_; + bool screen_space_rect_received_; + gfx::Rect last_rect_; + + viz::LocalSurfaceId last_surface_id_; + std::unique_ptr<base::RunLoop> surface_id_run_loop_; + + DISALLOW_COPY_AND_ASSIGN(UpdateResizeParamsMessageFilter); +}; + } // namespace content #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index c5fe59a..6e405a6b 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -250,7 +250,30 @@ } #endif -void BrowserPlugin::WasResized() { +void BrowserPlugin::WasResized( + const viz::LocalSurfaceId& child_allocated_surface_id) { + // TODO(ericrk): Once we short-circuit responses to child allocated surface + // IDs, we can remove |surface_id_changed| here and simply update. + // https://crbug.com/811944 + bool surface_id_changed = false; + if (child_allocated_surface_id.is_valid()) { + viz::LocalSurfaceId previous_id = GetLocalSurfaceId(); + parent_local_surface_id_allocator_.UpdateFromChild( + child_allocated_surface_id); + surface_id_changed = previous_id != GetLocalSurfaceId(); + } + + // We no longer use auto resize sequence numbers to trigger ID generation, + // instead getting auto resize IDs from the child. If our auto-resize + // sequence number changed our surface ID must change as well. + // TODO(ericrk): Once we short-circuit, we can remove references to sequence + // numbers and clean this up. https://crbug.com/811944. + if (sent_resize_params_ && + sent_resize_params_->auto_resize_sequence_number != + pending_resize_params_.auto_resize_sequence_number) { + DCHECK(surface_id_changed); + } + bool size_changed = !sent_resize_params_ || sent_resize_params_->auto_resize_enabled != pending_resize_params_.auto_resize_enabled || @@ -261,29 +284,40 @@ sent_resize_params_->local_frame_size != pending_resize_params_.local_frame_size || sent_resize_params_->screen_space_rect.size() != - pending_resize_params_.screen_space_rect.size() || - sent_resize_params_->auto_resize_sequence_number != - pending_resize_params_.auto_resize_sequence_number; + pending_resize_params_.screen_space_rect.size(); + + // Note that the following flag is true if the capture sequence number + // actually changed. That is, it is false if we did not have + // |sent_resize_params_|, which is different from the other local flags here. + bool capture_sequence_number_changed = + sent_resize_params_ && sent_resize_params_->capture_sequence_number != + pending_resize_params_.capture_sequence_number; bool synchronized_params_changed = !sent_resize_params_ || size_changed || - sent_resize_params_->screen_info != pending_resize_params_.screen_info; + sent_resize_params_->screen_info != pending_resize_params_.screen_info || + capture_sequence_number_changed; if (synchronized_params_changed) parent_local_surface_id_allocator_.GenerateId(); if (enable_surface_synchronization_ && frame_sink_id_.is_valid()) { - // TODO(vmpstr): When capture_sequence_number is available, the deadline - // should be infinite if the sequence number has changed. + // If we're synchronizing surfaces, then use an infinite deadline to ensure + // everything is synchronized. + cc::DeadlinePolicy deadline = + capture_sequence_number_changed + ? cc::DeadlinePolicy::UseInfiniteDeadline() + : cc::DeadlinePolicy::UseDefaultDeadline(); compositing_helper_->SetPrimarySurfaceId( viz::SurfaceId(frame_sink_id_, GetLocalSurfaceId()), - screen_space_rect().size(), cc::DeadlinePolicy::UseDefaultDeadline()); + screen_space_rect().size(), deadline); } bool position_changed = !sent_resize_params_ || sent_resize_params_->screen_space_rect.origin() != pending_resize_params_.screen_space_rect.origin(); - bool resize_params_changed = synchronized_params_changed || position_changed; + bool resize_params_changed = + synchronized_params_changed || position_changed || surface_id_changed; if (resize_params_changed && attached()) { // Let the browser know about the updated view rect. @@ -323,7 +357,7 @@ attached_ = true; if (child_local_surface_id) parent_local_surface_id_allocator_.Reset(*child_local_surface_id); - WasResized(); + WasResized(viz::LocalSurfaceId()); } void BrowserPlugin::OnGuestGone(int browser_plugin_instance_id) { @@ -337,13 +371,15 @@ guest_crashed_ = false; frame_sink_id_ = frame_sink_id; sent_resize_params_ = base::nullopt; - WasResized(); + WasResized(viz::LocalSurfaceId()); } -void BrowserPlugin::OnResizeDueToAutoResize(int browser_plugin_instance_id, - uint64_t sequence_number) { +void BrowserPlugin::OnResizeDueToAutoResize( + int browser_plugin_instance_id, + uint64_t sequence_number, + viz::LocalSurfaceId child_allocated_local_surface_id) { pending_resize_params_.auto_resize_sequence_number = sequence_number; - WasResized(); + WasResized(child_allocated_local_surface_id); } void BrowserPlugin::OnEnableAutoResize(int browser_plugin_instance_id, @@ -352,12 +388,12 @@ pending_resize_params_.auto_resize_enabled = true; pending_resize_params_.min_size_for_auto_resize = min_size; pending_resize_params_.max_size_for_auto_resize = max_size; - WasResized(); + WasResized(viz::LocalSurfaceId()); } void BrowserPlugin::OnDisableAutoResize(int browser_plugin_instance_id) { pending_resize_params_.auto_resize_enabled = false; - WasResized(); + WasResized(viz::LocalSurfaceId()); } void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id, @@ -449,7 +485,13 @@ screen_info.device_scale_factor); return; } - WasResized(); + WasResized(viz::LocalSurfaceId()); +} + +void BrowserPlugin::UpdateCaptureSequenceNumber( + uint32_t capture_sequence_number) { + pending_resize_params_.capture_sequence_number = capture_sequence_number; + WasResized(viz::LocalSurfaceId()); } bool BrowserPlugin::ShouldGuestBeFocused() const { @@ -581,7 +623,7 @@ screen_info().device_scale_factor); return; } - WasResized(); + WasResized(viz::LocalSurfaceId()); } void BrowserPlugin::UpdateFocus(bool focused, blink::WebFocusType focus_type) {
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index a123a1b..0d46f46 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -76,6 +76,8 @@ void ScreenInfoChanged(const ScreenInfo& screen_info); + void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number); + // Indicates whether the guest should be focused. bool ShouldGuestBeFocused() const; @@ -90,7 +92,7 @@ // Returns the last allocated LocalSurfaceId. const viz::LocalSurfaceId& GetLocalSurfaceId() const; - void WasResized(); + void WasResized(const viz::LocalSurfaceId& child_allocated_local_surface_id); // Returns whether a message should be forwarded to BrowserPlugin. static bool ShouldForwardToBrowserPlugin(const IPC::Message& message); @@ -193,7 +195,8 @@ void OnGuestGone(int instance_id); void OnGuestReady(int instance_id, const viz::FrameSinkId& frame_sink_id); void OnResizeDueToAutoResize(int browser_plugin_instance_id, - uint64_t sequence_number); + uint64_t sequence_number, + viz::LocalSurfaceId child_allocated_surface_id); void OnEnableAutoResize(int browser_plugin_instance_id, const gfx::Size& min_size, const gfx::Size& max_size);
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index a5fc045..03e4eaf8 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -29,6 +29,7 @@ #include "media/base/media_switches.h" #include "media/base/renderer_factory_selector.h" #include "media/base/surface_manager.h" +#include "media/blink/remote_playback_client_wrapper_impl.h" #include "media/blink/resource_fetch_context.h" #include "media/blink/webencryptedmediaclient_impl.h" #include "media/blink/webmediaplayer_impl.h" @@ -53,6 +54,7 @@ #include "content/renderer/media/android/stream_texture_wrapper_impl.h" #include "media/base/android/media_codec_util.h" #include "media/base/media.h" +#include "media/renderers/flinging_renderer_client_factory.h" #include "url/gurl.h" #endif @@ -242,9 +244,10 @@ base::WeakPtr<media::MediaObserver> media_observer; - auto factory_selector = - CreateRendererFactorySelector(media_log.get(), use_media_player_renderer, - GetDecoderFactory(), &media_observer); + auto factory_selector = CreateRendererFactorySelector( + media_log.get(), use_media_player_renderer, GetDecoderFactory(), + std::make_unique<media::RemotePlaybackClientWrapperImpl>(client), + &media_observer); #if BUILDFLAG(ENABLE_MEDIA_REMOTING) DCHECK(media_observer); @@ -343,6 +346,7 @@ media::MediaLog* media_log, bool use_media_player, media::DecoderFactory* decoder_factory, + std::unique_ptr<media::RemotePlaybackClientWrapper> client_wrapper, base::WeakPtr<media::MediaObserver>* out_media_observer) { RenderThreadImpl* render_thread = RenderThreadImpl::current(); // Render thread may not exist in tests, returning nullptr if it does not. @@ -354,6 +358,7 @@ #if defined(OS_ANDROID) DCHECK(remote_interfaces_); + // MediaPlayerRendererClientFactory setup. auto mojo_media_player_renderer_factory = std::make_unique<media::MojoRendererFactory>( media::mojom::HostedRendererType::kMediaPlayer, @@ -373,6 +378,38 @@ base::ThreadTaskRunnerHandle::Get()))); factory_selector->SetUseMediaPlayer(use_media_player); + + // FlingingRendererClientFactory (FRCF) setup. + auto mojo_flinging_factory = std::make_unique<media::MojoRendererFactory>( + media::mojom::HostedRendererType::kFlinging, + media::MojoRendererFactory::GetGpuFactoriesCB(), + GetMediaInterfaceFactory()); + + // Save a temp copy of the pointer, before moving it into the FRCF. + // The FRCF cannot be aware of the MojoRendererFactory directly, due to + // layering issues. + media::MojoRendererFactory* temp_mojo_flinging_factory = + mojo_flinging_factory.get(); + + auto flinging_factory = + std::make_unique<media::FlingingRendererClientFactory>( + std::move(mojo_flinging_factory), std::move(client_wrapper)); + + // base::Unretained is safe here because the FRCF owns the MojoRendererFactory + // and is guaranteed to outlive it. + temp_mojo_flinging_factory->SetGetTypeSpecificIdCB(base::BindRepeating( + &media::FlingingRendererClientFactory::GetActivePresentationId, + base::Unretained(flinging_factory.get()))); + + // base::Unretained is safe here because |factory_selector| owns + // |flinging_factory|. + factory_selector->SetQueryIsFlingingActiveCB( + base::Bind(&media::FlingingRendererClientFactory::IsFlingingActive, + base::Unretained(flinging_factory.get()))); + + factory_selector->AddFactory( + media::RendererFactorySelector::FactoryType::FLINGING, + std::move(flinging_factory)); #endif // defined(OS_ANDROID) bool use_mojo_renderer_factory = false;
diff --git a/content/renderer/media/media_factory.h b/content/renderer/media/media_factory.h index 406b172..1d5aeece 100644 --- a/content/renderer/media/media_factory.h +++ b/content/renderer/media/media_factory.h
@@ -43,6 +43,7 @@ class DecoderFactory; class MediaLog; class MediaObserver; +class RemotePlaybackClientWrapper; class RendererWebMediaPlayerDelegate; class SurfaceManager; class WebEncryptedMediaClientImpl; @@ -112,6 +113,7 @@ media::MediaLog* media_log, bool use_media_player, media::DecoderFactory* decoder_factory, + std::unique_ptr<media::RemotePlaybackClientWrapper> client_wrapper, base::WeakPtr<media::MediaObserver>* out_media_observer); blink::WebMediaPlayer* CreateWebMediaPlayerForMediaStream(
diff --git a/content/renderer/media/mojo_audio_output_ipc.cc b/content/renderer/media/mojo_audio_output_ipc.cc index 883c1e4..287c8a8 100644 --- a/content/renderer/media/mojo_audio_output_ipc.cc +++ b/content/renderer/media/mojo_audio_output_ipc.cc
@@ -32,9 +32,9 @@ MojoAudioOutputIPC::~MojoAudioOutputIPC() { DCHECK(!AuthorizationRequested() && !StreamCreationRequested()) << "CloseStream must be called before destructing the AudioOutputIPC"; - // No sequence check. - // Destructing |weak_factory_| on any sequence is safe since it's not used - // after the final call to CloseStream, where its pointers are invalidated. + // No thread check. + // Destructing |weak_factory_| on any thread is safe since it's not used after + // the final call to CloseStream, where its pointers are invalidated. } void MojoAudioOutputIPC::RequestDeviceAuthorization( @@ -81,13 +81,17 @@ // Since the creation callback won't fire if the provider binding is gone // and |this| owns |stream_provider_|, unretained is safe. stream_creation_start_time_ = base::TimeTicks::Now(); - media::mojom::AudioOutputStreamProviderClientPtr client_ptr; + media::mojom::AudioOutputStreamClientPtr client_ptr; binding_.Bind(mojo::MakeRequest(&client_ptr)); - // Unretained is safe because |this| owns |binding_|. - binding_.set_connection_error_with_reason_handler( - base::BindOnce(&MojoAudioOutputIPC::ProviderClientBindingDisconnected, - base::Unretained(this))); - stream_provider_->Acquire(params, std::move(client_ptr)); + stream_provider_->Acquire(mojo::MakeRequest(&stream_), std::move(client_ptr), + params, + base::BindOnce(&MojoAudioOutputIPC::StreamCreated, + base::Unretained(this))); + + // Don't set a connection error handler. Either an error has already been + // signaled through the AudioOutputStreamClient interface, or the connection + // is broken because the frame owning |this| was destroyed, in which + // case |this| will soon be cleaned up anyways. } void MojoAudioOutputIPC::PlayStream() { @@ -119,25 +123,18 @@ stream_->SetVolume(volume); } -void MojoAudioOutputIPC::ProviderClientBindingDisconnected( - uint32_t disconnect_reason, - const std::string& description) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +void MojoAudioOutputIPC::OnError() { + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(delegate_); - if (disconnect_reason == kPlatformErrorDisconnectReason) { - delegate_->OnError(); - } - // Otherwise, disconnection was due to the frame owning |this| being - // destructed or having a navigation. In this case, |this| will soon be - // cleaned up. + delegate_->OnError(); } -bool MojoAudioOutputIPC::AuthorizationRequested() const { +bool MojoAudioOutputIPC::AuthorizationRequested() { return stream_provider_.is_bound(); } -bool MojoAudioOutputIPC::StreamCreationRequested() const { - return binding_.is_bound(); +bool MojoAudioOutputIPC::StreamCreationRequested() { + return stream_.is_bound(); } media::mojom::AudioOutputStreamProviderRequest @@ -206,14 +203,13 @@ delegate_->OnDeviceAuthorized(status, params, device_id); } -void MojoAudioOutputIPC::Created(media::mojom::AudioOutputStreamPtr stream, - media::mojom::AudioDataPipePtr data_pipe) { +void MojoAudioOutputIPC::StreamCreated( + media::mojom::AudioDataPipePtr data_pipe) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(delegate_); UMA_HISTOGRAM_TIMES("Media.Audio.Render.OutputDeviceStreamCreationTime", base::TimeTicks::Now() - stream_creation_start_time_); - stream_ = std::move(stream); base::PlatformFile socket_handle; auto result =
diff --git a/content/renderer/media/mojo_audio_output_ipc.h b/content/renderer/media/mojo_audio_output_ipc.h index b91da3e..e2bd52f 100644 --- a/content/renderer/media/mojo_audio_output_ipc.h +++ b/content/renderer/media/mojo_audio_output_ipc.h
@@ -24,7 +24,7 @@ // thread. class CONTENT_EXPORT MojoAudioOutputIPC : public media::AudioOutputIPC, - public media::mojom::AudioOutputStreamProviderClient { + public media::mojom::AudioOutputStreamClient { public: using FactoryAccessorCB = base::RepeatingCallback<mojom::RendererAudioOutputStreamFactory*()>; @@ -48,20 +48,15 @@ void CloseStream() override; void SetVolume(double volume) override; - // media::mojom::AudioOutputStreamProviderClient implementation. - void Created(media::mojom::AudioOutputStreamPtr stream, - media::mojom::AudioDataPipePtr data_pipe) override; + // media::mojom::AudioOutputStreamClient implementation. + void OnError() override; private: using AuthorizationCB = mojom::RendererAudioOutputStreamFactory:: RequestDeviceAuthorizationCallback; - bool AuthorizationRequested() const; - bool StreamCreationRequested() const; - - void ProviderClientBindingDisconnected(uint32_t disconnect_reason, - const std::string& description); - + bool AuthorizationRequested(); + bool StreamCreationRequested(); media::mojom::AudioOutputStreamProviderRequest MakeProviderRequest(); // Tries to acquire a RendererAudioOutputStreamFactory and requests device @@ -76,11 +71,11 @@ const media::AudioParameters& params, const std::string& device_id) const; - SEQUENCE_CHECKER(sequence_checker_); + void StreamCreated(media::mojom::AudioDataPipePtr data_pipe); const FactoryAccessorCB factory_accessor_; - mojo::Binding<media::mojom::AudioOutputStreamProviderClient> binding_; + mojo::Binding<media::mojom::AudioOutputStreamClient> binding_; media::mojom::AudioOutputStreamProviderPtr stream_provider_; media::mojom::AudioOutputStreamPtr stream_; media::AudioOutputIPCDelegate* delegate_ = nullptr;
diff --git a/content/renderer/media/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/mojo_audio_output_ipc_unittest.cc index 8d8a03e..ca3697a 100644 --- a/content/renderer/media/mojo_audio_output_ipc_unittest.cc +++ b/content/renderer/media/mojo_audio_output_ipc_unittest.cc
@@ -57,33 +57,30 @@ EXPECT_TRUE(binding_); } - void Acquire(const media::AudioParameters& params, - media::mojom::AudioOutputStreamProviderClientPtr provider_client) - override { + void Acquire(media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamClientPtr client_ptr, + const media::AudioParameters& params, + AcquireCallback callback) override { EXPECT_EQ(binding_, base::nullopt); EXPECT_NE(stream_, nullptr); - std::swap(provider_client, provider_client_); - media::mojom::AudioOutputStreamPtr stream_ptr; - binding_.emplace(stream_, mojo::MakeRequest(&stream_ptr)); + std::swap(client_, client_ptr); + binding_.emplace(stream_, std::move(stream_request)); base::CancelableSyncSocket foreign_socket; EXPECT_TRUE( base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket)); - provider_client_->Created( - std::move(stream_ptr), - {base::in_place, mojo::SharedBufferHandle::Create(kMemoryLength), - mojo::WrapPlatformFile(foreign_socket.Release())}); + std::move(callback).Run({base::in_place, + mojo::SharedBufferHandle::Create(kMemoryLength), + mojo::WrapPlatformFile(foreign_socket.Release())}); } - void SignalErrorToProviderClient() { - provider_client_.ResetWithReason( - media::mojom::AudioOutputStreamProviderClient:: - kPlatformErrorDisconnectReason, - std::string()); + media::mojom::AudioOutputStreamClient* client() { + DCHECK(client_.get()); + return client_.get(); } private: media::mojom::AudioOutputStream* stream_; - media::mojom::AudioOutputStreamProviderClientPtr provider_client_; + media::mojom::AudioOutputStreamClientPtr client_; base::Optional<mojo::Binding<media::mojom::AudioOutputStream>> binding_; base::CancelableSyncSocket socket_; }; @@ -137,10 +134,6 @@ expected_device_id_ = device_id; } - void SignalErrorToProviderClient() { - provider_->SignalErrorToProviderClient(); - } - void Disconnect() { binding_.Close(); this_proxy_.reset(); @@ -150,6 +143,10 @@ expect_request_ = false; } + media::mojom::AudioOutputStreamClient* client() { + return provider_->client(); + } + MojoAudioOutputIPC::FactoryAccessorCB GetAccessor() { return base::BindRepeating(&TestRemoteFactory::get, base::Unretained(this)); } @@ -389,7 +386,7 @@ Mock::VerifyAndClearExpectations(&delegate); EXPECT_CALL(delegate, OnError()); - stream_factory.SignalErrorToProviderClient(); + stream_factory.client()->OnError(); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(&delegate); @@ -533,12 +530,6 @@ StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; - EXPECT_CALL(delegate, OnDeviceAuthorized( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, - _, std::string(kReturnedDeviceId))); - EXPECT_CALL(delegate, GotOnStreamCreated()); - EXPECT_CALL(stream, Play()); - const std::unique_ptr<media::AudioOutputIPC> ipc = std::make_unique<MojoAudioOutputIPC>( stream_factory.GetAccessor(), @@ -548,9 +539,15 @@ ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId); ipc->CreateStream(&delegate, Params()); - base::RunLoop().RunUntilIdle(); ipc->PlayStream(); + + EXPECT_CALL(delegate, OnDeviceAuthorized( + media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, + _, std::string(kReturnedDeviceId))); + EXPECT_CALL(delegate, GotOnStreamCreated()); + EXPECT_CALL(stream, Play()); base::RunLoop().RunUntilIdle(); + ipc->CloseStream(); base::RunLoop().RunUntilIdle(); } @@ -561,12 +558,6 @@ StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; - EXPECT_CALL(delegate, OnDeviceAuthorized( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, - _, std::string(kReturnedDeviceId))); - EXPECT_CALL(delegate, GotOnStreamCreated()); - EXPECT_CALL(stream, Pause()); - const std::unique_ptr<media::AudioOutputIPC> ipc = std::make_unique<MojoAudioOutputIPC>( stream_factory.GetAccessor(), @@ -576,9 +567,15 @@ ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId); ipc->CreateStream(&delegate, Params()); - base::RunLoop().RunUntilIdle(); ipc->PauseStream(); + + EXPECT_CALL(delegate, OnDeviceAuthorized( + media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, + _, std::string(kReturnedDeviceId))); + EXPECT_CALL(delegate, GotOnStreamCreated()); + EXPECT_CALL(stream, Pause()); base::RunLoop().RunUntilIdle(); + ipc->CloseStream(); base::RunLoop().RunUntilIdle(); } @@ -589,12 +586,6 @@ StrictMock<MockStream> stream; StrictMock<MockDelegate> delegate; - EXPECT_CALL(delegate, OnDeviceAuthorized( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, - _, std::string(kReturnedDeviceId))); - EXPECT_CALL(delegate, GotOnStreamCreated()); - EXPECT_CALL(stream, SetVolume(kNewVolume)); - const std::unique_ptr<media::AudioOutputIPC> ipc = std::make_unique<MojoAudioOutputIPC>( stream_factory.GetAccessor(), @@ -604,9 +595,15 @@ ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId); ipc->CreateStream(&delegate, Params()); - base::RunLoop().RunUntilIdle(); ipc->SetVolume(kNewVolume); + + EXPECT_CALL(delegate, OnDeviceAuthorized( + media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, + _, std::string(kReturnedDeviceId))); + EXPECT_CALL(delegate, GotOnStreamCreated()); + EXPECT_CALL(stream, SetVolume(kNewVolume)); base::RunLoop().RunUntilIdle(); + ipc->CloseStream(); base::RunLoop().RunUntilIdle(); }
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index 3c02df5f..493c7c4 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -1125,31 +1125,4 @@ {{GURL(kTestFirstURL), kFrameEventDidCommitSameDocumentLoad}}); } -// Verify that a RenderFrameProxy correctly handles autoresize. -TEST_F(RenderFrameImplTest, ProxyAutoresize) { - auto* proxy = RenderFrameProxy::FromRoutingID(kFrameProxyRouteId); - - // Send a ViewChanged message to initialize our proxy with a frame sink. - FrameMsg_ViewChanged_Params view_changed_params; - view_changed_params.frame_sink_id = viz::FrameSinkId(20, 21); - FrameMsg_ViewChanged view_changed(kFrameProxyRouteId, view_changed_params); - proxy->OnMessageReceived(view_changed); - render_thread_->sink().ClearMessages(); - - // Send a simulated sequence of messages representing an auto-resize - // transaction. - FrameMsg_BeginResizeDueToAutoResize begin_msg(kFrameProxyRouteId); - proxy->OnMessageReceived(begin_msg); - proxy->FrameRectsChanged(blink::WebRect(0, 0, 300, 300), - blink::WebRect(0, 0, 300, 300)); - FrameMsg_EndResizeDueToAutoResize end_msg(kFrameProxyRouteId, 7); - proxy->OnMessageReceived(end_msg); - - // We should have exactly one UpdateResizeParams message. - const IPC::Message* msg1 = render_thread_->sink().GetUniqueMessageMatching( - FrameHostMsg_UpdateResizeParams::ID); - EXPECT_TRUE(msg1); - render_thread_->sink().ClearMessages(); -} - } // namespace content
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 5d56039..6fbdc4fd 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -258,7 +258,7 @@ void RenderFrameProxy::ResendResizeParams() { // Reset |sent_resize_params_| in order to allocate a new viz::LocalSurfaceId. sent_resize_params_ = base::nullopt; - WasResized(); + WasResized(viz::LocalSurfaceId()); } void RenderFrameProxy::WillBeginCompositorFrame() { @@ -280,7 +280,13 @@ screen_info.device_scale_factor); return; } - WasResized(); + WasResized(viz::LocalSurfaceId()); +} + +void RenderFrameProxy::UpdateCaptureSequenceNumber( + uint32_t capture_sequence_number) { + pending_resize_params_.capture_sequence_number = capture_sequence_number; + WasResized(viz::LocalSurfaceId()); } void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) { @@ -417,10 +423,7 @@ OnSetFrameOwnerProperties) IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateOrigin, OnDidUpdateOrigin) IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetPageFocus) - IPC_MESSAGE_HANDLER(FrameMsg_BeginResizeDueToAutoResize, - OnBeginResizeDueToAutoResize) - IPC_MESSAGE_HANDLER(FrameMsg_EndResizeDueToAutoResize, - OnEndResizeDueToAutoResize) + IPC_MESSAGE_HANDLER(FrameMsg_ResizeDueToAutoResize, OnResizeDueToAutoResize) IPC_MESSAGE_HANDLER(FrameMsg_EnableAutoResize, OnEnableAutoResize) IPC_MESSAGE_HANDLER(FrameMsg_DisableAutoResize, OnDisableAutoResize) IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame) @@ -567,16 +570,11 @@ web_frame_->ScrollRectToVisible(rect_to_scroll, params); } -void RenderFrameProxy::OnBeginResizeDueToAutoResize() { - DCHECK(!transaction_pending_); - transaction_pending_ = true; -} - -void RenderFrameProxy::OnEndResizeDueToAutoResize(uint64_t sequence_number) { - DCHECK(transaction_pending_); - transaction_pending_ = false; +void RenderFrameProxy::OnResizeDueToAutoResize( + uint64_t sequence_number, + viz::LocalSurfaceId child_allocated_surface_id) { pending_resize_params_.auto_resize_sequence_number = sequence_number; - WasResized(); + WasResized(child_allocated_surface_id); } void RenderFrameProxy::OnEnableAutoResize(const gfx::Size& min_size, @@ -584,12 +582,12 @@ pending_resize_params_.auto_resize_enabled = true; pending_resize_params_.min_size_for_auto_resize = min_size; pending_resize_params_.max_size_for_auto_resize = max_size; - WasResized(); + WasResized(viz::LocalSurfaceId()); } void RenderFrameProxy::OnDisableAutoResize() { pending_resize_params_.auto_resize_enabled = false; - WasResized(); + WasResized(viz::LocalSurfaceId()); } #if defined(USE_AURA) @@ -599,10 +597,41 @@ } #endif -void RenderFrameProxy::WasResized() { - if (!frame_sink_id_.is_valid() || crashed_ || transaction_pending_) +void RenderFrameProxy::WasResized( + const viz::LocalSurfaceId& child_allocated_surface_id) { + if (!frame_sink_id_.is_valid() || crashed_) return; + // Note that the following flag is true if the capture sequence number + // actually changed. That is, it is false if we did not have + // |sent_resize_params_|, which is different from + // |synchronized_params_changed| below. + bool capture_sequence_number_changed = + sent_resize_params_ && sent_resize_params_->capture_sequence_number != + pending_resize_params_.capture_sequence_number; + + // TODO(ericrk): Once we short-circuit responses to child allocated surface + // IDs, we can remove |surface_id_changed| here and simply update. + // https://crbug.com/811944 + bool surface_id_changed = false; + if (child_allocated_surface_id.is_valid()) { + viz::LocalSurfaceId previous_id = local_surface_id_; + local_surface_id_ = parent_local_surface_id_allocator_.UpdateFromChild( + child_allocated_surface_id); + surface_id_changed = previous_id != local_surface_id_; + } + + // We no longer use auto resize sequence numbers to trigger ID generation, + // instead getting auto resize IDs from the child. If our auto-resize + // sequence number changed our surface ID must change as well. + // TODO(ericrk): Once we short-circuit, we can remove references to sequence + // numbers and clean this up. https://crbug.com/811944. + if (sent_resize_params_ && + sent_resize_params_->auto_resize_sequence_number != + pending_resize_params_.auto_resize_sequence_number) { + DCHECK(surface_id_changed); + } + bool synchronized_params_changed = !sent_resize_params_ || sent_resize_params_->auto_resize_enabled != @@ -616,25 +645,28 @@ sent_resize_params_->screen_space_rect.size() != pending_resize_params_.screen_space_rect.size() || sent_resize_params_->screen_info != pending_resize_params_.screen_info || - sent_resize_params_->auto_resize_sequence_number != - pending_resize_params_.auto_resize_sequence_number; + capture_sequence_number_changed; if (synchronized_params_changed) local_surface_id_ = parent_local_surface_id_allocator_.GenerateId(); viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_); if (enable_surface_synchronization_) { - // TODO(vmpstr): When capture_sequence_number is available, the deadline - // should be infinite if the sequence number has changed. - compositing_helper_->SetPrimarySurfaceId( - surface_id, local_frame_size(), - cc::DeadlinePolicy::UseDefaultDeadline()); + // If we're synchronizing surfaces, then use an infinite deadline to ensure + // everything is synchronized. + cc::DeadlinePolicy deadline = + capture_sequence_number_changed + ? cc::DeadlinePolicy::UseInfiniteDeadline() + : cc::DeadlinePolicy::UseDefaultDeadline(); + compositing_helper_->SetPrimarySurfaceId(surface_id, local_frame_size(), + deadline); } bool rect_changed = !sent_resize_params_ || sent_resize_params_->screen_space_rect != pending_resize_params_.screen_space_rect; - bool resize_params_changed = synchronized_params_changed || rect_changed; + bool resize_params_changed = + synchronized_params_changed || rect_changed || surface_id_changed; #if defined(USE_AURA) if (rect_changed && mus_embedded_frame_) { @@ -773,7 +805,7 @@ screen_info().device_scale_factor); return; } - WasResized(); + WasResized(viz::LocalSurfaceId()); } void RenderFrameProxy::UpdateRemoteViewportIntersection(
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 99795ac..47a4faf1 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -134,6 +134,10 @@ // ScreenInfo has changed. void OnScreenInfoChanged(const ScreenInfo& screen_info); + // Invoked by RenderWidget when a new capture sequence number was set, + // indicating that surfaces should be synchronized. + void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number); + // Pass replicated information, such as security origin, to this // RenderFrameProxy's WebRemoteFrame. void SetReplicatedState(const FrameReplicationState& state); @@ -157,7 +161,7 @@ std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame); #endif - void WasResized(); + void WasResized(const viz::LocalSurfaceId& child_allocated_surface_id); const gfx::Rect& screen_space_rect() const { return pending_resize_params_.screen_space_rect; @@ -250,8 +254,8 @@ void OnSetHasReceivedUserGesture(); void OnScrollRectToVisible(const gfx::Rect& rect_to_scroll, const blink::WebScrollIntoViewParams& params); - void OnBeginResizeDueToAutoResize(); - void OnEndResizeDueToAutoResize(uint64_t sequence_number); + void OnResizeDueToAutoResize(uint64_t sequence_number, + viz::LocalSurfaceId child_allocated_surface_id); void OnEnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size); void OnDisableAutoResize(); void OnSetHasReceivedUserGestureBeforeNavigation(bool value); @@ -301,11 +305,6 @@ // |sent_resize_params_|. FrameResizeParams pending_resize_params_; - // Whether we are in the middle of a transaction which modifies - // |pending_resize_params_|. If so, we delay allocating a new LocalSurfaceId - // until the transaction completes. - bool transaction_pending_ = false; - bool crashed_ = false; viz::FrameSinkId frame_sink_id_;
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 724673f..647b3375 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -447,6 +447,7 @@ params.visible_viewport_size = params.new_size; params.auto_resize_enabled = view()->auto_resize_mode(); params.auto_resize_sequence_number = view()->auto_resize_sequence_number(); + params.capture_sequence_number = view()->capture_sequence_number(); params.min_size_for_auto_resize = view()->min_size_for_auto_resize(); params.max_size_for_auto_resize = view()->max_size_for_auto_resize(); params.needs_resize_ack = false;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 6b72983..23d78a6 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1296,6 +1296,7 @@ UpdateSurfaceAndScreenInfo(new_local_surface_id, new_compositor_viewport_pixel_size, params.screen_info); + UpdateCaptureSequenceNumber(params.capture_sequence_number); if (compositor_) { // If surface synchronization is enabled, then this will use the provided // |local_surface_id_| to submit the next generated CompositorFrame. @@ -1854,6 +1855,19 @@ UpdateWebViewWithDeviceScaleFactor(); } +void RenderWidget::UpdateCaptureSequenceNumber( + uint32_t capture_sequence_number) { + if (capture_sequence_number == last_capture_sequence_number_) + return; + last_capture_sequence_number_ = capture_sequence_number; + + // Notify observers of the new capture sequence number. + for (auto& observer : render_frame_proxies_) + observer.UpdateCaptureSequenceNumber(capture_sequence_number); + for (auto& observer : browser_plugins_) + observer.UpdateCaptureSequenceNumber(capture_sequence_number); +} + void RenderWidget::OnRepaint(gfx::Size size_to_paint) { // During shutdown we can just ignore this message. if (!GetWebWidget()) @@ -2269,7 +2283,7 @@ gfx::Size new_compositor_viewport_pixel_size = gfx::ScaleToCeiledSize(size_, GetWebScreenInfo().device_scale_factor); viz::LocalSurfaceId local_surface_id; - if (!compositor_viewport_pixel_size_.IsEmpty()) + if (!new_compositor_viewport_pixel_size.IsEmpty()) local_surface_id = child_local_surface_id_allocator_.GenerateId(); UpdateSurfaceAndScreenInfo( local_surface_id, new_compositor_viewport_pixel_size, screen_info_);
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index ab70a7b7..25beb801 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -429,6 +429,11 @@ const gfx::Size& max_size_for_auto_resize() const { return max_size_for_auto_resize_; } + + uint32_t capture_sequence_number() const { + return last_capture_sequence_number_; + } + // MainThreadEventQueueClient overrides. // Requests a BeginMainFrame callback from the compositor. @@ -900,6 +905,8 @@ const gfx::Size& new_compositor_viewport_pixel_size, const ScreenInfo& new_screen_info); + void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number); + // A variant of Send but is fatal if it fails. The browser may // be waiting for this IPC Message and if the send fails the browser will // be left in a state waiting for something that never comes. And if it @@ -992,11 +999,12 @@ gfx::Rect viewport_intersection_; gfx::Rect compositor_visible_rect_; - // Cache whether or not we have touch handlers, to reduce IPCs sent. // Different consumers in the browser process makes different assumptions, so // must always send the first IPC regardless of value. base::Optional<bool> has_touch_handlers_; + uint32_t last_capture_sequence_number_ = 0u; + base::WeakPtrFactory<RenderWidget> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RenderWidget);
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index 04eb7e6..b86b30b 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -517,6 +517,18 @@ EXPECT_TRUE(local_surface_id2.has_value()); } + // Our first child allocated LSI should match |fake_parent_local_surface_id| + // with an incremented child sequence number. + EXPECT_NE(fake_parent_local_surface_id, local_surface_id1); + EXPECT_EQ(fake_parent_local_surface_id.parent_sequence_number(), + local_surface_id1->parent_sequence_number()); + EXPECT_EQ(fake_parent_local_surface_id.child_sequence_number() + 1, + local_surface_id1->child_sequence_number()); + EXPECT_EQ(fake_parent_local_surface_id.embed_token(), + local_surface_id2->embed_token()); + + // Our second child allocated LSI should match the first with an incremented + // child sequence number. EXPECT_NE(local_surface_id1, local_surface_id2); EXPECT_EQ(local_surface_id1->parent_sequence_number(), local_surface_id2->parent_sequence_number());
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc index e6aefb32..aec857e 100644 --- a/content/test/content_browser_test_utils_internal.cc +++ b/content/test/content_browser_test_utils_internal.cc
@@ -365,114 +365,6 @@ } } -UpdateResizeParamsMessageFilter::UpdateResizeParamsMessageFilter() - : content::BrowserMessageFilter(FrameMsgStart), - screen_space_rect_run_loop_(std::make_unique<base::RunLoop>()), - screen_space_rect_received_(false) {} - -void UpdateResizeParamsMessageFilter::WaitForRect() { - screen_space_rect_run_loop_->Run(); -} - -void UpdateResizeParamsMessageFilter::ResetRectRunLoop() { - last_rect_ = gfx::Rect(); - screen_space_rect_run_loop_.reset(new base::RunLoop); - screen_space_rect_received_ = false; -} - -viz::FrameSinkId UpdateResizeParamsMessageFilter::GetOrWaitForId() { - // No-op if already quit. - frame_sink_id_run_loop_.Run(); - return frame_sink_id_; -} - -uint64_t UpdateResizeParamsMessageFilter::WaitForSequenceNumber() { - sequence_number_run_loop_.reset(new base::RunLoop); - sequence_number_run_loop_->Run(); - return last_sequence_number_; -} - -UpdateResizeParamsMessageFilter::~UpdateResizeParamsMessageFilter() {} - -void UpdateResizeParamsMessageFilter::OnUpdateResizeParams( - const viz::SurfaceId& surface_id, - const FrameResizeParams& resize_params) { - gfx::Rect screen_space_rect_in_dip = resize_params.screen_space_rect; - if (IsUseZoomForDSFEnabled()) { - screen_space_rect_in_dip = - gfx::Rect(gfx::ScaleToFlooredPoint( - resize_params.screen_space_rect.origin(), - 1.f / resize_params.screen_info.device_scale_factor), - gfx::ScaleToCeiledSize( - resize_params.screen_space_rect.size(), - 1.f / resize_params.screen_info.device_scale_factor)); - } - // Track each rect updates. - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&UpdateResizeParamsMessageFilter::OnUpdatedFrameRectOnUI, - this, screen_space_rect_in_dip)); - - // Track each sequence number update. - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce( - &UpdateResizeParamsMessageFilter::OnUpdatedSequenceNumberOnUI, this, - resize_params.auto_resize_sequence_number)); - - // Record the received value. We cannot check the current state of the child - // frame, as it can only be processed on the UI thread, and we cannot block - // here. - frame_sink_id_ = surface_id.frame_sink_id(); - - // There can be several updates before a valid viz::FrameSinkId is ready. Do - // not quit |run_loop_| until after we receive a valid one. - if (!frame_sink_id_.is_valid()) - return; - - // We can't nest on the IO thread. So tests will wait on the UI thread, so - // post there to exit the nesting. - content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) - ->PostTask(FROM_HERE, - base::BindOnce( - &UpdateResizeParamsMessageFilter::OnUpdatedFrameSinkIdOnUI, - this)); -} - -void UpdateResizeParamsMessageFilter::OnUpdatedFrameRectOnUI( - const gfx::Rect& rect) { - last_rect_ = rect; - if (!screen_space_rect_received_) { - screen_space_rect_received_ = true; - // Tests looking at the rect currently expect all received input to finish - // processing before the test continutes. - screen_space_rect_run_loop_->QuitWhenIdle(); - } -} - -void UpdateResizeParamsMessageFilter::OnUpdatedFrameSinkIdOnUI() { - frame_sink_id_run_loop_.Quit(); -} - -void UpdateResizeParamsMessageFilter::OnUpdatedSequenceNumberOnUI( - uint64_t sequence_number) { - last_sequence_number_ = sequence_number; - if (sequence_number_run_loop_) { - sequence_number_run_loop_->QuitWhenIdle(); - } -} - -bool UpdateResizeParamsMessageFilter::OnMessageReceived( - const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(UpdateResizeParamsMessageFilter, message) - IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateResizeParams, OnUpdateResizeParams) - IPC_END_MESSAGE_MAP() - - // We do not consume the message, so that we can verify the effects of it - // being processed. - return false; -} - RenderProcessHostKillWaiter::RenderProcessHostKillWaiter( RenderProcessHost* render_process_host) : exit_watcher_(render_process_host,
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h index 70f1dc3..b1505ecd 100644 --- a/content/test/content_browser_test_utils_internal.h +++ b/content/test/content_browser_test_utils_internal.h
@@ -35,7 +35,6 @@ class Shell; class SiteInstance; class ToRenderFrameHost; -struct FrameResizeParams; // Navigates the frame represented by |node| to |url|, blocking until the // navigation finishes. @@ -191,52 +190,6 @@ DISALLOW_COPY_AND_ASSIGN(UrlCommitObserver); }; -// Class to sniff incoming IPCs for FrameHostMsg_UpdateResizeParams messages. -// This allows the message to continue to the target child so that processing -// can be verified by tests. -class UpdateResizeParamsMessageFilter : public content::BrowserMessageFilter { - public: - UpdateResizeParamsMessageFilter(); - - gfx::Rect last_rect() const { return last_rect_; } - - void WaitForRect(); - void ResetRectRunLoop(); - - // Returns the new viz::FrameSinkId immediately if the IPC has been received. - // Otherwise this will block the UI thread until it has been received, then it - // will return the new viz::FrameSinkId. - viz::FrameSinkId GetOrWaitForId(); - - // Waits for the next sequence number to be received and returns it. - uint64_t WaitForSequenceNumber(); - - protected: - ~UpdateResizeParamsMessageFilter() override; - - private: - void OnUpdateResizeParams(const viz::SurfaceId& surface_id, - const FrameResizeParams& resize_params); - // |rect| is in DIPs. - void OnUpdatedFrameRectOnUI(const gfx::Rect& rect); - void OnUpdatedFrameSinkIdOnUI(); - void OnUpdatedSequenceNumberOnUI(uint64_t sequence_number); - - bool OnMessageReceived(const IPC::Message& message) override; - - viz::FrameSinkId frame_sink_id_; - base::RunLoop frame_sink_id_run_loop_; - - std::unique_ptr<base::RunLoop> screen_space_rect_run_loop_; - bool screen_space_rect_received_; - gfx::Rect last_rect_; - - uint64_t last_sequence_number_ = 0; - std::unique_ptr<base::RunLoop> sequence_number_run_loop_; - - DISALLOW_COPY_AND_ASSIGN(UpdateResizeParamsMessageFilter); -}; - // Waits for a kill of the given RenderProcessHost and returns the // BadMessageReason that caused a //content-triggerred kill. //
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index b0a00a0..e114e3a 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -1257,47 +1257,45 @@ ], }, - # Temporarily disabled while we roll Vulkan. - # TODO(jmadill): Re-enable after roll. http://anglebug.com/2393 - # 'angle_deqp_gles2_vulkan_tests': { - # 'tester_configs': [ - # { - # 'predicate': Predicates.DEQP, - # 'swarming_dimension_sets': [ - # # NVIDIA Win 10 - # { - # 'gpu': NVIDIA_QUADRO_P400_ALL_DRIVERS, - # 'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS, - # }, - # # AMD Win 7 - # { - # 'gpu': '1002:6613', - # 'os': 'Windows-2008ServerR2-SP1' - # }, - # # NVIDIA Linux Quadro P400 - # { - # 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, - # 'os': 'Ubuntu' - # }, - # ], - # }, - # ], - # 'disabled_tester_configs': [ - # { - # 'names': [ - # 'Linux FYI Ozone (Intel)', - # ], - # }, - # ], - # 'desktop_swarming': { - # 'shards': 4, - # }, - # 'test': 'angle_deqp_gles2_tests', - # 'args': [ - # '--test-launcher-batch-limit=400', - # '--deqp-egl-display-type=angle-vulkan' - # ] - # }, + 'angle_deqp_gles2_vulkan_tests': { + 'tester_configs': [ + { + 'predicate': Predicates.DEQP, + 'swarming_dimension_sets': [ + # NVIDIA Win 10 + { + 'gpu': NVIDIA_QUADRO_P400_ALL_DRIVERS, + 'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS, + }, + # AMD Win 7 + { + 'gpu': '1002:6613', + 'os': 'Windows-2008ServerR2-SP1' + }, + # NVIDIA Linux Quadro P400 + { + 'gpu': LINUX_QUADRO_P400_STABLE_DRIVER, + 'os': 'Ubuntu' + }, + ], + }, + ], + 'disabled_tester_configs': [ + { + 'names': [ + 'Linux FYI Ozone (Intel)', + ], + }, + ], + 'desktop_swarming': { + 'shards': 4, + }, + 'test': 'angle_deqp_gles2_tests', + 'args': [ + '--test-launcher-batch-limit=400', + '--deqp-egl-display-type=angle-vulkan' + ] + }, 'angle_deqp_gles3_gles_tests': { 'tester_configs': [
diff --git a/content/test/gpu/gpu_tests/context_lost_expectations.py b/content/test/gpu/gpu_tests/context_lost_expectations.py index 25b7599a..1b201a5a 100644 --- a/content/test/gpu/gpu_tests/context_lost_expectations.py +++ b/content/test/gpu/gpu_tests/context_lost_expectations.py
@@ -53,10 +53,3 @@ ['android', ('qualcomm', 'Adreno (TM) 420')], bug=611906) self.Fail('ContextLost_WebGLContextLostFromQuantity', ['android', ('qualcomm', 'Adreno (TM) 420')], bug=611906) - - # Nexus 9 and Nvidia Shield TV - self.Fail('ContextLost_WebGLBlockedAfterJSNavigation', - ['android', 'nvidia'], bug=832886) - self.Fail('ContextLost_WebGLUnblockedAfterUserInitiatedReload', - ['android', 'nvidia'], bug=832886) -
diff --git a/content/test/gpu/gpu_tests/context_lost_integration_test.py b/content/test/gpu/gpu_tests/context_lost_integration_test.py index ff083ce..2804c58 100644 --- a/content/test/gpu/gpu_tests/context_lost_integration_test.py +++ b/content/test/gpu/gpu_tests/context_lost_integration_test.py
@@ -298,7 +298,11 @@ self.fail( 'Page should have been blocked from getting a new WebGL context') finally: - gpucrash_tab.Close() + # This try/except is still needed. crbug.com/832886 + try: + gpucrash_tab.Close() + except Exception: + print 'Tab crashed while closing chrome://gpucrash' def _ContextLost_WebGLUnblockedAfterUserInitiatedReload(self, test_path): self.RestartBrowserIfNecessaryWithArgs(self._AddDefaultArgs([])) @@ -334,7 +338,11 @@ self.fail( 'WebGL should have been unblocked after a user-initiated navigation') finally: - gpucrash_tab.Close() + # This try/except is still needed. crbug.com/832886 + try: + gpucrash_tab.Close() + except Exception: + print 'Tab crashed while closing chrome://gpucrash' def load_tests(loader, tests, pattern): del loader, tests, pattern # Unused.
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py index 3360d4fd..d1550ca 100644 --- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -79,6 +79,7 @@ ('GpuProcess_gpu_info_complete', 'gpu/functional_3d_css.html'), ('GpuProcess_driver_bug_workarounds_in_gpu_process', 'chrome:gpu'), ('GpuProcess_readback_webgl_gpu_process', 'chrome:gpu'), + ('GpuProcess_feature_status_under_swiftshader', 'chrome:gpu'), ('GpuProcess_only_one_workaround', 'chrome:gpu'), ('GpuProcess_disable_gpu', 'gpu/functional_webgl.html'), ('GpuProcess_disable_gpu_and_swiftshader', @@ -186,7 +187,7 @@ 'workarounds are not equal: %s != %s, diff: %s' % (browser_list, gpu_list, list(diff))) - basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info') + basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basicInfo') disabled_gl_extensions = None for info in basic_infos: if info['description'].startswith('Disabled Extensions'): @@ -262,6 +263,40 @@ if not result: self.fail('WebGL readback setup failed: %s' % feature_status_list) + def _GpuProcess_feature_status_under_swiftshader(self, test_path): + if not self._SupportsSwiftShader(): + return + # Hit test group 2 with entry 153 from kSoftwareRenderingListEntries. + self.RestartBrowserIfNecessaryWithArgs([ + '--gpu-blacklist-test-group=2']) + self._Navigate(test_path) + feature_status_list = self.tab.EvaluateJavaScript( + 'browserBridge.gpuInfo.featureStatus.featureStatus') + for name, status in feature_status_list.items(): + if name == 'webgl': + if status != 'unavailable_software': + self.fail('WebGL status for SwiftShader failed: %s' % status) + return + elif name == '2d_canvas': + if status != 'unavailable_software': + self.fail('2D Canvas status for SwiftShader failed: %s' % status) + return + else: + pass + feature_status_for_hardware_gpu_list = self.tab.EvaluateJavaScript( + 'browserBridge.gpuInfo.featureStatusForHardwareGpu.featureStatus') + for name, status in feature_status_for_hardware_gpu_list.items(): + if name == 'webgl': + if status != 'unavailable_off': + self.fail('WebGL status for hardware GPU failed: %s' % status) + return + elif name == '2d_canvas': + if status != 'enabled': + self.fail('2D Canvas status for hardware GPU failed: %s' % status) + return + else: + pass + def _GpuProcess_only_one_workaround(self, test_path): # Start this test by launching the browser with no command line # arguments.
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 5d9711c9..14f6872d 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -93,15 +93,9 @@ self.Fail('Pixel_WebGL_PremultipliedAlpha_False', ['android', 'nvidia'], bug=791733) - self.Flaky('Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear', - ['mac', 'intel'], bug=832900) - # TODO(zmo): temporarily suppress these two tests until new # reference images with new names are generated. self.Fail('Pixel_Canvas2DRedBox_NoGpuProcess', ['linux', 'mac', 'win'], bug=744658) self.Fail('Pixel_CSS3DBlueBox_NoGpuProcess', ['linux', 'mac', 'win'], bug=744658) - - # TODO(kbr): temporary suppression for new test. - self.Fail('Pixel_WebGLSadCanvas', bug=575305)
diff --git a/content/test/gpu/gpu_tests/pixel_integration_test.py b/content/test/gpu/gpu_tests/pixel_integration_test.py index 11f06e5..cffd126 100644 --- a/content/test/gpu/gpu_tests/pixel_integration_test.py +++ b/content/test/gpu/gpu_tests/pixel_integration_test.py
@@ -130,67 +130,75 @@ tab.Navigate(url, script_to_evaluate_on_commit=test_harness_script) tab.action_runner.WaitForJavaScriptCondition( 'domAutomationController._proceed', timeout=300) - if tab.EvaluateJavaScript('domAutomationController._readyForActions'): + do_page_action = tab.EvaluateJavaScript( + 'domAutomationController._readyForActions') + if do_page_action: self._DoPageAction(tab, page) - if not tab.EvaluateJavaScript('domAutomationController._succeeded'): - self.fail('page indicated test failure') - if not tab.screenshot_supported: - self.fail('Browser does not support screenshot capture') - screenshot = tab.Screenshot(5) - if screenshot is None: - self.fail('Could not capture screenshot') - dpr = tab.EvaluateJavaScript('window.devicePixelRatio') - if page.test_rect: - screenshot = image_util.Crop( - screenshot, int(page.test_rect[0] * dpr), - int(page.test_rect[1] * dpr), int(page.test_rect[2] * dpr), - int(page.test_rect[3] * dpr)) - if page.expected_colors: - # Use expected colors instead of ref images for validation. - self._ValidateScreenshotSamples( - tab, page.name, screenshot, page.expected_colors, dpr) - return - image_name = self._UrlToImageName(page.name) - if self.GetParsedCommandLineOptions().upload_refimg_to_cloud_storage: - if self._ConditionallyUploadToCloudStorage(image_name, page, tab, - screenshot): - # This is the new reference image; there's nothing to compare against. - ref_png = screenshot + try: + if not tab.EvaluateJavaScript('domAutomationController._succeeded'): + self.fail('page indicated test failure') + if not tab.screenshot_supported: + self.fail('Browser does not support screenshot capture') + screenshot = tab.Screenshot(5) + if screenshot is None: + self.fail('Could not capture screenshot') + dpr = tab.EvaluateJavaScript('window.devicePixelRatio') + if page.test_rect: + screenshot = image_util.Crop( + screenshot, int(page.test_rect[0] * dpr), + int(page.test_rect[1] * dpr), int(page.test_rect[2] * dpr), + int(page.test_rect[3] * dpr)) + if page.expected_colors: + # Use expected colors instead of ref images for validation. + self._ValidateScreenshotSamples( + tab, page.name, screenshot, page.expected_colors, dpr) + return + image_name = self._UrlToImageName(page.name) + if self.GetParsedCommandLineOptions().upload_refimg_to_cloud_storage: + if self._ConditionallyUploadToCloudStorage(image_name, page, tab, + screenshot): + # This is the new reference image; there's nothing to compare against. + ref_png = screenshot + else: + # There was a preexisting reference image, so we might as well + # compare against it. + ref_png = self._DownloadFromCloudStorage(image_name, page, tab) + elif self.GetParsedCommandLineOptions().\ + download_refimg_from_cloud_storage: + # This bot doesn't have the ability to properly generate a + # reference image, so download it from cloud storage. + try: + ref_png = self._DownloadFromCloudStorage(image_name, page, tab) + except cloud_storage.NotFoundError: + # There is no reference image yet in cloud storage. This + # happens when the revision of the test is incremented or when + # a new test is added, because the trybots are not allowed to + # produce reference images, only the bots on the main + # waterfalls. Report this as a failure so the developer has to + # take action by explicitly suppressing the failure and + # removing the suppression once the reference images have been + # generated. Otherwise silent failures could happen for long + # periods of time. + self.fail('Could not find image %s in cloud storage' % image_name) else: - # There was a preexisting reference image, so we might as well - # compare against it. - ref_png = self._DownloadFromCloudStorage(image_name, page, tab) - elif self.GetParsedCommandLineOptions().download_refimg_from_cloud_storage: - # This bot doesn't have the ability to properly generate a - # reference image, so download it from cloud storage. - try: - ref_png = self._DownloadFromCloudStorage(image_name, page, tab) - except cloud_storage.NotFoundError: - # There is no reference image yet in cloud storage. This - # happens when the revision of the test is incremented or when - # a new test is added, because the trybots are not allowed to - # produce reference images, only the bots on the main - # waterfalls. Report this as a failure so the developer has to - # take action by explicitly suppressing the failure and - # removing the suppression once the reference images have been - # generated. Otherwise silent failures could happen for long - # periods of time. - self.fail('Could not find image %s in cloud storage' % image_name) - else: - # Legacy path using on-disk results. - ref_png = self._GetReferenceImage( - self.GetParsedCommandLineOptions().reference_dir, - image_name, page.revision, screenshot) + # Legacy path using on-disk results. + ref_png = self._GetReferenceImage( + self.GetParsedCommandLineOptions().reference_dir, + image_name, page.revision, screenshot) - # Test new snapshot against existing reference image - if not image_util.AreEqual(ref_png, screenshot, tolerance=page.tolerance): - if self.GetParsedCommandLineOptions().test_machine_name: - self._UploadErrorImagesToCloudStorage(image_name, screenshot, ref_png) - else: - self._WriteErrorImages( - self.GetParsedCommandLineOptions().generated_dir, image_name, - screenshot, ref_png) - self.fail('Reference image did not match captured screen') + # Test new snapshot against existing reference image + if not image_util.AreEqual(ref_png, screenshot, tolerance=page.tolerance): + if self.GetParsedCommandLineOptions().test_machine_name: + self._UploadErrorImagesToCloudStorage(image_name, screenshot, ref_png) + else: + self._WriteErrorImages( + self.GetParsedCommandLineOptions().generated_dir, image_name, + screenshot, ref_png) + self.fail('Reference image did not match captured screen') + finally: + if do_page_action: + # Assume that page actions might have killed the GPU process. + self._RestartBrowser('Must restart after page actions') def _DoPageAction(self, tab, page): getattr(self, '_' + page.optional_action)(tab, page)
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index 038d8883..15a0f0c 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -99,6 +99,7 @@ void SetNeedsBeginFrames(bool needs_begin_frames) override {} void SetWantsAnimateOnlyBeginFrames() override {} void TakeFallbackContentFrom(RenderWidgetHostView* view) override; + void EnsureSurfaceSynchronizedForLayoutTest() override {} // RenderWidgetHostViewBase: void InitAsPopup(RenderWidgetHostView* parent_host_view,
diff --git a/device/BUILD.gn b/device/BUILD.gn index 6982c5b..7990f5a 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -137,7 +137,10 @@ # Serial is supported in below platforms. See //device/servial/BUILD.gn if (is_win || is_linux || is_mac) { - sources += [ "serial/serial_io_handler_posix_unittest.cc" ] + sources += [ + "serial/serial_device_enumerator_unittest.cc", + "serial/serial_io_handler_posix_unittest.cc", + ] deps += [ "//device/serial" ] } }
diff --git a/device/serial/serial_device_enumerator_unittest.cc b/device/serial/serial_device_enumerator_unittest.cc new file mode 100644 index 0000000..4f0f55a --- /dev/null +++ b/device/serial/serial_device_enumerator_unittest.cc
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/serial/serial_device_enumerator.h" + +#include <memory> +#include <vector> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +TEST(SerialDeviceEnumeratorTest, GetDevices) { + // There is no guarantee that a test machine will have a serial device + // available. The purpose of this test is to ensure that the process of + // attempting to enumerate devices does not cause a crash. + auto enumerator = SerialDeviceEnumerator::Create(); + ASSERT_TRUE(enumerator); + std::vector<mojom::SerialDeviceInfoPtr> devices = enumerator->GetDevices(); +} + +} // namespace device
diff --git a/docs/README.md b/docs/README.md index 7aee7c0..3997dff0 100644 --- a/docs/README.md +++ b/docs/README.md
@@ -291,6 +291,9 @@ * [VoiceOver](ios/voiceover.md) - Using Apple's VoiceOver feature with Chromium on iOS. +### Memory +* [Memory Overview](memory/README.md) + ### Memory Infrastructure Timeline Profiling (MemoryInfra) * [Overview](memory-infra/README.md) * [GPU Profiling](memory-infra/probe-gpu.md) @@ -299,7 +302,6 @@ * [Memory Usage in CC](memory-infra/probe-cc.md) * [Memory Benchmarks](memory-infra/memory_benchmarks.md) * [Heap Profiling](memory-infra/heap_profiler.md) -* [Heap Profiling Internals](memory-infra/heap_profiler_internals.md) ### Misc * [Useful URLs](useful_urls.md) - A collection of links to various tools and
diff --git a/docs/memory-infra/README.md b/docs/memory-infra/README.md index 84593a8..37404df 100644 --- a/docs/memory-infra/README.md +++ b/docs/memory-infra/README.md
@@ -114,7 +114,6 @@ * [Adding MemoryInfra Tracing to a Component](adding_memory_infra_tracing.md) * [GPU Memory Tracing](probe-gpu.md) - * [Heap Profiler Internals](heap_profiler_internals.md) * [Heap Profiling with MemoryInfra](heap_profiler.md) * [Startup Tracing with MemoryInfra](memory_infra_startup_tracing.md)
diff --git a/docs/memory-infra/heap_profiler_internals.md b/docs/memory-infra/heap_profiler_internals.md deleted file mode 100644 index d1019c8..0000000 --- a/docs/memory-infra/heap_profiler_internals.md +++ /dev/null
@@ -1,184 +0,0 @@ -# Heap Profiler Internals - -This document describes how the heap profiler works and how to add heap -profiling support to your allocator. If you just want to know how to use it, -see [Heap Profiling with MemoryInfra](heap_profiler.md) - -[TOC] - -## Overview - -The heap profiler consists of tree main components: - - * **The Context Tracker**: Responsible for providing context (pseudo stack - backtrace) when an allocation occurs. - * **The Allocation Register**: A specialized hash table that stores allocation - details by address. - * **The Heap Dump Writer**: Extracts the most important information from a set - of recorded allocations and converts it into a format that can be dumped into - the trace log. - -These components are designed to work well together, but to be usable -independently as well. - -When there is a way to get notified of all allocations and frees, this is the -normal flow: - - 1. When an allocation occurs, call - [`AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot()`][context-tracker] - to get an [`AllocationContext`][alloc-context]. - 2. Insert that context together with the address and size into an - [`AllocationRegister`][alloc-register] by calling `Insert()`. - 3. When memory is freed, remove it from the register with `Remove()`. - 4. On memory dump, collect the allocations from the register, call - [`ExportHeapDump()`][export-heap-dump], and add the generated heap dump to - the memory dump. - -[context-tracker]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_context_tracker.h -[alloc-context]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_context.h -[alloc-register]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_register.h -[export-heap-dump]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_heap_dump_writer.h - -*** aside -An allocator can skip step 2 and 3 if it is able to store the context itself, -and if it is able to enumerate all allocations for step 4. -*** - -When heap profiling is enabled (the `--enable-heap-profiling` flag is passed), -the memory dump manager calls `OnHeapProfilingEnabled()` on every -`MemoryDumpProvider` as early as possible, so allocators can start recording -allocations. This should be done even when tracing has not been started, -because these allocations might still be around when a heap dump happens during -tracing. - -## Context Tracker - -The [`AllocationContextTracker`][context-tracker] is a thread-local object. Its -main purpose is to keep track of a pseudo stack of trace events. Chrome has -been instrumented with lots of `TRACE_EVENT` macros. These trace events push -their name to a thread-local stack when they go into scope, and pop when they -go out of scope, if all of the following conditions have been met: - - * A trace is being recorded. - * The category of the event is enabled in the trace config. - * Heap profiling is enabled (with the `--enable-heap-profiling` flag). - -This means that allocations that occur before tracing is started will not have -backtrace information in their context. - -A thread-local instance of the context tracker is initialized lazily when it is -first accessed. This might be because a trace event pushed or popped, or because -`GetContextSnapshot()` was called when an allocation occurred. - -[`AllocationContext`][alloc-context] is what is used to group and break down -allocations. Currently `AllocationContext` has the following fields: - - * Backtrace: filled by the context tracker, obtained from the thread-local - pseudo stack. - * Type name: to be filled in at a point where the type of a pointer is known, - set to _[unknown]_ by default. - -It is possible to modify this context after insertion into the register, for -instance to set the type name if it was not known at the time of allocation. - -## Allocation Register - -The [`AllocationRegister`][alloc-register] is a hash table specialized for -storing `(size, AllocationContext)` pairs by address. It has been optimized for -Chrome's typical number of unfreed allocations, and it is backed by `mmap` -memory directly so there are no reentrancy issues when using it to record -`malloc` allocations. - -The allocation register is threading-agnostic. Access must be synchronised -properly. - -## Heap Dump Writer - -Dumping every single allocation in the allocation register straight into the -trace log is not an option due to the sheer volume (~300k unfreed allocations). -The role of the [`ExportHeapDump()`][export-heap-dump] function is to group -allocations, striking a balance between trace log size and detail. - -See the [Heap Dump Format][heap-dump-format] document for more details about the -structure of the heap dump in the trace log. - -[heap-dump-format]: https://docs.google.com/document/d/1NqBg1MzVnuMsnvV1AKLdKaPSPGpd81NaMPVk5stYanQ - -## Instrumenting an Allocator - -Below is an example of adding heap profiling support to an allocator that has -an existing memory dump provider. - -```cpp -class FooDumpProvider : public MemoryDumpProvider { - - // Kept as pointer because |AllocationRegister| allocates a lot of virtual - // address space when constructed, so only construct it when heap profiling is - // enabled. - scoped_ptr<AllocationRegister> allocation_register_; - Lock allocation_register_lock_; - - static FooDumpProvider* GetInstance(); - - void InsertAllocation(void* address, size_t size) { - AllocationContext context = AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); - AutoLock lock(allocation_register_lock_); - allocation_register_->Insert(address, size, context); - } - - void RemoveAllocation(void* address) { - AutoLock lock(allocation_register_lock_); - allocation_register_->Remove(address); - } - - // Will be called as early as possible by the memory dump manager. - void OnHeapProfilingEnabled(bool enabled) override { - AutoLock lock(allocation_register_lock_); - allocation_register_.reset(new AllocationRegister()); - - // At this point, make sure that from now on, for every allocation and - // free, |FooDumpProvider::GetInstance()->InsertAllocation()| and - // |RemoveAllocation| are called. - } - - bool OnMemoryDump(const MemoryDumpArgs& args, - ProcessMemoryDump& pmd) override { - // Do regular dumping here. - - // Dump the heap only for detailed dumps. - if (args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { - TraceEventMemoryOverhead overhead; - hash_map<AllocationContext, size_t> bytes_by_context; - - { - AutoLock lock(allocation_register_lock_); - if (allocation_register_) { - // Group allocations in the register into |bytes_by_context|, but do - // no additional processing inside the lock. - for (const auto& alloc_size : *allocation_register_) - bytes_by_context[alloc_size.context] += alloc_size.size; - - allocation_register_->EstimateTraceMemoryOverhead(&overhead); - } - } - - if (!bytes_by_context.empty()) { - scoped_refptr<TracedValue> heap_dump = ExportHeapDump( - bytes_by_context, - pmd->session_state()->stack_frame_deduplicator(), - pmb->session_state()->type_name_deduplicator()); - pmd->AddHeapDump("foo_allocator", heap_dump); - overhead.DumpInto("tracing/heap_profiler", pmd); - } - } - - return true; - } -}; - -``` - -*** aside -The implementation for `malloc` is more complicated because it needs to deal -with reentrancy. -***
diff --git a/extensions/renderer/messaging_util.cc b/extensions/renderer/messaging_util.cc index cc292b0..3ab9ded 100644 --- a/extensions/renderer/messaging_util.cc +++ b/extensions/renderer/messaging_util.cc
@@ -183,7 +183,10 @@ if (!v8_frame_id->IsUndefined()) { DCHECK(v8_frame_id->IsInt32()); - options.frame_id = v8_frame_id->Int32Value(); + int frame_id = v8_frame_id.As<v8::Int32>()->Value(); + // NOTE(devlin): JS bindings coerce any negative value to -1. For + // backwards compatibility, we do the same here. + options.frame_id = frame_id < 0 ? -1 : frame_id; } }
diff --git a/extensions/renderer/messaging_util_unittest.cc b/extensions/renderer/messaging_util_unittest.cc index 89e248bd..80a7ab0 100644 --- a/extensions/renderer/messaging_util_unittest.cc +++ b/extensions/renderer/messaging_util_unittest.cc
@@ -49,6 +49,37 @@ } } +TEST_F(MessagingUtilTest, TestParseMessageOptionsFrameId) { + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + + struct { + int expected_frame_id; + const char* string_options; + } test_cases[] = { + {messaging_util::kNoFrameId, "({})"}, + {messaging_util::kNoFrameId, "({frameId: undefined})"}, + // Note: we don't test null here, because the argument parsing code + // ensures we would never pass undefined to ParseMessageOptions (and + // there's a DCHECK to validate it). The null case is tested in the tabs' + // API hooks delegate test. + {0, "({frameId: 0})"}, + {2, "({frameId: 2})"}, + }; + + for (const auto& test_case : test_cases) { + SCOPED_TRACE(test_case.string_options); + v8::Local<v8::Value> value = + V8ValueFromScriptSource(context, test_case.string_options); + ASSERT_FALSE(value.IsEmpty()); + ASSERT_TRUE(value->IsObject()); + messaging_util::MessageOptions options = + messaging_util::ParseMessageOptions(context, value.As<v8::Object>(), + messaging_util::PARSE_FRAME_ID); + EXPECT_EQ(test_case.expected_frame_id, options.frame_id); + } +} + using MessagingUtilWithSystemTest = NativeExtensionBindingsSystemUnittest; TEST_F(MessagingUtilWithSystemTest, TestGetTargetIdFromExtensionContext) {
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 29b70f43..0c092cb 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc
@@ -99,6 +99,10 @@ return gpu; } +bool GPUInfo::IsInitialized() const { + return gpu.vendor_id != 0 || !gl_vendor.empty(); +} + void GPUInfo::EnumerateFields(Enumerator* enumerator) const { struct GPUInfoKnownFields { base::TimeDelta initialization_time;
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h index 3562a7c..8b27e08 100644 --- a/gpu/config/gpu_info.h +++ b/gpu/config/gpu_info.h
@@ -119,6 +119,8 @@ // The currently active gpu. const GPUDevice& active_gpu() const; + bool IsInitialized() const; + // The amount of time taken to get from the process starting to the message // loop being pumped. base::TimeDelta initialization_time;
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index 0d3ce07..16072ae 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc
@@ -409,14 +409,17 @@ } void GpuInit::AdjustInfoToSwiftShader() { + gpu_info_for_hardware_gpu_ = gpu_info_; + gpu_feature_info_for_hardware_gpu_ = gpu_feature_info_; gpu_feature_info_ = ComputeGpuFeatureInfoForSwiftShader(); - gpu_info_.gl_vendor = "Google Inc. (" + gpu_info_.gl_vendor + ")"; - gpu_info_.gl_renderer = "Google SwiftShader (" + gpu_info_.gl_renderer + ")"; - gpu_info_.gl_version = - "OpenGL ES 2.0 SwiftShader (" + gpu_info_.gl_version + ")"; + gpu_info_.gl_vendor = "Google Inc."; + gpu_info_.gl_renderer = "Google SwiftShader"; + gpu_info_.gl_version = "OpenGL ES 2.0 SwiftShader"; } void GpuInit::AdjustInfoToNoGpu() { + gpu_info_for_hardware_gpu_ = gpu_info_; + gpu_feature_info_for_hardware_gpu_ = gpu_feature_info_; gpu_feature_info_ = ComputeGpuFeatureInfoWithNoGpu(); gpu_info_.gl_vendor = "Disabled"; gpu_info_.gl_renderer = "Disabled";
diff --git a/gpu/ipc/service/gpu_init.h b/gpu/ipc/service/gpu_init.h index f104b6c..813c0e6 100644 --- a/gpu/ipc/service/gpu_init.h +++ b/gpu/ipc/service/gpu_init.h
@@ -48,6 +48,12 @@ const GPUInfo& gpu_info() const { return gpu_info_; } const GpuFeatureInfo& gpu_feature_info() const { return gpu_feature_info_; } + const GPUInfo& gpu_info_for_hardware_gpu() const { + return gpu_info_for_hardware_gpu_; + } + const GpuFeatureInfo& gpu_feature_info_for_hardware_gpu() const { + return gpu_feature_info_for_hardware_gpu_; + } const GpuPreferences& gpu_preferences() const { return gpu_preferences_; } std::unique_ptr<GpuWatchdogThread> TakeWatchdogThread() { return std::move(watchdog_thread_); @@ -62,6 +68,11 @@ GpuPreferences gpu_preferences_; bool init_successful_ = false; + // The following data are collected from hardware GPU and saved before + // switching to SwiftShader. + GPUInfo gpu_info_for_hardware_gpu_; + GpuFeatureInfo gpu_feature_info_for_hardware_gpu_; + bool ShouldEnableSwiftShader(base::CommandLine* command_line, bool blacklist_needs_more_info); void AdjustInfoToSwiftShader();
diff --git a/infra/config/branch/cq.cfg b/infra/config/branch/cq.cfg index 5942440..054abe404 100644 --- a/infra/config/branch/cq.cfg +++ b/infra/config/branch/cq.cfg
@@ -106,7 +106,7 @@ } builders { name: "linux_chromium_tsan_rel_ng" - equivalent_to { bucket: "luci.chromium.try" percentage: 10 } + equivalent_to { bucket: "luci.chromium.try" percentage: 100 } } builders { # Temporary addition to gather data for LUCI migration.
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index b7485a9..ba76b6e 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -415,11 +415,18 @@ builders { name: "Android arm64 Builder (dbg)" mixins: "android-ci" + mixins: "goma-many-jobs-for-ci" dimensions: "os:Ubuntu-14.04" execution_timeout_secs: 14400 # 4h } builders { + name: "Android Cronet Builder" + mixins: "android-ci" + dimensions: "os:Ubuntu-14.04" + } + + builders { name: "Android FYI 32 Vk Release (Nexus 5X)" mixins: "android-gpu-fyi-ci" } @@ -1116,6 +1123,11 @@ } builders { mixins: "android-try" + name: "android_cronet" + dimensions: "os:Ubuntu-14.04" + } + builders { + mixins: "android-try" name: "android_n5x_swarming_dbg" dimensions: "os:Ubuntu-14.04" }
diff --git a/infra/config/global/luci-milo-dev.cfg b/infra/config/global/luci-milo-dev.cfg index 99c5857..3380ee35 100644 --- a/infra/config/global/luci-milo-dev.cfg +++ b/infra/config/global/luci-milo-dev.cfg
@@ -3436,6 +3436,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.android/android_archive_rel_ng" @@ -3527,6 +3528,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.angle/android_angle_deqp_rel_ng" @@ -3594,6 +3596,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.chromiumos/chromeos-amd64-generic-rel" @@ -3619,6 +3622,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.linux/cast_shell_audio_linux" @@ -3764,6 +3768,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.mac/ios-device" @@ -3873,6 +3878,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.perf/Android Compile Perf" @@ -3916,6 +3922,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.win/win10_chromium_x64_rel_ng" @@ -4000,6 +4007,7 @@ repo_url: "https://chromium.googlesource.com/chromium/src" ref: "refs/heads/master" manifest_name: "REVISION" + builder_view_only: true builders: { name: "buildbot/tryserver.blink/linux_trusty_blink_compile_dbg"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index f44e4f86..ecf9fb7 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -1653,6 +1653,17 @@ category: "chromium.linux|debug" short_name: "ci" } + + builders: { + name: "buildbot/chromium.android/Android Cronet Builder" + category: "chromium.android|cronet" + short_name: "bb" + } + builders: { + name: "buildbucket/luci.chromium.ci/Android Cronet Builder" + category: "chromium.android|cronet" + short_name: "ci" + } builders: { name: "buildbot/chromium.fyi/Android deterministic" category: "chromium.android|release" @@ -1738,17 +1749,8 @@ header_id: "chromium" builders: { - name: "buildbot/chromium.android/Android Cronet ARM64 Builder" - category: "cronet" - short_name: "rel" - } - builders: { - name: "buildbot/chromium.android/Android Cronet ARM64 Builder (dbg)" - category: "cronet" - short_name: "dbg" - } - builders: { name: "buildbot/chromium.android/Android Cronet Builder" + name: "buildbucket/luci.chromium.ci/Android Cronet Builder" category: "cronet" short_name: "rel" } @@ -1778,21 +1780,31 @@ short_name: "mar" } builders: { - name: "buildbot/chromium.android/Android Cronet x86 Builder" + name: "buildbot/chromium.android/Android Cronet Marshmallow 64bit Perf" category: "cronet" + short_name: "prf" + } + builders: { + name: "buildbot/chromium.android/Android Cronet ARM64 Builder" + category: "cronet|arm64" + short_name: "rel" + } + builders: { + name: "buildbot/chromium.android/Android Cronet ARM64 Builder (dbg)" + category: "cronet|arm64" + short_name: "dbg" + } + builders: { + name: "buildbot/chromium.android/Android Cronet x86 Builder" + category: "cronet|x86" short_name: "rel" } builders: { name: "buildbot/chromium.android/Android Cronet x86 Builder (dbg)" - category: "cronet" + category: "cronet|x86" short_name: "dbg" } builders: { - name: "buildbot/chromium.android/Android Cronet Marshmallow 64bit Perf" - category: "cronet" - short_name: "prf" - } - builders: { name: "buildbot/chromium.android/Android arm Builder (dbg)" category: "builder|arm" short_name: "32" @@ -3762,6 +3774,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.android/android_archive_rel_ng" @@ -3813,6 +3826,7 @@ } builders: { name: "buildbot/tryserver.chromium.android/android_cronet" + name: "buildbucket/luci.chromium.try/android_cronet" } builders: { name: "buildbot/tryserver.chromium.android/android_cronet_tester" @@ -3850,6 +3864,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.chromiumos/chromeos-amd64-generic-rel" @@ -3875,6 +3890,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.linux/cast_shell_audio_linux" @@ -4005,6 +4021,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.mac/ios-device" @@ -4114,6 +4131,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbot/tryserver.chromium.perf/Android Compile Perf" @@ -4157,6 +4175,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbucket/luci.chromium.try/win10_chromium_x64_dbg_ng" @@ -4244,6 +4263,7 @@ repo_url: "https://chromium.googlesource.com/chromium/src" ref: "refs/heads/master" manifest_name: "REVISION" + builder_view_only: true builders: { name: "buildbot/tryserver.blink/linux_trusty_blink_compile_dbg" @@ -4296,6 +4316,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbucket/luci.chromium.try/android_angle_deqp_rel_ng" @@ -4363,6 +4384,7 @@ ref: "refs/heads/master" manifest_name: "REVISION" header_id: "chromium" + builder_view_only: true builders: { name: "buildbucket/luci.chromium.try/android_arm64_dbg_recipe"
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index 77bb9d1c..157080a 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -53,6 +53,7 @@ # Android. Sorted alphabetically. triggers: "Android arm64 Builder (dbg)" + triggers: "Android Cronet Builder" triggers: "Android FYI 32 Vk Release (Nexus 5X)" triggers: "Android FYI 64 Vk Release (Nexus 5X)" triggers: "Android FYI dEQP Release (Nexus 5X)" @@ -142,6 +143,16 @@ } job { + id: "Android Cronet Builder" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Android Cronet Builder" + } +} + +job { id: "Android FYI 32 Vk Release (Nexus 5X)" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 2db398d..0e9689e 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -4075,7 +4075,13 @@ if (self.currentWebState) { UIEdgeInsets contentPadding = self.currentWebState->GetWebViewProxy().contentInset; - contentPadding.top = AlignValueToPixel(progress * [self toolbarHeight]); + CGFloat toolbarHeightFullscreen = 0; + if (IsUIRefreshPhase1Enabled()) { + toolbarHeightFullscreen = kToolbarHeightFullscreen; + } + CGFloat toolbarHeightDelta = [self toolbarHeight] - toolbarHeightFullscreen; + contentPadding.top = AlignValueToPixel(toolbarHeightFullscreen + + progress * toolbarHeightDelta); contentPadding.bottom = AlignValueToPixel(progress * [self secondaryToolbarHeightWithInset]); self.currentWebState->GetWebViewProxy().contentInset = contentPadding;
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc index ae7b77d..266284b 100644 --- a/media/audio/audio_output_device.cc +++ b/media/audio/audio_output_device.cc
@@ -249,7 +249,6 @@ if (state_ == PAUSED) { TRACE_EVENT_ASYNC_BEGIN0( "audio", "StartingPlayback", audio_callback_.get()); - ipc_->SetVolume(volume_); ipc_->PlayStream(); state_ = PLAYING; play_on_start_ = false; @@ -302,12 +301,8 @@ void AudioOutputDevice::SetVolumeOnIOThread(double volume) { DCHECK(task_runner()->BelongsToCurrentThread()); - if (state_ >= CREATING_STREAM) { - // Defer playing until start unless we've already started. - volume_ = volume; - if (state_ == PLAYING) - ipc_->SetVolume(volume_); - } + if (state_ >= CREATING_STREAM) + ipc_->SetVolume(volume); } void AudioOutputDevice::OnError() {
diff --git a/media/audio/audio_output_device.h b/media/audio/audio_output_device.h index bed3fbe..dae0c14 100644 --- a/media/audio/audio_output_device.h +++ b/media/audio/audio_output_device.h
@@ -187,9 +187,6 @@ // State of Play() / Pause() calls before OnStreamCreated() is called. bool play_on_start_; - // Last set volume. - double volume_ = 1.0; - // The media session ID used to identify which input device to be started. // Only used by Unified IO. int session_id_;
diff --git a/media/base/renderer_factory_selector.cc b/media/base/renderer_factory_selector.cc index 4e50612..ef2b579 100644 --- a/media/base/renderer_factory_selector.cc +++ b/media/base/renderer_factory_selector.cc
@@ -35,6 +35,9 @@ if (query_is_remoting_active_cb_ && query_is_remoting_active_cb_.Run()) next_factory_type = FactoryType::COURIER; + if (query_is_flinging_active_cb_ && query_is_flinging_active_cb_.Run()) + next_factory_type = FactoryType::FLINGING; + DVLOG(1) << __func__ << " Selecting factory type: " << next_factory_type; RendererFactory* current_factory = factories_[next_factory_type].get(); @@ -56,4 +59,10 @@ query_is_remoting_active_cb_ = query_is_remoting_active_cb; } +void RendererFactorySelector::SetQueryIsFlingingActiveCB( + QueryIsFlingingActiveCB query_is_flinging_active_cb) { + DCHECK(!query_is_flinging_active_cb_); + query_is_flinging_active_cb_ = query_is_flinging_active_cb; +} + } // namespace media
diff --git a/media/base/renderer_factory_selector.h b/media/base/renderer_factory_selector.h index c579434..6d929b1d4c 100644 --- a/media/base/renderer_factory_selector.h +++ b/media/base/renderer_factory_selector.h
@@ -17,13 +17,15 @@ class MEDIA_EXPORT RendererFactorySelector { public: using QueryIsRemotingActiveCB = base::Callback<bool()>; + using QueryIsFlingingActiveCB = base::Callback<bool()>; enum FactoryType { DEFAULT, // DefaultRendererFactory. MOJO, // MojoRendererFactory. MEDIA_PLAYER, // MediaPlayerRendererClientFactory. COURIER, // CourierRendererFactory. - FACTORY_TYPE_MAX = COURIER, + FLINGING, // FlingingRendererClientFactory + FACTORY_TYPE_MAX = FLINGING, }; RendererFactorySelector(); @@ -54,10 +56,16 @@ void SetQueryIsRemotingActiveCB( QueryIsRemotingActiveCB query_is_remoting_active_cb); + // Sets the callback to query whether we are currently flinging media, and if + // we should temporarily use the FLINGING factory. + void SetQueryIsFlingingActiveCB( + QueryIsFlingingActiveCB query_is_flinging_active_cb); + private: bool use_media_player_ = false; QueryIsRemotingActiveCB query_is_remoting_active_cb_; + QueryIsFlingingActiveCB query_is_flinging_active_cb_; base::Optional<FactoryType> base_factory_type_; std::unique_ptr<RendererFactory> factories_[FACTORY_TYPE_MAX + 1];
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc index 01599dde..c4a349b 100644 --- a/media/base/test_helpers.cc +++ b/media/base/test_helpers.cc
@@ -126,6 +126,7 @@ } static VideoDecoderConfig GetTestConfig(VideoCodec codec, + VideoCodecProfile config, VideoRotation rotation, gfx::Size coded_size, bool is_encrypted) { @@ -133,8 +134,8 @@ gfx::Size natural_size = coded_size; return VideoDecoderConfig( - codec, VIDEO_CODEC_PROFILE_UNKNOWN, PIXEL_FORMAT_I420, COLOR_SPACE_JPEG, - rotation, coded_size, visible_rect, natural_size, EmptyExtraData(), + codec, config, PIXEL_FORMAT_I420, COLOR_SPACE_JPEG, rotation, coded_size, + visible_rect, natural_size, EmptyExtraData(), is_encrypted ? AesCtrEncryptionScheme() : Unencrypted()); } @@ -143,38 +144,44 @@ // static VideoDecoderConfig TestVideoConfig::Invalid() { - return GetTestConfig(kUnknownVideoCodec, VIDEO_ROTATION_0, kNormalSize, - false); + return GetTestConfig(kUnknownVideoCodec, VIDEO_CODEC_PROFILE_UNKNOWN, + VIDEO_ROTATION_0, kNormalSize, false); } // static VideoDecoderConfig TestVideoConfig::Normal(VideoCodec codec) { - return GetTestConfig(codec, VIDEO_ROTATION_0, kNormalSize, false); + return GetTestConfig(codec, VIDEO_CODEC_PROFILE_UNKNOWN, VIDEO_ROTATION_0, + kNormalSize, false); } // static -VideoDecoderConfig TestVideoConfig::NormalH264() { - return GetTestConfig(kCodecH264, VIDEO_ROTATION_0, kNormalSize, false); +VideoDecoderConfig TestVideoConfig::NormalH264(VideoCodecProfile config) { + return GetTestConfig(kCodecH264, config, VIDEO_ROTATION_0, kNormalSize, + false); } // static VideoDecoderConfig TestVideoConfig::NormalEncrypted(VideoCodec codec) { - return GetTestConfig(codec, VIDEO_ROTATION_0, kNormalSize, true); + return GetTestConfig(codec, VIDEO_CODEC_PROFILE_UNKNOWN, VIDEO_ROTATION_0, + kNormalSize, true); } // static VideoDecoderConfig TestVideoConfig::NormalRotated(VideoRotation rotation) { - return GetTestConfig(kCodecVP8, rotation, kNormalSize, false); + return GetTestConfig(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, rotation, + kNormalSize, false); } // static VideoDecoderConfig TestVideoConfig::Large(VideoCodec codec) { - return GetTestConfig(codec, VIDEO_ROTATION_0, kLargeSize, false); + return GetTestConfig(codec, VIDEO_CODEC_PROFILE_UNKNOWN, VIDEO_ROTATION_0, + kLargeSize, false); } // static VideoDecoderConfig TestVideoConfig::LargeEncrypted(VideoCodec codec) { - return GetTestConfig(codec, VIDEO_ROTATION_0, kLargeSize, true); + return GetTestConfig(codec, VIDEO_CODEC_PROFILE_UNKNOWN, VIDEO_ROTATION_0, + kLargeSize, true); } // static
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h index 1003154..21ea5cc 100644 --- a/media/base/test_helpers.h +++ b/media/base/test_helpers.h
@@ -88,7 +88,8 @@ static VideoDecoderConfig Invalid(); static VideoDecoderConfig Normal(VideoCodec codec = kCodecVP8); - static VideoDecoderConfig NormalH264(); + static VideoDecoderConfig NormalH264( + VideoCodecProfile = VIDEO_CODEC_PROFILE_UNKNOWN); static VideoDecoderConfig NormalEncrypted(VideoCodec codec = kCodecVP8); static VideoDecoderConfig NormalRotated(VideoRotation rotation);
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 391c797..b82376a7 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -576,6 +576,7 @@ testonly = true deps = [ "//base", + "//base/test:test_support", "//media:test_support", "//media/gpu", "//media/gpu/ipc/service:unit_tests", @@ -594,6 +595,7 @@ "windows/d3d11_cdm_proxy_unittest.cc", "windows/d3d11_mocks.cc", "windows/d3d11_mocks.h", + "windows/d3d11_video_decoder_unittest.cc", ] libs = [ "dxguid.lib" ] }
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 6c52a1fc..354aea0 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -45,18 +45,32 @@ namespace media { -D3D11VideoDecoder::D3D11VideoDecoder( +std::unique_ptr<VideoDecoder> D3D11VideoDecoder::Create( scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, const gpu::GpuPreferences& gpu_preferences, - base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb) - : impl_task_runner_(std::move(gpu_task_runner)), - gpu_preferences_(gpu_preferences), - weak_factory_(this) { + const gpu::GpuDriverBugWorkarounds& gpu_workarounds, + base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb) { // We create |impl_| on the wrong thread, but we never use it here. // Note that the output callback will hop to our thread, post the video // frame, and along with a callback that will hop back to the impl thread // when it's released. - impl_ = std::make_unique<D3D11VideoDecoderImpl>(get_stub_cb); + // Note that we WrapUnique<VideoDecoder> rather than D3D11VideoDecoder to make + // this castable; the deleters have to match. + return base::WrapUnique<VideoDecoder>(new D3D11VideoDecoder( + std::move(gpu_task_runner), gpu_preferences, gpu_workarounds, + std::make_unique<D3D11VideoDecoderImpl>(get_stub_cb))); +} + +D3D11VideoDecoder::D3D11VideoDecoder( + scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, + const gpu::GpuPreferences& gpu_preferences, + const gpu::GpuDriverBugWorkarounds& gpu_workarounds, + std::unique_ptr<D3D11VideoDecoderImpl> impl) + : impl_(std::move(impl)), + impl_task_runner_(std::move(gpu_task_runner)), + gpu_preferences_(gpu_preferences), + gpu_workarounds_(gpu_workarounds), + weak_factory_(this) { impl_weak_ = impl_->GetWeakPtr(); } @@ -78,13 +92,15 @@ const InitCB& init_cb, const OutputCB& output_cb, const WaitingForDecryptionKeyCB& waiting_for_decryption_key_cb) { - if (IsUnsupported(config)) { + if (!IsPotentiallySupported(config)) { init_cb.Run(false); return; } // Bind our own init / output cb that hop to this thread, so we don't call the // originals on some other thread. + // Important but subtle note: base::Bind will copy |config_| since it's a + // const ref. // TODO(liberato): what's the lifetime of |cdm_context|? impl_task_runner_->PostTask( FROM_HERE, @@ -127,19 +143,21 @@ return impl_->GetMaxDecodeRequests(); } -bool D3D11VideoDecoder::IsUnsupported(const VideoDecoderConfig& config) { +bool D3D11VideoDecoder::IsPotentiallySupported( + const VideoDecoderConfig& config) { // TODO(liberato): All of this could be moved into MojoVideoDecoder, so that // it could run on the client side and save the IPC hop. // Must be H264. const bool is_h264 = config.profile() >= H264PROFILE_MIN && config.profile() <= H264PROFILE_MAX; + if (!is_h264) - return true; + return false; // Must use NV12, which excludes HDR. if (config.profile() == H264PROFILE_HIGH10PROFILE) - return true; + return false; // TODO(liberato): dxva checks IsHDR() in the target colorspace, but we don't // have the target colorspace. It's commented as being for vpx, though, so @@ -147,15 +165,16 @@ // Must use the validating decoder. if (gpu_preferences_.use_passthrough_cmd_decoder) - return true; + return false; // Must allow zero-copy of nv12 textures. - // TODO(liberato): check gpu workarounds too, once it's plumbed through. It - // will be added as part of VDAVideoDecoder. if (!gpu_preferences_.enable_zero_copy_dxgi_video) - return true; + return false; - return false; + if (gpu_workarounds_.disable_dxgi_zero_copy_video) + return false; + + return true; } } // namespace media
diff --git a/media/gpu/windows/d3d11_video_decoder.h b/media/gpu/windows/d3d11_video_decoder.h index f9551e8..dcf3f9d 100644 --- a/media/gpu/windows/d3d11_video_decoder.h +++ b/media/gpu/windows/d3d11_video_decoder.h
@@ -11,6 +11,8 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" +#include "gpu/command_buffer/service/gpu_preferences.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" #include "gpu/ipc/service/command_buffer_stub.h" #include "media/base/video_decoder.h" #include "media/gpu/media_gpu_export.h" @@ -18,6 +20,7 @@ namespace media { class D3D11VideoDecoderImpl; +class D3D11VideoDecoderTest; // Thread-hopping implementation of D3D11VideoDecoder. It's meant to run on // a random thread, and hop to the gpu main thread. It does this so that it @@ -27,11 +30,11 @@ // now, it's easier to hop threads. class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder { public: - D3D11VideoDecoder( + static std::unique_ptr<VideoDecoder> Create( scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, const gpu::GpuPreferences& gpu_preferences, + const gpu::GpuDriverBugWorkarounds& gpu_workarounds, base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb); - ~D3D11VideoDecoder() override; // VideoDecoder implementation: std::string GetDisplayName() const override; @@ -49,11 +52,24 @@ bool CanReadWithoutStalling() const override; int GetMaxDecodeRequests() const override; - // Return true if |config| definitely isn't going to work, so that we can fail + // Return false |config| definitely isn't going to work, so that we can fail // init without bothering with a thread hop. - bool IsUnsupported(const VideoDecoderConfig& config); + bool IsPotentiallySupported(const VideoDecoderConfig& config); + + protected: + // Owners should call Destroy(). This is automatic via + // std::default_delete<media::VideoDecoder> when held by a + // std::unique_ptr<media::VideoDecoder>. + ~D3D11VideoDecoder() override; private: + friend class D3D11VideoDecoderTest; + + D3D11VideoDecoder(scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, + const gpu::GpuPreferences& gpu_preferences, + const gpu::GpuDriverBugWorkarounds& gpu_workarounds, + std::unique_ptr<D3D11VideoDecoderImpl> impl); + // The implementation, which we trampoline to the impl thread. // This must be freed on the impl thread. std::unique_ptr<D3D11VideoDecoderImpl> impl_; @@ -65,6 +81,7 @@ scoped_refptr<base::SequencedTaskRunner> impl_task_runner_; gpu::GpuPreferences gpu_preferences_; + gpu::GpuDriverBugWorkarounds gpu_workarounds_; base::WeakPtrFactory<D3D11VideoDecoder> weak_factory_;
diff --git a/media/gpu/windows/d3d11_video_decoder_unittest.cc b/media/gpu/windows/d3d11_video_decoder_unittest.cc new file mode 100644 index 0000000..d29b30a --- /dev/null +++ b/media/gpu/windows/d3d11_video_decoder_unittest.cc
@@ -0,0 +1,146 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/gpu/windows/d3d11_video_decoder.h" + +#include <d3d11.h> +#include <d3d11_1.h> +#include <initguid.h> + +#include "base/bind.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "media/base/decoder_buffer.h" +#include "media/base/test_helpers.h" +#include "media/gpu/windows/d3d11_mocks.h" +#include "media/gpu/windows/d3d11_video_decoder_impl.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +namespace media { + +class MockD3D11VideoDecoderImpl : public D3D11VideoDecoderImpl { + public: + MockD3D11VideoDecoderImpl() + : D3D11VideoDecoderImpl( + base::RepeatingCallback<gpu::CommandBufferStub*()>()) {} + + MOCK_METHOD6( + Initialize, + void(const VideoDecoderConfig& config, + bool low_delay, + CdmContext* cdm_context, + const InitCB& init_cb, + const OutputCB& output_cb, + const WaitingForDecryptionKeyCB& waiting_for_decryption_key_cb)); + + MOCK_METHOD2(Decode, + void(scoped_refptr<DecoderBuffer> buffer, + const DecodeCB& decode_cb)); + MOCK_METHOD1(Reset, void(const base::RepeatingClosure& closure)); +}; + +class D3D11VideoDecoderTest : public ::testing::Test { + public: + void SetUp() override { + // Set up some sane defaults. + gpu_preferences_.enable_zero_copy_dxgi_video = true; + gpu_preferences_.use_passthrough_cmd_decoder = false; + gpu_workarounds_.disable_dxgi_zero_copy_video = false; + supported_config_ = TestVideoConfig::NormalH264(H264PROFILE_MAIN); + } + + void TearDown() override { + decoder_.reset(); + // Run the gpu thread runner to tear down |impl_|. + base::RunLoop().RunUntilIdle(); + } + + void CreateDecoder() { + std::unique_ptr<MockD3D11VideoDecoderImpl> impl = + std::make_unique<MockD3D11VideoDecoderImpl>(); + impl_ = impl.get(); + + gpu_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + + decoder_ = base::WrapUnique<VideoDecoder>(new D3D11VideoDecoder( + gpu_task_runner_, gpu_preferences_, gpu_workarounds_, std::move(impl))); + } + + enum InitExpectation { + kExpectFailure = false, + kExpectSuccess = true, + }; + + void InitializeDecoder(const VideoDecoderConfig& config, + InitExpectation expectation) { + const bool low_delay = false; + CdmContext* cdm_context = nullptr; + + if (expectation == kExpectSuccess) { + EXPECT_CALL(*this, MockInitCB(_)).Times(0); + EXPECT_CALL(*impl_, Initialize(_, low_delay, cdm_context, _, _, _)); + } else { + EXPECT_CALL(*this, MockInitCB(false)); + } + + decoder_->Initialize(config, low_delay, cdm_context, + base::BindRepeating(&D3D11VideoDecoderTest::MockInitCB, + base::Unretained(this)), + VideoDecoder::OutputCB(), + VideoDecoder::WaitingForDecryptionKeyCB()); + base::RunLoop().RunUntilIdle(); + } + + base::test::ScopedTaskEnvironment env_; + + scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; + + std::unique_ptr<VideoDecoder> decoder_; + gpu::GpuPreferences gpu_preferences_; + gpu::GpuDriverBugWorkarounds gpu_workarounds_; + MockD3D11VideoDecoderImpl* impl_ = nullptr; + VideoDecoderConfig supported_config_; + + MOCK_METHOD1(MockInitCB, void(bool)); +}; + +TEST_F(D3D11VideoDecoderTest, SupportsH264) { + CreateDecoder(); + // Make sure that we're testing H264. + ASSERT_EQ(supported_config_.profile(), H264PROFILE_MAIN); + InitializeDecoder(supported_config_, kExpectSuccess); +} + +TEST_F(D3D11VideoDecoderTest, DoesNotSupportVP8) { + CreateDecoder(); + InitializeDecoder(TestVideoConfig::Normal(kCodecVP8), kExpectFailure); +} + +TEST_F(D3D11VideoDecoderTest, DoesNotSupportVP9) { + CreateDecoder(); + InitializeDecoder(TestVideoConfig::Normal(kCodecVP9), kExpectFailure); +} + +TEST_F(D3D11VideoDecoderTest, RequiresZeroCopyPreference) { + gpu_preferences_.enable_zero_copy_dxgi_video = false; + CreateDecoder(); + InitializeDecoder(supported_config_, kExpectFailure); +} + +TEST_F(D3D11VideoDecoderTest, FailsIfUsingPassthroughDecoder) { + gpu_preferences_.use_passthrough_cmd_decoder = true; + CreateDecoder(); + InitializeDecoder(supported_config_, kExpectFailure); +} + +TEST_F(D3D11VideoDecoderTest, FailsIfZeroCopyWorkaround) { + gpu_workarounds_.disable_dxgi_zero_copy_video = true; + CreateDecoder(); + InitializeDecoder(supported_config_, kExpectFailure); +} + +} // namespace media
diff --git a/media/mojo/clients/mojo_renderer_factory.cc b/media/mojo/clients/mojo_renderer_factory.cc index 2601efde..4a2096a 100644 --- a/media/mojo/clients/mojo_renderer_factory.cc +++ b/media/mojo/clients/mojo_renderer_factory.cc
@@ -27,6 +27,11 @@ MojoRendererFactory::~MojoRendererFactory() = default; +void MojoRendererFactory::SetGetTypeSpecificIdCB( + const GetTypeSpecificIdCB& get_type_specific_id) { + get_type_specific_id_ = get_type_specific_id; +} + std::unique_ptr<Renderer> MojoRendererFactory::CreateRenderer( const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, const scoped_refptr<base::TaskRunner>& /* worker_task_runner */, @@ -52,7 +57,10 @@ mojom::RendererPtr renderer_ptr; if (interface_factory_) { - interface_factory_->CreateRenderer(hosted_renderer_type_, std::string(), + interface_factory_->CreateRenderer(hosted_renderer_type_, + get_type_specific_id_.is_null() + ? std::string() + : get_type_specific_id_.Run(), mojo::MakeRequest(&renderer_ptr)); } else { NOTREACHED();
diff --git a/media/mojo/clients/mojo_renderer_factory.h b/media/mojo/clients/mojo_renderer_factory.h index f0fa1f33..5096df53 100644 --- a/media/mojo/clients/mojo_renderer_factory.h +++ b/media/mojo/clients/mojo_renderer_factory.h
@@ -24,6 +24,7 @@ class MojoRendererFactory : public RendererFactory { public: using GetGpuFactoriesCB = base::Callback<GpuVideoAcceleratorFactories*()>; + using GetTypeSpecificIdCB = base::Callback<std::string()>; MojoRendererFactory(mojom::HostedRendererType type, const GetGpuFactoriesCB& get_gpu_factories_cb, @@ -39,10 +40,19 @@ const RequestOverlayInfoCB& request_overlay_info_cb, const gfx::ColorSpace& target_color_space) final; + // Sets the callback that will fetch the TypeSpecificId when + // InterfaceFactory::CreateRenderer() is called. What the string represents + // depends on the value of |hosted_renderer_type_|. Currently, we only use it + // with mojom::HostedRendererType::kFlinging, in which case + // |get_type_specific_id| should return the presentation ID to be given to the + // FlingingRenderer in the browser process. + void SetGetTypeSpecificIdCB(const GetTypeSpecificIdCB& get_type_specific_id); + private: mojom::RendererPtr GetRendererPtr(); GetGpuFactoriesCB get_gpu_factories_cb_; + GetTypeSpecificIdCB get_type_specific_id_; // InterfaceFactory or InterfaceProvider used to create or connect to remote // renderer.
diff --git a/media/mojo/interfaces/audio_output_stream.mojom b/media/mojo/interfaces/audio_output_stream.mojom index fbc1fbf..2ccf4b75 100644 --- a/media/mojo/interfaces/audio_output_stream.mojom +++ b/media/mojo/interfaces/audio_output_stream.mojom
@@ -25,6 +25,21 @@ SetVolume(double volume); }; +interface AudioOutputStreamClient { + // Called if the stream has an error such as failing to open/losing access to + // a device. This renders the stream unusable. + OnError(); +}; + +interface AudioOutputStreamProvider { + // Creates a new AudioOutputStream using |params|. |data_pipe| is used to + // transfer audio data. + // Can only be called once. + Acquire(AudioOutputStream& output_stream, AudioOutputStreamClient client, + AudioParameters params) + => (AudioDataPipe data_pipe); +}; + // An AudioOutputStreamObserver gets notifications about events related to an // AudioOutputStream. DidStartPlaying() is invoked when the stream starts // playing and it is eventually followed by a DidStopPlaying() call. A stream @@ -33,13 +48,6 @@ // Note: It is possible that DidStopPlaying() is not called in shutdown // situations. interface AudioOutputStreamObserver { - // This code is used as disconnect reason when stream ended or failed to - // start due to an unrecoverable platform error, e.g. the hardware device is - // busy or disconnected. - // If the error code isn't used, the stream ended due to being terminated by - // the client. - const uint32 kPlatformErrorDisconnectReason = 1; - // This notification indicates that the stream started playing. The stream // should be considered non-audible until a DidChangeAudibleState() call says // otherwise. @@ -55,27 +63,3 @@ // DidStartPlaying() and before DidStopPlaying(). DidChangeAudibleState(bool is_audible); }; - -interface AudioOutputStreamProvider { - // Creates a new AudioOutputStream using |params|. |client| is notified when - // the stream is ready. The stream lifetime is bound by the lifetime of - // |client|. On error, the |client| will have a disconnect reason among the - // specified ones in AudioOutputStreamProviderClient. - // Can only be called once. - Acquire(AudioParameters params, AudioOutputStreamProviderClient client); -}; - -interface AudioOutputStreamProviderClient { - // This code is used as disconnect reason when stream ended or failed to - // start due to an unrecoverable platform error, e.g. the hardware device is - // busy or disconnected. - // If the error code isn't used, the stream ended/wasn't started due to the - // stream becoming unnecessary or unwanted, or the request was dropped. - const uint32 kPlatformErrorDisconnectReason = 1; - - // |stream| is used to pass commands to the stream, and |data_pipe| is used - // to transfer the audio data. - // TODO(https://crbug.com/787806): Currently, this will be called at most - // once. In the future, it may be called several times. - Created(AudioOutputStream stream, AudioDataPipe data_pipe); -};
diff --git a/media/mojo/services/OWNERS b/media/mojo/services/OWNERS index da9d4b5c..fce6c7a 100644 --- a/media/mojo/services/OWNERS +++ b/media/mojo/services/OWNERS
@@ -15,6 +15,3 @@ per-file pipeline_apptest_manifest.json=set noparent per-file pipeline_apptest_manifest.json=file://ipc/SECURITY_OWNERS - -per-file mojo_audio_output*=file://media/audio/OWNERS -per-file mojo_audio_input*=file://media/audio/OWNERS
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index f4ecc9f..fa8a58d 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -136,8 +136,8 @@ command_buffer_id->channel_token, command_buffer_id->route_id)); #elif defined(OS_WIN) - return std::make_unique<D3D11VideoDecoder>( - gpu_task_runner_, gpu_preferences_, + return D3D11VideoDecoder::Create( + gpu_task_runner_, gpu_preferences_, gpu_workarounds_, base::BindRepeating(&GetCommandBufferStub, media_gpu_channel_manager_, command_buffer_id->channel_token, command_buffer_id->route_id));
diff --git a/media/mojo/services/mojo_audio_output_stream.cc b/media/mojo/services/mojo_audio_output_stream.cc index 57af5108..79e5241 100644 --- a/media/mojo/services/mojo_audio_output_stream.cc +++ b/media/mojo/services/mojo_audio_output_stream.cc
@@ -15,20 +15,29 @@ namespace media { MojoAudioOutputStream::MojoAudioOutputStream( + mojom::AudioOutputStreamRequest request, + mojom::AudioOutputStreamClientPtr client, CreateDelegateCallback create_delegate_callback, StreamCreatedCallback stream_created_callback, - DeleterCallback deleter_callback) + base::OnceClosure deleter_callback) : stream_created_callback_(std::move(stream_created_callback)), deleter_callback_(std::move(deleter_callback)), - binding_(this), + binding_(this, std::move(request)), + client_(std::move(client)), weak_factory_(this) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(stream_created_callback_); DCHECK(deleter_callback_); + // |this| owns |binding_|, so unretained is safe. + binding_.set_connection_error_handler( + base::BindOnce(&MojoAudioOutputStream::OnError, base::Unretained(this))); + client_.set_connection_error_handler( + base::BindOnce(&MojoAudioOutputStream::OnError, base::Unretained(this))); delegate_ = std::move(create_delegate_callback).Run(this); if (!delegate_) { // Failed to initialize the stream. We cannot call |deleter_callback_| yet, // since construction isn't done. + binding_.Close(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&MojoAudioOutputStream::OnStreamError, @@ -86,27 +95,21 @@ DCHECK(buffer_handle.is_valid()); DCHECK(socket_handle.is_valid()); - mojom::AudioOutputStreamPtr stream; - binding_.Bind(mojo::MakeRequest(&stream)); - // |this| owns |binding_| so unretained is safe. - binding_.set_connection_error_handler(base::BindOnce( - &MojoAudioOutputStream::StreamConnectionLost, base::Unretained(this))); - - std::move(stream_created_callback_) - .Run(std::move(stream), {base::in_place, std::move(buffer_handle), - std::move(socket_handle)}); + base::ResetAndReturn(&stream_created_callback_) + .Run( + {base::in_place, std::move(buffer_handle), std::move(socket_handle)}); } void MojoAudioOutputStream::OnStreamError(int stream_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(deleter_callback_); - std::move(deleter_callback_).Run(/*had_error*/ true); // Deletes |this|. + client_->OnError(); + OnError(); } -void MojoAudioOutputStream::StreamConnectionLost() { +void MojoAudioOutputStream::OnError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(deleter_callback_); - std::move(deleter_callback_).Run(/*had_error*/ false); // Deletes |this|. + std::move(deleter_callback_).Run(); // Deletes |this|. } } // namespace media
diff --git a/media/mojo/services/mojo_audio_output_stream.h b/media/mojo/services/mojo_audio_output_stream.h index d4958dda..2170526 100644 --- a/media/mojo/services/mojo_audio_output_stream.h +++ b/media/mojo/services/mojo_audio_output_stream.h
@@ -23,22 +23,21 @@ public AudioOutputDelegate::EventHandler { public: using StreamCreatedCallback = - base::OnceCallback<void(mojom::AudioOutputStreamPtr, - media::mojom::AudioDataPipePtr)>; + mojom::AudioOutputStreamProvider::AcquireCallback; using CreateDelegateCallback = base::OnceCallback<std::unique_ptr<AudioOutputDelegate>( AudioOutputDelegate::EventHandler*)>; - using DeleterCallback = base::OnceCallback<void(bool)>; // |create_delegate_callback| is used to obtain an AudioOutputDelegate for the // stream in the constructor. |stream_created_callback| is called when the // stream has been initialized. |deleter_callback| is called when this class - // should be removed (stream ended/error). Its argument indicates if an error - // was encountered (false indicates that the remote end closed the stream). - // |deleter_callback| is required to destroy |this| synchronously. - MojoAudioOutputStream(CreateDelegateCallback create_delegate_callback, + // should be removed (stream ended/error). |deleter_callback| is required to + // destroy |this| synchronously. + MojoAudioOutputStream(mojom::AudioOutputStreamRequest request, + mojom::AudioOutputStreamClientPtr client, + CreateDelegateCallback create_delegate_callback, StreamCreatedCallback stream_created_callback, - DeleterCallback deleter_callback); + base::OnceClosure deleter_callback); ~MojoAudioOutputStream() override; @@ -55,13 +54,15 @@ std::unique_ptr<base::CancelableSyncSocket> foreign_socket) override; void OnStreamError(int stream_id) override; - void StreamConnectionLost(); + // Closes connection to client and notifies owner. + void OnError(); SEQUENCE_CHECKER(sequence_checker_); StreamCreatedCallback stream_created_callback_; - DeleterCallback deleter_callback_; + base::OnceClosure deleter_callback_; mojo::Binding<AudioOutputStream> binding_; + mojom::AudioOutputStreamClientPtr client_; std::unique_ptr<AudioOutputDelegate> delegate_; base::WeakPtrFactory<MojoAudioOutputStream> weak_factory_;
diff --git a/media/mojo/services/mojo_audio_output_stream_provider.cc b/media/mojo/services/mojo_audio_output_stream_provider.cc index 74ccb4a..32e7b7f 100644 --- a/media/mojo/services/mojo_audio_output_stream_provider.cc +++ b/media/mojo/services/mojo_audio_output_stream_provider.cc
@@ -23,9 +23,8 @@ observer_binding_(observer_.get()) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Unretained is safe since |this| owns |binding_|. - binding_.set_connection_error_handler( - base::BindOnce(&MojoAudioOutputStreamProvider::CleanUp, - base::Unretained(this), /*had_error*/ false)); + binding_.set_connection_error_handler(base::Bind( + &MojoAudioOutputStreamProvider::OnError, base::Unretained(this))); DCHECK(create_delegate_callback_); DCHECK(deleter_callback_); } @@ -35,8 +34,10 @@ } void MojoAudioOutputStreamProvider::Acquire( + mojom::AudioOutputStreamRequest stream_request, + mojom::AudioOutputStreamClientPtr client, const AudioParameters& params, - mojom::AudioOutputStreamProviderClientPtr provider_client) { + AcquireCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); #if !defined(OS_ANDROID) if (params.IsBitstreamFormat()) { @@ -52,31 +53,29 @@ return; } - provider_client_ = std::move(provider_client); - mojom::AudioOutputStreamObserverPtr observer_ptr; observer_binding_.Bind(mojo::MakeRequest(&observer_ptr)); // Unretained is safe since |this| owns |audio_output_|. - audio_output_.emplace( - base::BindOnce(std::move(create_delegate_callback_), params, - std::move(observer_ptr)), - base::BindOnce(&mojom::AudioOutputStreamProviderClient::Created, - base::Unretained(provider_client_.get())), - base::BindOnce(&MojoAudioOutputStreamProvider::CleanUp, - base::Unretained(this))); + audio_output_.emplace(std::move(stream_request), std::move(client), + base::BindOnce(std::move(create_delegate_callback_), + params, std::move(observer_ptr)), + std::move(callback), + base::BindOnce(&MojoAudioOutputStreamProvider::OnError, + base::Unretained(this))); } -void MojoAudioOutputStreamProvider::CleanUp(bool had_error) { - if (had_error) { - provider_client_.ResetWithReason( - mojom::AudioOutputStreamProviderClient::kPlatformErrorDisconnectReason, - std::string()); - } +void MojoAudioOutputStreamProvider::OnError() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Deletes |this|: std::move(deleter_callback_).Run(this); } void MojoAudioOutputStreamProvider::BadMessage(const std::string& error) { mojo::ReportBadMessage(error); + if (binding_.is_bound()) + binding_.Unbind(); + if (observer_binding_.is_bound()) + observer_binding_.Unbind(); std::move(deleter_callback_).Run(this); // deletes |this|. }
diff --git a/media/mojo/services/mojo_audio_output_stream_provider.h b/media/mojo/services/mojo_audio_output_stream_provider.h index 0d580f3..f642571b 100644 --- a/media/mojo/services/mojo_audio_output_stream_provider.h +++ b/media/mojo/services/mojo_audio_output_stream_provider.h
@@ -42,25 +42,25 @@ private: // mojom::AudioOutputStreamProvider implementation. - void Acquire( - const AudioParameters& params, - mojom::AudioOutputStreamProviderClientPtr provider_client) override; + void Acquire(mojom::AudioOutputStreamRequest stream_request, + mojom::AudioOutputStreamClientPtr client, + const AudioParameters& params, + AcquireCallback acquire_callback) override; // Called when |audio_output_| had an error. - void CleanUp(bool had_error); + void OnError(); // Closes mojo connections, reports a bad message, and self-destructs. void BadMessage(const std::string& error); SEQUENCE_CHECKER(sequence_checker_); + base::Optional<MojoAudioOutputStream> audio_output_; mojo::Binding<AudioOutputStreamProvider> binding_; CreateDelegateCallback create_delegate_callback_; DeleterCallback deleter_callback_; std::unique_ptr<mojom::AudioOutputStreamObserver> observer_; mojo::Binding<mojom::AudioOutputStreamObserver> observer_binding_; - base::Optional<MojoAudioOutputStream> audio_output_; - mojom::AudioOutputStreamProviderClientPtr provider_client_; DISALLOW_COPY_AND_ASSIGN(MojoAudioOutputStreamProvider); };
diff --git a/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc b/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc index e559976..49edfa9 100644 --- a/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc +++ b/media/mojo/services/mojo_audio_output_stream_provider_unittest.cc
@@ -31,6 +31,8 @@ using MockDeleter = base::MockCallback< base::OnceCallback<void(mojom::AudioOutputStreamProvider*)>>; +void FakeAcquireCallback(mojom::AudioDataPipePtr data_pipe) {} + class FakeObserver : public mojom::AudioOutputStreamObserver { public: FakeObserver() = default; @@ -81,22 +83,26 @@ mojo::MakeRequest(&provider_ptr), base::BindOnce(&CreateFakeDelegate), deleter.Get(), std::make_unique<FakeObserver>()); - mojom::AudioOutputStreamProviderClientPtr client_1; - mojo::MakeRequest(&client_1); - provider_ptr->Acquire(media::AudioParameters::UnavailableDeviceParams(), - std::move(client_1)); + mojom::AudioOutputStreamPtr stream_1; + mojom::AudioOutputStreamClientPtr client_1; + mojom::AudioOutputStreamClientRequest client_request_1 = + mojo::MakeRequest(&client_1); - mojom::AudioOutputStreamProviderClientPtr client_2; - mojo::MakeRequest(&client_2); - provider_ptr->Acquire(media::AudioParameters::UnavailableDeviceParams(), - std::move(client_2)); + mojom::AudioOutputStreamPtr stream_2; + mojom::AudioOutputStreamClientPtr client_2; + mojom::AudioOutputStreamClientRequest client_request_2 = + mojo::MakeRequest(&client_2); + provider_ptr->Acquire(mojo::MakeRequest(&stream_1), std::move(client_1), + media::AudioParameters::UnavailableDeviceParams(), + base::BindOnce(&FakeAcquireCallback)); + provider_ptr->Acquire(mojo::MakeRequest(&stream_2), std::move(client_2), + media::AudioParameters::UnavailableDeviceParams(), + base::BindOnce(&FakeAcquireCallback)); EXPECT_CALL(deleter, Run(provider)).WillOnce(DeleteArg<0>()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(got_bad_message); Mock::VerifyAndClear(&deleter); - - mojo::edk::SetDefaultProcessErrorCallback(mojo::edk::ProcessErrorCallback()); } TEST(MojoAudioOutputStreamProviderTest, @@ -118,9 +124,12 @@ mojo::MakeRequest(&provider_ptr), base::BindOnce(&CreateFakeDelegate), deleter.Get(), std::make_unique<FakeObserver>()); - mojom::AudioOutputStreamProviderClientPtr client; - mojo::MakeRequest(&client); - provider_ptr->Acquire(params, std::move(client)); + mojom::AudioOutputStreamPtr stream; + mojom::AudioOutputStreamClientPtr client; + mojom::AudioOutputStreamClientRequest client_request = + mojo::MakeRequest(&client); + provider_ptr->Acquire(mojo::MakeRequest(&stream), std::move(client), params, + base::BindOnce(&FakeAcquireCallback)); #if defined(OS_ANDROID) base::RunLoop().RunUntilIdle(); @@ -135,7 +144,6 @@ EXPECT_TRUE(got_bad_message); Mock::VerifyAndClear(&deleter); #endif - mojo::edk::SetDefaultProcessErrorCallback(mojo::edk::ProcessErrorCallback()); } } // namespace media
diff --git a/media/mojo/services/mojo_audio_output_stream_unittest.cc b/media/mojo/services/mojo_audio_output_stream_unittest.cc index 9df6d45..efd1619 100644 --- a/media/mojo/services/mojo_audio_output_stream_unittest.cc +++ b/media/mojo/services/mojo_audio_output_stream_unittest.cc
@@ -11,7 +11,6 @@ #include "base/run_loop.h" #include "base/sync_socket.h" #include "media/audio/audio_output_controller.h" -#include "mojo/public/cpp/system/message_pipe.h" #include "mojo/public/cpp/system/platform_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,14 +88,14 @@ class MockDeleter { public: - MOCK_METHOD1(Finished, void(bool)); + MOCK_METHOD0(Finished, void()); }; -class MockClient { +class MockClient : public mojom::AudioOutputStreamClient { public: MockClient() = default; - void Initialize(mojom::AudioDataPipePtr data_pipe) { + void Initialized(mojom::AudioDataPipePtr data_pipe) { ASSERT_TRUE(data_pipe->shared_memory.is_valid()); ASSERT_TRUE(data_pipe->socket.is_valid()); @@ -122,6 +121,8 @@ MOCK_METHOD0(GotNotification, void()); + MOCK_METHOD0(OnError, void()); + private: std::unique_ptr<base::SharedMemory> buffer_; std::unique_ptr<base::CancelableSyncSocket> socket_; @@ -132,9 +133,9 @@ return nullptr; } -void NotCalled(mojom::AudioOutputStreamPtr, mojom::AudioDataPipePtr) { - ADD_FAILURE() << "The StreamCreated callback was called despite the test " - "expecting it not to."; +void NotCalled(mojom::AudioDataPipePtr data_pipe) { + EXPECT_TRUE(false) << "The StreamCreated callback was called despite the " + "test expecting it not to."; } } // namespace @@ -142,30 +143,23 @@ class MojoAudioOutputStreamTest : public Test { public: MojoAudioOutputStreamTest() - : foreign_socket_(std::make_unique<TestCancelableSyncSocket>()) {} + : foreign_socket_(std::make_unique<TestCancelableSyncSocket>()), + client_binding_(&client_, mojo::MakeRequest(&client_ptr_)) {} AudioOutputStreamPtr CreateAudioOutput() { - mojom::AudioOutputStreamPtr p; - pending_stream_request_ = mojo::MakeRequest(&p); + AudioOutputStreamPtr p; ExpectDelegateCreation(); impl_ = std::make_unique<MojoAudioOutputStream>( + mojo::MakeRequest(&p), std::move(client_ptr_), base::BindOnce(&MockDelegateFactory::CreateDelegate, base::Unretained(&mock_delegate_factory_)), - base::BindOnce(&MojoAudioOutputStreamTest::CreatedStream, - base::Unretained(this)), + base::BindOnce(&MockClient::Initialized, base::Unretained(&client_)), base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_))); + EXPECT_TRUE(p.is_bound()); return p; } protected: - void CreatedStream(mojom::AudioOutputStreamPtr stream, - mojom::AudioDataPipePtr data_pipe) { - EXPECT_EQ(mojo::FuseMessagePipes(pending_stream_request_.PassMessagePipe(), - stream.PassInterface().PassHandle()), - MOJO_RESULT_OK); - client_.Initialize(std::move(data_pipe)); - } - void ExpectDelegateCreation() { delegate_ = new StrictMock<MockDelegate>(); mock_delegate_factory_.PrepareDelegateForCreation( @@ -186,51 +180,45 @@ StrictMock<MockDelegateFactory> mock_delegate_factory_; StrictMock<MockDeleter> deleter_; StrictMock<MockClient> client_; - mojom::AudioOutputStreamRequest pending_stream_request_; + media::mojom::AudioOutputStreamClientPtr client_ptr_; + mojo::Binding<media::mojom::AudioOutputStreamClient> client_binding_; std::unique_ptr<MojoAudioOutputStream> impl_; }; TEST_F(MojoAudioOutputStreamTest, NoDelegate_SignalsError) { + bool deleter_called = false; + EXPECT_CALL(client_, OnError()).Times(1); mojom::AudioOutputStreamPtr stream_ptr; MojoAudioOutputStream stream( + mojo::MakeRequest(&stream_ptr), std::move(client_ptr_), base::BindOnce(&CreateNoDelegate), base::BindOnce(&NotCalled), - base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_))); - EXPECT_CALL(deleter_, Finished(true)); + base::BindOnce([](bool* p) { *p = true; }, &deleter_called)); + EXPECT_FALSE(deleter_called) + << "Stream shouldn't call the deleter from its constructor."; base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(deleter_called); } TEST_F(MojoAudioOutputStreamTest, Play_Plays) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - - EXPECT_CALL(client_, GotNotification()); EXPECT_CALL(*delegate_, OnPlayStream()); - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); audio_output_ptr->Play(); base::RunLoop().RunUntilIdle(); } TEST_F(MojoAudioOutputStreamTest, Pause_Pauses) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - - EXPECT_CALL(client_, GotNotification()); EXPECT_CALL(*delegate_, OnPauseStream()); - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); audio_output_ptr->Pause(); base::RunLoop().RunUntilIdle(); } TEST_F(MojoAudioOutputStreamTest, SetVolume_SetsVolume) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - - EXPECT_CALL(client_, GotNotification()); EXPECT_CALL(*delegate_, OnSetVolume(kNewVolume)); - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); audio_output_ptr->SetVolume(kNewVolume); base::RunLoop().RunUntilIdle(); } @@ -265,11 +253,9 @@ TEST_F(MojoAudioOutputStreamTest, SetVolumeTooLarge_Error) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - EXPECT_CALL(deleter_, Finished(true)); - EXPECT_CALL(client_, GotNotification()); + EXPECT_CALL(deleter_, Finished()); + EXPECT_CALL(client_, OnError()).Times(1); - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); audio_output_ptr->SetVolume(15); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClear(&deleter_); @@ -277,11 +263,9 @@ TEST_F(MojoAudioOutputStreamTest, SetVolumeNegative_Error) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - EXPECT_CALL(deleter_, Finished(true)); - EXPECT_CALL(client_, GotNotification()); + EXPECT_CALL(deleter_, Finished()); + EXPECT_CALL(client_, OnError()).Times(1); - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); audio_output_ptr->SetVolume(-0.5); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClear(&deleter_); @@ -289,7 +273,8 @@ TEST_F(MojoAudioOutputStreamTest, DelegateErrorBeforeCreated_PropagatesError) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - EXPECT_CALL(deleter_, Finished(true)); + EXPECT_CALL(deleter_, Finished()); + EXPECT_CALL(client_, OnError()).Times(1); ASSERT_NE(nullptr, delegate_event_handler_); delegate_event_handler_->OnStreamError(kStreamId); @@ -301,7 +286,8 @@ TEST_F(MojoAudioOutputStreamTest, DelegateErrorAfterCreated_PropagatesError) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); EXPECT_CALL(client_, GotNotification()); - EXPECT_CALL(deleter_, Finished(true)); + EXPECT_CALL(deleter_, Finished()); + EXPECT_CALL(client_, OnError()).Times(1); base::RunLoop().RunUntilIdle(); ASSERT_NE(nullptr, delegate_event_handler_); @@ -314,14 +300,9 @@ Mock::VerifyAndClear(&deleter_); } -TEST_F(MojoAudioOutputStreamTest, RemoteEndGone_CallsDeleter) { +TEST_F(MojoAudioOutputStreamTest, RemoteEndGone_Error) { AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); - - EXPECT_CALL(client_, GotNotification()); - EXPECT_CALL(deleter_, Finished(false)); - - delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, - std::move(foreign_socket_)); + EXPECT_CALL(deleter_, Finished()); audio_output_ptr.reset(); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClear(&deleter_);
diff --git a/media/renderers/BUILD.gn b/media/renderers/BUILD.gn index 10b5d8f..5002ccf 100644 --- a/media/renderers/BUILD.gn +++ b/media/renderers/BUILD.gn
@@ -15,6 +15,8 @@ "audio_renderer_impl.h", "default_renderer_factory.cc", "default_renderer_factory.h", + "flinging_renderer_client_factory.cc", + "flinging_renderer_client_factory.h", "paint_canvas_video_renderer.cc", "paint_canvas_video_renderer.h", "remote_playback_client_wrapper.h",
diff --git a/media/renderers/flinging_renderer_client_factory.cc b/media/renderers/flinging_renderer_client_factory.cc new file mode 100644 index 0000000..0343b95 --- /dev/null +++ b/media/renderers/flinging_renderer_client_factory.cc
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/renderers/flinging_renderer_client_factory.h" + +#include "base/logging.h" +#include "media/base/overlay_info.h" + +namespace media { + +FlingingRendererClientFactory::FlingingRendererClientFactory( + std::unique_ptr<RendererFactory> mojo_flinging_factory, + std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client) + : mojo_flinging_factory_(std::move(mojo_flinging_factory)), + remote_playback_client_(std::move(remote_playback_client)) {} + +FlingingRendererClientFactory::~FlingingRendererClientFactory() = default; + +std::unique_ptr<Renderer> FlingingRendererClientFactory::CreateRenderer( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const scoped_refptr<base::TaskRunner>& worker_task_runner, + AudioRendererSink* audio_renderer_sink, + VideoRendererSink* video_renderer_sink, + const RequestOverlayInfoCB& request_overlay_info_cb, + const gfx::ColorSpace& target_color_space) { + DCHECK(IsFlingingActive()); + return mojo_flinging_factory_->CreateRenderer( + media_task_runner, worker_task_runner, audio_renderer_sink, + video_renderer_sink, request_overlay_info_cb, target_color_space); +} + +std::string FlingingRendererClientFactory::GetActivePresentationId() { + return remote_playback_client_->GetActivePresentationId(); +} + +bool FlingingRendererClientFactory::IsFlingingActive() { + return !GetActivePresentationId().empty(); +} + +} // namespace media
diff --git a/media/renderers/flinging_renderer_client_factory.h b/media/renderers/flinging_renderer_client_factory.h new file mode 100644 index 0000000..73a28a5 --- /dev/null +++ b/media/renderers/flinging_renderer_client_factory.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_ +#define MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_ + +#include "media/base/media_export.h" +#include "media/base/renderer_factory.h" +#include "media/renderers/remote_playback_client_wrapper.h" + +namespace media { + +// Creates a renderer for media flinging. +// The FRCF uses a MojoRendererFactory to create a FlingingRenderer in the +// browser process. The actual renderer returned by the FRCF is a MojoRenderer +// directly (as opposed to a dedicated FlingingRendererClient), because all the +// renderer needs to do is forward calls to the FlingingRenderer in the browser. +class MEDIA_EXPORT FlingingRendererClientFactory : public RendererFactory { + public: + // |mojo_flinging_factory| should be created using + // HostedRendererType::kFlinging, and GetActivePresentationId() + // should be given to it through SetGetTypeSpecificIdCB(). + FlingingRendererClientFactory( + std::unique_ptr<RendererFactory> mojo_flinging_factory, + std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client); + ~FlingingRendererClientFactory() override; + + std::unique_ptr<Renderer> CreateRenderer( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const scoped_refptr<base::TaskRunner>& worker_task_runner, + AudioRendererSink* audio_renderer_sink, + VideoRendererSink* video_renderer_sink, + const RequestOverlayInfoCB& request_overlay_info_cb, + const gfx::ColorSpace& target_color_space) override; + + // Returns whether media flinging has started, based off of whether the + // |remote_playback_client_| has a presentation ID or not. Called by + // RendererFactorySelector to determine when to create a FlingingRenderer. + bool IsFlingingActive(); + + // Used by the |mojo_flinging_factory_| to retrieve the latest presentation ID + // when CreateRenderer() is called. + std::string GetActivePresentationId(); + + private: + std::unique_ptr<RendererFactory> mojo_flinging_factory_; + std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client_; + + DISALLOW_COPY_AND_ASSIGN(FlingingRendererClientFactory); +}; + +} // namespace media + +#endif // MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_
diff --git a/media/test/data/multiple_cdm_types.html b/media/test/data/multiple_cdm_types.html index ad313ea6..84a11fb 100644 --- a/media/test/data/multiple_cdm_types.html +++ b/media/test/data/multiple_cdm_types.html
@@ -79,7 +79,9 @@ session3 = session; log('Crash session2'); return session.update(crashJwkSet); - }).then(function() { + }).finally(function() { + // Due to the crash, the update() above could resolve or reject. + // So use "finally" so that we continue the test regardless. log('Session2 crashed'); return session2.closed; }).then(function() {
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index a6f4b27..21546bb 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -692,13 +692,13 @@ } void SetChannelID(std::unique_ptr<ChannelID> channel_id) override {} void DeleteChannelID(const std::string& server_identifier, - const base::Closure& completion_callback) override {} + base::OnceClosure completion_callback) override {} void DeleteForDomainsCreatedBetween( const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& completion_callback) override {} - void DeleteAll(const base::Closure& completion_callback) override {} + base::OnceClosure completion_callback) override {} + void DeleteAll(base::OnceClosure completion_callback) override {} void GetAllChannelIDs(const GetChannelIDListCallback& callback) override {} int GetChannelIDCount() override { return 0; } void SetForceKeepSessionState() override {} @@ -719,13 +719,13 @@ } void SetChannelID(std::unique_ptr<ChannelID> channel_id) override {} void DeleteChannelID(const std::string& server_identifier, - const base::Closure& completion_callback) override {} + base::OnceClosure completion_callback) override {} void DeleteForDomainsCreatedBetween( const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& completion_callback) override {} - void DeleteAll(const base::Closure& completion_callback) override {} + base::OnceClosure completion_callback) override {} + void DeleteAll(base::OnceClosure completion_callback) override {} void GetAllChannelIDs(const GetChannelIDListCallback& callback) override {} int GetChannelIDCount() override { return 0; } void SetForceKeepSessionState() override {}
diff --git a/net/ssl/channel_id_store.h b/net/ssl/channel_id_store.h index da4d195c..8e8e5c27 100644 --- a/net/ssl/channel_id_store.h +++ b/net/ssl/channel_id_store.h
@@ -53,10 +53,11 @@ typedef std::list<ChannelID> ChannelIDList; - typedef base::Callback< + typedef base::RepeatingCallback< void(int, const std::string&, std::unique_ptr<crypto::ECPrivateKey>)> GetChannelIDCallback; - typedef base::Callback<void(const ChannelIDList&)> GetChannelIDListCallback; + typedef base::RepeatingCallback<void(const ChannelIDList&)> + GetChannelIDListCallback; virtual ~ChannelIDStore(); @@ -74,9 +75,8 @@ virtual void SetChannelID(std::unique_ptr<ChannelID> channel_id) = 0; // Removes a keypair from the store. - virtual void DeleteChannelID( - const std::string& server_identifier, - const base::Closure& completion_callback) = 0; + virtual void DeleteChannelID(const std::string& server_identifier, + base::OnceClosure completion_callback) = 0; // Deletes the channel ID keypairs that have a creation_date greater than // or equal to |delete_begin| and less than |delete_end| and whose server @@ -86,10 +86,10 @@ const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& completion_callback) = 0; + base::OnceClosure completion_callback) = 0; // Removes all channel ID keypairs from the store. - virtual void DeleteAll(const base::Closure& completion_callback) = 0; + virtual void DeleteAll(base::OnceClosure completion_callback) = 0; // Returns all channel ID keypairs. virtual void GetAllChannelIDs(const GetChannelIDListCallback& callback) = 0;
diff --git a/net/ssl/default_channel_id_store.cc b/net/ssl/default_channel_id_store.cc index 34f656a..218d13f 100644 --- a/net/ssl/default_channel_id_store.cc +++ b/net/ssl/default_channel_id_store.cc
@@ -33,15 +33,15 @@ virtual void Run(DefaultChannelIDStore* store) = 0; protected: - void InvokeCallback(base::Closure callback) const; + void InvokeCallback(base::OnceClosure callback) const; }; DefaultChannelIDStore::Task::~Task() = default; void DefaultChannelIDStore::Task::InvokeCallback( - base::Closure callback) const { + base::OnceClosure callback) const { if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } // -------------------------------------------------------------------------- @@ -75,8 +75,8 @@ GetChannelIDCallback()); DCHECK(err != ERR_IO_PENDING); - InvokeCallback(base::Bind(callback_, err, server_identifier_, - base::Passed(std::move(key_result)))); + InvokeCallback(base::BindOnce(callback_, err, server_identifier_, + std::move(key_result))); } // -------------------------------------------------------------------------- @@ -109,22 +109,19 @@ : public DefaultChannelIDStore::Task { public: DeleteChannelIDTask(const std::string& server_identifier, - const base::Closure& callback); + base::OnceClosure callback); ~DeleteChannelIDTask() override; void Run(DefaultChannelIDStore* store) override; private: std::string server_identifier_; - base::Closure callback_; + base::OnceClosure callback_; }; -DefaultChannelIDStore::DeleteChannelIDTask:: - DeleteChannelIDTask( - const std::string& server_identifier, - const base::Closure& callback) - : server_identifier_(server_identifier), - callback_(callback) { -} +DefaultChannelIDStore::DeleteChannelIDTask::DeleteChannelIDTask( + const std::string& server_identifier, + base::OnceClosure callback) + : server_identifier_(server_identifier), callback_(std::move(callback)) {} DefaultChannelIDStore::DeleteChannelIDTask::~DeleteChannelIDTask() = default; @@ -132,7 +129,7 @@ DefaultChannelIDStore* store) { store->SyncDeleteChannelID(server_identifier_); - InvokeCallback(callback_); + InvokeCallback(std::move(callback_)); } // -------------------------------------------------------------------------- @@ -144,7 +141,7 @@ const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& callback); + base::OnceClosure callback); ~DeleteForDomainsCreatedBetweenTask() override; void Run(DefaultChannelIDStore* store) override; @@ -152,7 +149,7 @@ const base::Callback<bool(const std::string&)> domain_predicate_; base::Time delete_begin_; base::Time delete_end_; - base::Closure callback_; + base::OnceClosure callback_; }; DefaultChannelIDStore::DeleteForDomainsCreatedBetweenTask:: @@ -160,11 +157,11 @@ const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& callback) + base::OnceClosure callback) : domain_predicate_(domain_predicate), delete_begin_(delete_begin), delete_end_(delete_end), - callback_(callback) {} + callback_(std::move(callback)) {} DefaultChannelIDStore::DeleteForDomainsCreatedBetweenTask:: ~DeleteForDomainsCreatedBetweenTask() = default; @@ -174,7 +171,7 @@ store->SyncDeleteForDomainsCreatedBetween(domain_predicate_, delete_begin_, delete_end_); - InvokeCallback(callback_); + InvokeCallback(std::move(callback_)); } // -------------------------------------------------------------------------- @@ -203,7 +200,7 @@ ChannelIDList key_list; store->SyncGetAllChannelIDs(&key_list); - InvokeCallback(base::Bind(callback_, key_list)); + InvokeCallback(base::BindOnce(std::move(callback_), key_list)); } // -------------------------------------------------------------------------- @@ -248,24 +245,23 @@ void DefaultChannelIDStore::DeleteChannelID( const std::string& server_identifier, - const base::Closure& callback) { + base::OnceClosure callback) { RunOrEnqueueTask(std::unique_ptr<Task>( - new DeleteChannelIDTask(server_identifier, callback))); + new DeleteChannelIDTask(server_identifier, std::move(callback)))); } void DefaultChannelIDStore::DeleteForDomainsCreatedBetween( const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& callback) { + base::OnceClosure callback) { RunOrEnqueueTask(std::unique_ptr<Task>(new DeleteForDomainsCreatedBetweenTask( - domain_predicate, delete_begin, delete_end, callback))); + domain_predicate, delete_begin, delete_end, std::move(callback)))); } -void DefaultChannelIDStore::DeleteAll( - const base::Closure& callback) { +void DefaultChannelIDStore::DeleteAll(base::OnceClosure callback) { DeleteForDomainsCreatedBetween(base::Bind(&AllDomainsPredicate), base::Time(), - base::Time(), callback); + base::Time(), std::move(callback)); } void DefaultChannelIDStore::GetAllChannelIDs(
diff --git a/net/ssl/default_channel_id_store.h b/net/ssl/default_channel_id_store.h index bc5ab07..da94d78 100644 --- a/net/ssl/default_channel_id_store.h +++ b/net/ssl/default_channel_id_store.h
@@ -52,13 +52,13 @@ const GetChannelIDCallback& callback) override; void SetChannelID(std::unique_ptr<ChannelID> channel_id) override; void DeleteChannelID(const std::string& server_identifier, - const base::Closure& callback) override; + base::OnceClosure callback) override; void DeleteForDomainsCreatedBetween( const base::Callback<bool(const std::string&)>& domain_predicate, base::Time delete_begin, base::Time delete_end, - const base::Closure& callback) override; - void DeleteAll(const base::Closure& callback) override; + base::OnceClosure callback) override; + void DeleteAll(base::OnceClosure callback) override; void GetAllChannelIDs(const GetChannelIDListCallback& callback) override; void Flush() override; int GetChannelIDCount() override;
diff --git a/services/audio/output_stream.cc b/services/audio/output_stream.cc index f1bbfbb..02f7f24 100644 --- a/services/audio/output_stream.cc +++ b/services/audio/output_stream.cc
@@ -22,6 +22,7 @@ CreatedCallback created_callback, DeleteCallback delete_callback, media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamClientPtr client, media::mojom::AudioOutputStreamObserverAssociatedPtr observer, media::mojom::AudioLogPtr log, media::AudioManager* audio_manager, @@ -32,6 +33,7 @@ : foreign_socket_(), delete_callback_(std::move(delete_callback)), binding_(this, std::move(stream_request)), + client_(std::move(client)), observer_(std::move(observer)), log_(media::mojom::ThreadSafeAudioLogPtr::Create(std::move(log))), coordinator_(coordinator), @@ -48,6 +50,7 @@ &reader_), weak_factory_(this) { DCHECK(binding_.is_bound()); + DCHECK(client_.is_bound()); DCHECK(observer_.is_bound()); DCHECK(created_callback); DCHECK(delete_callback_); @@ -57,6 +60,7 @@ base::RepeatingClosure error_handler = base::BindRepeating(&OutputStream::OnError, base::Unretained(this)); binding_.set_connection_error_handler(error_handler); + client_.set_connection_error_handler(error_handler); // We allow the observer to terminate the stream by closing the message pipe. observer_.set_connection_error_handler(std::move(error_handler)); @@ -178,10 +182,8 @@ void OutputStream::OnControllerError() { DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - // Only propagate platform errors to the observer. - observer_.ResetWithReason( - media::mojom::AudioOutputStreamObserver::kPlatformErrorDisconnectReason, - std::string()); + // Only propagate platform errors to the renderer. + client_->OnError(); log_->get()->OnError(); OnError(); }
diff --git a/services/audio/output_stream.h b/services/audio/output_stream.h index aa04feb..939854e 100644 --- a/services/audio/output_stream.h +++ b/services/audio/output_stream.h
@@ -48,6 +48,7 @@ OutputStream(CreatedCallback created_callback, DeleteCallback delete_callback, media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamClientPtr client, media::mojom::AudioOutputStreamObserverAssociatedPtr observer, media::mojom::AudioLogPtr log, media::AudioManager* audio_manager, @@ -81,6 +82,7 @@ base::CancelableSyncSocket foreign_socket_; DeleteCallback delete_callback_; mojo::Binding<AudioOutputStream> binding_; + media::mojom::AudioOutputStreamClientPtr client_; media::mojom::AudioOutputStreamObserverAssociatedPtr observer_; const scoped_refptr<media::mojom::ThreadSafeAudioLogPtr> log_; GroupCoordinator* const coordinator_;
diff --git a/services/audio/output_stream_unittest.cc b/services/audio/output_stream_unittest.cc index 9b8e82ec..5c40fd8 100644 --- a/services/audio/output_stream_unittest.cc +++ b/services/audio/output_stream_unittest.cc
@@ -52,7 +52,30 @@ DISALLOW_COPY_AND_ASSIGN(MockStream); }; -const uint32_t kNoDisconnectReason = 0; +class MockClient : public media::mojom::AudioOutputStreamClient { + public: + MockClient() : binding_(this) {} + + media::mojom::AudioOutputStreamClientPtr MakePtr() { + DCHECK(!binding_.is_bound()); + media::mojom::AudioOutputStreamClientPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + binding_.set_connection_error_handler(base::BindOnce( + &MockClient::BindingConnectionError, base::Unretained(this))); + return ptr; + } + + void CloseBinding() { binding_.Close(); } + + MOCK_METHOD0(OnError, void()); + + MOCK_METHOD0(BindingConnectionError, void()); + + private: + mojo::Binding<media::mojom::AudioOutputStreamClient> binding_; + + DISALLOW_COPY_AND_ASSIGN(MockClient); +}; class MockObserver : public media::mojom::AudioOutputStreamObserver { public: @@ -62,7 +85,7 @@ DCHECK(!binding_.is_bound()); media::mojom::AudioOutputStreamObserverAssociatedPtrInfo ptr_info; binding_.Bind(mojo::MakeRequest(&ptr_info)); - binding_.set_connection_error_with_reason_handler(base::BindOnce( + binding_.set_connection_error_handler(base::BindOnce( &MockObserver::BindingConnectionError, base::Unretained(this))); return ptr_info; } @@ -73,8 +96,7 @@ MOCK_METHOD0(DidStopPlaying, void()); MOCK_METHOD1(DidChangeAudibleState, void(bool)); - MOCK_METHOD2(BindingConnectionError, - void(uint32_t /*disconnect_reason*/, const std::string&)); + MOCK_METHOD0(BindingConnectionError, void()); private: mojo::AssociatedBinding<media::mojom::AudioOutputStreamObserver> binding_; @@ -125,14 +147,17 @@ media::mojom::AudioOutputStreamPtr CreateStream() { media::mojom::AudioOutputStreamPtr stream_ptr; stream_factory_ptr_->CreateOutputStream( - mojo::MakeRequest(&stream_ptr), observer_.MakePtrInfo(), log_.MakePtr(), - "", media::AudioParameters::UnavailableDeviceParams(), + mojo::MakeRequest(&stream_ptr), client_.MakePtr(), + observer_.MakePtrInfo(), log_.MakePtr(), "", + media::AudioParameters::UnavailableDeviceParams(), base::UnguessableToken::Create(), created_callback_.Get()); return stream_ptr; } media::MockAudioManager& audio_manager() { return audio_manager_; } + MockClient& client() { return client_; } + MockObserver& observer() { return observer_; } MockLog& log() { return log_; } @@ -149,6 +174,7 @@ StreamFactory stream_factory_; mojom::StreamFactoryPtr stream_factory_ptr_; mojo::Binding<mojom::StreamFactory> stream_factory_binding_; + StrictMock<MockClient> client_; StrictMock<MockObserver> observer_; NiceMock<MockLog> log_; StrictMock<MockCreatedCallback> created_callback_; @@ -177,7 +203,8 @@ EXPECT_CALL(env.log(), OnClosed()); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); stream_ptr.reset(); base::RunLoop().RunUntilIdle(); } @@ -201,11 +228,41 @@ Mock::VerifyAndClear(&env.created_callback()); EXPECT_CALL(mock_stream, Close()); + EXPECT_CALL(env.client(), BindingConnectionError()); env.observer().CloseBinding(); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClear(&mock_stream); + Mock::VerifyAndClear(&env.client()); +} + +TEST(AudioServiceOutputStreamTest, + ConstructStreamAndDestructClient_DestructsStream) { + TestEnvironment env; + MockStream mock_stream; + env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating( + [](media::AudioOutputStream* stream, const media::AudioParameters& params, + const std::string& device_id) { return stream; }, + &mock_stream)); + + EXPECT_CALL(env.created_callback(), Created(successfully_)); + EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); + EXPECT_CALL(mock_stream, SetVolume(1)); + + media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream(); + base::RunLoop().RunUntilIdle(); + Mock::VerifyAndClear(&mock_stream); + Mock::VerifyAndClear(&env.created_callback()); + + EXPECT_CALL(mock_stream, Close()); + EXPECT_CALL(env.observer(), BindingConnectionError()); + + env.client().CloseBinding(); + base::RunLoop().RunUntilIdle(); + + Mock::VerifyAndClear(&mock_stream); + Mock::VerifyAndClear(&env.observer()); } TEST(AudioServiceOutputStreamTest, @@ -227,12 +284,14 @@ Mock::VerifyAndClear(&env.created_callback()); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); stream_ptr.reset(); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClear(&mock_stream); + Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.observer()); } @@ -268,7 +327,8 @@ EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(env.observer(), DidChangeAudibleState(false)).Times(AtMost(1)); EXPECT_CALL(env.observer(), DidStopPlaying()).Times(AtMost(1)); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); stream_ptr.reset(); base::RunLoop().RunUntilIdle(); } @@ -310,7 +370,8 @@ Mock::VerifyAndClear(&env.observer()); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); stream_ptr.reset(); base::RunLoop().RunUntilIdle(); } @@ -340,7 +401,8 @@ Mock::VerifyAndClear(&mock_stream); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); stream_ptr.reset(); base::RunLoop().RunUntilIdle(); } @@ -363,7 +425,8 @@ Mock::VerifyAndClear(&env.created_callback()); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.bad_message_callback(), Run(_)); stream_ptr->SetVolume(-0.1); base::RunLoop().RunUntilIdle(); @@ -387,7 +450,8 @@ Mock::VerifyAndClear(&env.created_callback()); EXPECT_CALL(mock_stream, Close()); - EXPECT_CALL(env.observer(), BindingConnectionError(kNoDisconnectReason, _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.bad_message_callback(), Run(_)); stream_ptr->SetVolume(1.1); base::RunLoop().RunUntilIdle(); @@ -402,12 +466,12 @@ media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream(); EXPECT_CALL(env.created_callback(), Created(unsuccessfully_)); - EXPECT_CALL(env.observer(), - BindingConnectionError(media::mojom::AudioOutputStreamObserver:: - kPlatformErrorDisconnectReason, - _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.log(), OnError()); + EXPECT_CALL(env.client(), OnError()); + EXPECT_CALL(env.client(), BindingConnectionError()); base::RunLoop().RunUntilIdle(); + Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.observer()); } @@ -422,12 +486,12 @@ media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream(); EXPECT_CALL(env.created_callback(), Created(unsuccessfully_)); - EXPECT_CALL(env.observer(), - BindingConnectionError(media::mojom::AudioOutputStreamObserver:: - kPlatformErrorDisconnectReason, - _)); + EXPECT_CALL(env.observer(), BindingConnectionError()); + EXPECT_CALL(env.client(), OnError()); + EXPECT_CALL(env.client(), BindingConnectionError()); base::RunLoop().RunUntilIdle(); + Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.observer()); }
diff --git a/services/audio/public/mojom/stream_factory.mojom b/services/audio/public/mojom/stream_factory.mojom index 91bc545c8..9e9a6dcc 100644 --- a/services/audio/public/mojom/stream_factory.mojom +++ b/services/audio/public/mojom/stream_factory.mojom
@@ -50,6 +50,7 @@ // will later be used for muting streams or capturing them for loopback. CreateOutputStream( media.mojom.AudioOutputStream& stream, + media.mojom.AudioOutputStreamClient client, associated media.mojom.AudioOutputStreamObserver observer, media.mojom.AudioLog log, string device_id, media.mojom.AudioParameters params,
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc index cf1866a9..9c442ee6 100644 --- a/services/audio/stream_factory.cc +++ b/services/audio/stream_factory.cc
@@ -54,6 +54,7 @@ void StreamFactory::CreateOutputStream( media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamClientPtr client, media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info, media::mojom::AudioLogPtr log, const std::string& output_device_id, @@ -71,8 +72,9 @@ output_streams_.insert(std::make_unique<OutputStream>( std::move(created_callback), std::move(deleter_callback), - std::move(stream_request), std::move(observer), std::move(log), - audio_manager_, output_device_id, params, &coordinator_, group_id)); + std::move(stream_request), std::move(client), std::move(observer), + std::move(log), audio_manager_, output_device_id, params, &coordinator_, + group_id)); } void StreamFactory::BindMuter(mojom::LocalMuterAssociatedRequest request,
diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h index 185b0177..3ef6673 100644 --- a/services/audio/stream_factory.h +++ b/services/audio/stream_factory.h
@@ -65,6 +65,7 @@ void CreateOutputStream( media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamClientPtr client, media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info, media::mojom::AudioLogPtr log, const std::string& output_device_id,
diff --git a/services/device/media_transfer_protocol/mtp_device_manager.cc b/services/device/media_transfer_protocol/mtp_device_manager.cc index 4c28628..c7b49e3 100644 --- a/services/device/media_transfer_protocol/mtp_device_manager.cc +++ b/services/device/media_transfer_protocol/mtp_device_manager.cc
@@ -41,6 +41,36 @@ std::move(callback).Run(std::move(storage_info_ptr_list)); } +void GetStorageInfoCallbackWrapper( + mojom::MtpManager::GetStorageInfoCallback callback, + const mojom::MtpStorageInfo* storage_info) { + std::move(callback).Run(storage_info->Clone()); +} + +void GetStorageInfoFromDeviceCallbackWrapper( + mojom::MtpManager::GetStorageInfoFromDeviceCallback callback, + const mojom::MtpStorageInfo& storage_info, + bool error) { + std::move(callback).Run(storage_info.Clone(), error); +} + +void ReadDirectoryCallbackWrapper( + mojom::MtpManager::ReadDirectoryCallback callback, + const std::vector<mojom::MtpFileEntry>& file_entries, + bool has_more, + bool error) { + std::vector<mojom::MtpFileEntryPtr> files(file_entries.size()); + for (size_t i = 0; i < file_entries.size(); ++i) + files[i] = file_entries[i].Clone(); + std::move(callback).Run(std::move(files), has_more, error); +} + +void GetFileInfoCallbackWrapper(mojom::MtpManager::GetFileInfoCallback callback, + const mojom::MtpFileEntry& file_entry, + bool error) { + std::move(callback).Run(file_entry.Clone(), error); +} + } // namespace MtpDeviceManager::MtpDeviceManager() {} @@ -51,7 +81,6 @@ bindings_.AddBinding(this, std::move(request)); } -// mojom::MtpManager override. void MtpDeviceManager::EnumerateStoragesAndSetClient( mojom::MtpManagerClientAssociatedPtrInfo client, EnumerateStoragesAndSetClientCallback callback) { @@ -68,4 +97,98 @@ base::BindOnce(EnumerateStorageCallbackWrapper, std::move(callback))); } +void MtpDeviceManager::GetStorageInfo(const std::string& storage_name, + GetStorageInfoCallback callback) { + MediaTransferProtocolManager::GetInstance()->GetStorageInfo( + storage_name, + base::BindOnce(GetStorageInfoCallbackWrapper, std::move(callback))); +} + +void MtpDeviceManager::GetStorageInfoFromDevice( + const std::string& storage_name, + GetStorageInfoFromDeviceCallback callback) { + MediaTransferProtocolManager::GetInstance()->GetStorageInfoFromDevice( + storage_name, + base::Bind(GetStorageInfoFromDeviceCallbackWrapper, + base::AdaptCallbackForRepeating(std::move(callback)))); +} + +void MtpDeviceManager::OpenStorage(const std::string& storage_name, + const std::string& mode, + OpenStorageCallback callback) { + MediaTransferProtocolManager::GetInstance()->OpenStorage( + storage_name, mode, base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::CloseStorage(const std::string& storage_handle, + CloseStorageCallback callback) { + MediaTransferProtocolManager::GetInstance()->CloseStorage( + storage_handle, base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::CreateDirectory(const std::string& storage_handle, + uint32_t parent_id, + const std::string& directory_name, + CreateDirectoryCallback callback) { + MediaTransferProtocolManager::GetInstance()->CreateDirectory( + storage_handle, parent_id, directory_name, + base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::ReadDirectory(const std::string& storage_handle, + uint32_t file_id, + uint64_t max_size, + ReadDirectoryCallback callback) { + MediaTransferProtocolManager::GetInstance()->ReadDirectory( + storage_handle, file_id, max_size, + base::Bind(ReadDirectoryCallbackWrapper, + base::AdaptCallbackForRepeating(std::move(callback)))); +} + +void MtpDeviceManager::ReadFileChunk(const std::string& storage_handle, + uint32_t file_id, + uint32_t offset, + uint32_t count, + ReadFileChunkCallback callback) { + MediaTransferProtocolManager::GetInstance()->ReadFileChunk( + storage_handle, file_id, offset, count, + base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::GetFileInfo(const std::string& storage_handle, + uint32_t file_id, + GetFileInfoCallback callback) { + MediaTransferProtocolManager::GetInstance()->GetFileInfo( + storage_handle, file_id, + base::Bind(GetFileInfoCallbackWrapper, + base::AdaptCallbackForRepeating(std::move(callback)))); +} + +void MtpDeviceManager::RenameObject(const std::string& storage_handle, + uint32_t object_id, + const std::string& new_name, + RenameObjectCallback callback) { + MediaTransferProtocolManager::GetInstance()->RenameObject( + storage_handle, object_id, new_name, + base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::CopyFileFromLocal(const std::string& storage_handle, + int64_t source_file_descriptor, + uint32_t parent_id, + const std::string& file_name, + CopyFileFromLocalCallback callback) { + MediaTransferProtocolManager::GetInstance()->CopyFileFromLocal( + storage_handle, source_file_descriptor, parent_id, file_name, + base::AdaptCallbackForRepeating(std::move(callback))); +} + +void MtpDeviceManager::DeleteObject(const std::string& storage_handle, + uint32_t object_id, + DeleteObjectCallback callback) { + MediaTransferProtocolManager::GetInstance()->DeleteObject( + storage_handle, object_id, + base::AdaptCallbackForRepeating(std::move(callback))); +} + } // namespace device
diff --git a/services/device/media_transfer_protocol/mtp_device_manager.h b/services/device/media_transfer_protocol/mtp_device_manager.h index 6632621..11d9667 100644 --- a/services/device/media_transfer_protocol/mtp_device_manager.h +++ b/services/device/media_transfer_protocol/mtp_device_manager.h
@@ -32,6 +32,44 @@ void EnumerateStoragesAndSetClient( mojom::MtpManagerClientAssociatedPtrInfo client, EnumerateStoragesAndSetClientCallback callback) override; + void GetStorageInfo(const std::string& storage_name, + GetStorageInfoCallback callback) override; + void GetStorageInfoFromDevice( + const std::string& storage_name, + GetStorageInfoFromDeviceCallback callback) override; + void OpenStorage(const std::string& storage_name, + const std::string& mode, + OpenStorageCallback callback) override; + void CloseStorage(const std::string& storage_handle, + CloseStorageCallback callback) override; + void CreateDirectory(const std::string& storage_handle, + uint32_t parent_id, + const std::string& directory_name, + CreateDirectoryCallback callback) override; + void ReadDirectory(const std::string& storage_handle, + uint32_t file_id, + uint64_t max_size, + ReadDirectoryCallback callback) override; + void ReadFileChunk(const std::string& storage_handle, + uint32_t file_id, + uint32_t offset, + uint32_t count, + ReadFileChunkCallback callback) override; + void GetFileInfo(const std::string& storage_handle, + uint32_t file_id, + GetFileInfoCallback callback) override; + void RenameObject(const std::string& storage_handle, + uint32_t object_id, + const std::string& new_name, + RenameObjectCallback callback) override; + void CopyFileFromLocal(const std::string& storage_handle, + int64_t source_file_descriptor, + uint32_t parent_id, + const std::string& file_name, + CopyFileFromLocalCallback callback) override; + void DeleteObject(const std::string& storage_handle, + uint32_t object_id, + DeleteObjectCallback callback) override; private: std::unique_ptr<MediaTransferProtocolManager::Observer> observer_;
diff --git a/services/device/public/mojom/mtp_manager.mojom b/services/device/public/mojom/mtp_manager.mojom index dc98a5e..09527f52 100644 --- a/services/device/public/mojom/mtp_manager.mojom +++ b/services/device/public/mojom/mtp_manager.mojom
@@ -4,6 +4,7 @@ module device.mojom; +import "device/media_transfer_protocol/public/mojom/mtp_file_entry.mojom"; import "device/media_transfer_protocol/public/mojom/mtp_storage_info.mojom"; interface MtpManagerClient { @@ -21,4 +22,57 @@ // the client being set and storage updates being made. EnumerateStoragesAndSetClient(associated MtpManagerClient client) => (array<MtpStorageInfo> storages); + + // Gets storage metadata for |storage_name|. + GetStorageInfo(string storage_name) => + (MtpStorageInfo storage_info); + + // Reads the metadata of |storage_name| from device. + GetStorageInfoFromDevice(string storage_name) => + (MtpStorageInfo storage_info, bool error); + + // Opens |storage_name| in |mode|. + OpenStorage(string storage_name, string mode) => + (string storage_handle, bool error); + + // Closes |storage_handle|. + CloseStorage(string storage_handle) => (bool error); + + // Creates |directory_name| in |parent_id|. + CreateDirectory(string storage_handle, uint32 parent_id, + string directory_name) => (bool error); + + // Reads directory entries from |file_id| on |storage_handle|. + // |max_size| is a maximum number of files to be read. + ReadDirectory(string storage_handle, + uint32 file_id, uint64 max_size) => + (array<MtpFileEntry> file_entries, bool has_more, bool error); + + + // Reads file data from |file_id| on |storage_handle|. + // Reads |count| bytes of data starting at |offset|. + ReadFileChunk(string storage_handle, + uint32 file_id, + uint32 offset, + uint32 count) => (string data, bool error); + + // Gets the file metadata for |file_id| on |storage_handle|. + GetFileInfo(string storage_handle, + uint32 file_id) => + (MtpFileEntry file_entry, bool error); + + // Renames |object_id| to |new_name|. + RenameObject(string storage_handle, + uint32 object_id, + string new_name) => (bool error); + + // Copies the file from |source_file_descriptor| to |file_name| on + // |parent_id|. + CopyFileFromLocal(string storage_handle, + int64 source_file_descriptor, + uint32 parent_id, + string file_name) => (bool error); + + // Deletes |object_id|. + DeleteObject(string storage_handle, uint32 object_id) => (bool error); };
diff --git a/services/network/http_cache_data_remover.cc b/services/network/http_cache_data_remover.cc index 95c695bd..d3c8406 100644 --- a/services/network/http_cache_data_remover.cc +++ b/services/network/http_cache_data_remover.cc
@@ -20,7 +20,7 @@ namespace { -bool DoesUrlMatchFilter(mojom::ClearCacheUrlFilter_Type filter_type, +bool DoesUrlMatchFilter(mojom::ClearDataFilter_Type filter_type, const std::set<url::Origin>& origins, const std::set<std::string>& domains, const GURL& url) { @@ -34,13 +34,13 @@ bool found_origin = (origins.find(url::Origin::Create(url)) != origins.end()); return ((found_domain || found_origin) == - (filter_type == mojom::ClearCacheUrlFilter_Type::DELETE_MATCHES)); + (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES)); } } // namespace HttpCacheDataRemover::HttpCacheDataRemover( - mojom::ClearCacheUrlFilterPtr url_filter, + mojom::ClearDataFilterPtr url_filter, base::Time delete_begin, base::Time delete_end, HttpCacheDataRemoverCallback done_callback) @@ -69,7 +69,7 @@ // static. std::unique_ptr<HttpCacheDataRemover> HttpCacheDataRemover::CreateAndStart( net::URLRequestContext* url_request_context, - mojom::ClearCacheUrlFilterPtr url_filter, + mojom::ClearDataFilterPtr url_filter, base::Time delete_begin, base::Time delete_end, HttpCacheDataRemoverCallback done_callback) {
diff --git a/services/network/http_cache_data_remover.h b/services/network/http_cache_data_remover.h index 4108a5d..a8a32a6 100644 --- a/services/network/http_cache_data_remover.h +++ b/services/network/http_cache_data_remover.h
@@ -41,7 +41,7 @@ // interface and might be slow. static std::unique_ptr<HttpCacheDataRemover> CreateAndStart( net::URLRequestContext* url_request_context, - mojom::ClearCacheUrlFilterPtr url_filter, + mojom::ClearDataFilterPtr url_filter, base::Time delete_begin, base::Time delete_end, HttpCacheDataRemoverCallback done_callback); @@ -49,7 +49,7 @@ ~HttpCacheDataRemover(); private: - HttpCacheDataRemover(mojom::ClearCacheUrlFilterPtr url_filter, + HttpCacheDataRemover(mojom::ClearDataFilterPtr url_filter, base::Time delete_begin, base::Time delete_end, HttpCacheDataRemoverCallback done_callback);
diff --git a/services/network/http_cache_data_remover_unittest.cc b/services/network/http_cache_data_remover_unittest.cc index 4aba258..23dc86b 100644 --- a/services/network/http_cache_data_remover_unittest.cc +++ b/services/network/http_cache_data_remover_unittest.cc
@@ -104,7 +104,7 @@ static_cast<size_t>(backend_->GetEntryCount())); } - void RemoveData(mojom::ClearCacheUrlFilterPtr filter, + void RemoveData(mojom::ClearDataFilterPtr filter, base::Time start_time, base::Time end_time) { base::RunLoop run_loop; @@ -158,8 +158,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterDeleteByDomain) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::DELETE_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::DELETE_MATCHES; filter->domains.push_back("wikipedia.com"); filter->domains.push_back("google.com"); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -171,8 +171,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterKeepByDomain) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::KEEP_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES; filter->domains.push_back("wikipedia.com"); filter->domains.push_back("google.com"); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -184,8 +184,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterDeleteByOrigin) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::DELETE_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::DELETE_MATCHES; filter->origins.push_back(url::Origin::Create(GURL("http://www.google.com"))); filter->origins.push_back(url::Origin::Create(GURL("http://localhost:1234"))); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -195,8 +195,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterKeepByOrigin) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::KEEP_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES; filter->origins.push_back(url::Origin::Create(GURL("http://www.google.com"))); filter->origins.push_back(url::Origin::Create(GURL("http://localhost:1234"))); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -206,8 +206,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterDeleteByDomainAndOrigin) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::DELETE_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::DELETE_MATCHES; filter->domains.push_back("wikipedia.com"); filter->origins.push_back(url::Origin::Create(GURL("http://localhost:1234"))); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -218,8 +218,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterKeepByDomainAndOrigin) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::KEEP_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES; filter->domains.push_back("wikipedia.com"); filter->origins.push_back(url::Origin::Create(GURL("http://localhost:1234"))); RemoveData(std::move(filter), base::Time(), base::Time()); @@ -264,8 +264,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterDeleteByDomainAndDate) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::DELETE_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::DELETE_MATCHES; filter->domains.push_back("google.com"); filter->domains.push_back("wikipedia.com"); @@ -282,8 +282,8 @@ } TEST_F(HttpCacheDataRemoverTest, FilterKeepByDomainAndDate) { - mojom::ClearCacheUrlFilterPtr filter = mojom::ClearCacheUrlFilter::New(); - filter->type = mojom::ClearCacheUrlFilter_Type::KEEP_MATCHES; + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES; filter->domains.push_back("google.com"); filter->domains.push_back("wikipedia.com");
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index e5977c3..b3ebce1 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -98,6 +98,17 @@ } }; +// Predicate function to determine if the given |channel_id_server_id| matches +// the |filter_type| and |filter_domains| from a |mojom::ClearDataFilter|. +bool MatchesClearChannelIdFilter(mojom::ClearDataFilter_Type filter_type, + std::set<std::string> filter_domains, + const std::string& channel_id_server_id) { + bool found_domain = + filter_domains.find(channel_id_server_id) != filter_domains.end(); + return (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES) == + found_domain; +} + } // namespace constexpr bool NetworkContext::enable_resource_scheduler_; @@ -497,7 +508,7 @@ void NetworkContext::ClearHttpCache(base::Time start_time, base::Time end_time, - mojom::ClearCacheUrlFilterPtr filter, + mojom::ClearDataFilterPtr filter, ClearHttpCacheCallback callback) { // It's safe to use Unretained below as the HttpCacheDataRemover is owner by // |this| and guarantees it won't call its callback if deleted. @@ -522,6 +533,32 @@ std::move(callback).Run(); } +void NetworkContext::ClearChannelIds(base::Time start_time, + base::Time end_time, + mojom::ClearDataFilterPtr filter, + ClearChannelIdsCallback callback) { + base::RepeatingCallback<bool(const std::string& channel_id_server_id)> + filter_predicate; + if (filter) { + DCHECK(filter->origins.empty()) + << "Origin filtering not allowed in a ClearChannelIds request as " + "channel IDs are only keyed by domain."; + + std::set<std::string> filter_domains; + filter_domains.insert(filter->domains.begin(), filter->domains.end()); + filter_predicate = base::BindRepeating( + &MatchesClearChannelIdFilter, filter->type, std::move(filter_domains)); + } else { + filter_predicate = + base::BindRepeating([](const std::string&) { return true; }); + } + + url_request_context_->channel_id_service() + ->GetChannelIDStore() + ->DeleteForDomainsCreatedBetween(std::move(filter_predicate), start_time, + end_time, std::move(callback)); +} + void NetworkContext::SetNetworkConditions( const std::string& profile_id, mojom::NetworkConditionsPtr conditions) {
diff --git a/services/network/network_context.h b/services/network/network_context.h index f050d92..4728238c 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -117,8 +117,12 @@ base::OnceClosure completion_callback) override; void ClearHttpCache(base::Time start_time, base::Time end_time, - mojom::ClearCacheUrlFilterPtr filter, + mojom::ClearDataFilterPtr filter, ClearHttpCacheCallback callback) override; + void ClearChannelIds(base::Time start_time, + base::Time end_time, + mojom::ClearDataFilterPtr filter, + ClearChannelIdsCallback callback) override; void SetNetworkConditions(const std::string& profile_id, mojom::NetworkConditionsPtr conditions) override; void SetAcceptLanguage(const std::string& new_accept_language) override;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 07c6b188..1599bfe 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -18,6 +18,7 @@ #include "base/metrics/field_trial.h" #include "base/run_loop.h" #include "base/strings/string_split.h" +#include "base/test/gtest_util.h" #include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" @@ -44,6 +45,8 @@ #include "net/proxy_resolution/proxy_config.h" #include "net/proxy_resolution/proxy_info.h" #include "net/proxy_resolution/proxy_resolution_service.h" +#include "net/ssl/channel_id_service.h" +#include "net/ssl/channel_id_store.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/http_user_agent_settings.h" @@ -57,6 +60,7 @@ #include "services/network/public/mojom/proxy_config.mojom.h" #include "services/network/test/test_url_loader_client.h" #include "services/network/udp_socket_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/scheme_host_port.h" @@ -633,7 +637,7 @@ ASSERT_EQ(nullptr, cache); base::RunLoop run_loop; network_context->ClearHttpCache(base::Time(), base::Time(), - /*filter=*/nullptr, + nullptr /* filter */, base::BindOnce(run_loop.QuitClosure())); run_loop.Run(); } @@ -679,7 +683,7 @@ EXPECT_EQ(entry_urls.size(), static_cast<size_t>(backend->GetEntryCount())); base::RunLoop run_loop; network_context->ClearHttpCache(base::Time(), base::Time(), - /*filter=*/nullptr, + nullptr /* filter */, base::BindOnce(run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(0U, static_cast<size_t>(backend->GetEntryCount())); @@ -702,16 +706,176 @@ base::RunLoop run_loop; base::RepeatingClosure barrier_closure = base::BarrierClosure( - /*num_closures=*/kNumberOfClearCalls, run_loop.QuitClosure()); + kNumberOfClearCalls /* num_closures */, run_loop.QuitClosure()); for (int i = 0; i < kNumberOfClearCalls; i++) { network_context->ClearHttpCache(base::Time(), base::Time(), - /*filter=*/nullptr, + nullptr /* filter */, base::BindOnce(barrier_closure)); } run_loop.Run(); // If all the callbacks were invoked, we should terminate. } +TEST_F(NetworkContextTest, ClearChannelIds) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + net::ChannelIDStore* store = network_context->url_request_context() + ->channel_id_service() + ->GetChannelIDStore(); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "google.com", base::Time::FromDoubleT(123), + crypto::ECPrivateKey::Create())); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "chromium.org", base::Time::FromDoubleT(456), + crypto::ECPrivateKey::Create())); + + ASSERT_EQ(2, store->GetChannelIDCount()); + + base::RunLoop run_loop; + network_context->ClearChannelIds(base::Time(), base::Time(), + nullptr /* filter */, + base::BindOnce(run_loop.QuitClosure())); + run_loop.Run(); + + EXPECT_EQ(0, store->GetChannelIDCount()); +} + +TEST_F(NetworkContextTest, ClearEmptyChannelIds) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + net::ChannelIDStore* store = network_context->url_request_context() + ->channel_id_service() + ->GetChannelIDStore(); + ASSERT_EQ(0, store->GetChannelIDCount()); + + base::RunLoop run_loop; + network_context->ClearChannelIds(base::Time(), base::Time(), + nullptr /* filter */, + base::BindOnce(run_loop.QuitClosure())); + run_loop.Run(); + + EXPECT_EQ(0, store->GetChannelIDCount()); +} + +void GetAllChannelIdsCallback( + base::RunLoop* run_loop, + net::ChannelIDStore::ChannelIDList* dest, + const net::ChannelIDStore::ChannelIDList& result) { + *dest = result; + run_loop->Quit(); +} + +TEST_F(NetworkContextTest, ClearChannelIdsWithKeepFilter) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + net::ChannelIDStore* store = network_context->url_request_context() + ->channel_id_service() + ->GetChannelIDStore(); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "google.com", base::Time::FromDoubleT(123), + crypto::ECPrivateKey::Create())); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "chromium.org", base::Time::FromDoubleT(456), + crypto::ECPrivateKey::Create())); + + ASSERT_EQ(2, store->GetChannelIDCount()); + + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::KEEP_MATCHES; + filter->domains.push_back("chromium.org"); + + base::RunLoop run_loop1; + network_context->ClearChannelIds(base::Time(), base::Time(), + std::move(filter), + base::BindOnce(run_loop1.QuitClosure())); + run_loop1.Run(); + + base::RunLoop run_loop2; + net::ChannelIDStore::ChannelIDList channel_ids; + store->GetAllChannelIDs( + base::BindRepeating(&GetAllChannelIdsCallback, &run_loop2, &channel_ids)); + run_loop2.Run(); + ASSERT_EQ(1u, channel_ids.size()); + EXPECT_EQ("chromium.org", channel_ids.front().server_identifier()); +} + +TEST_F(NetworkContextTest, ClearChannelIdsWithDeleteFilter) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + net::ChannelIDStore* store = network_context->url_request_context() + ->channel_id_service() + ->GetChannelIDStore(); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "google.com", base::Time::FromDoubleT(123), + crypto::ECPrivateKey::Create())); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "chromium.org", base::Time::FromDoubleT(456), + crypto::ECPrivateKey::Create())); + + ASSERT_EQ(2, store->GetChannelIDCount()); + + mojom::ClearDataFilterPtr filter = mojom::ClearDataFilter::New(); + filter->type = mojom::ClearDataFilter_Type::DELETE_MATCHES; + filter->domains.push_back("chromium.org"); + + base::RunLoop run_loop1; + network_context->ClearChannelIds(base::Time(), base::Time(), + std::move(filter), + base::BindOnce(run_loop1.QuitClosure())); + run_loop1.Run(); + + base::RunLoop run_loop2; + net::ChannelIDStore::ChannelIDList channel_ids; + store->GetAllChannelIDs( + base::BindRepeating(&GetAllChannelIdsCallback, &run_loop2, &channel_ids)); + run_loop2.Run(); + ASSERT_EQ(1u, channel_ids.size()); + EXPECT_EQ("google.com", channel_ids.front().server_identifier()); +} + +TEST_F(NetworkContextTest, ClearChannelIdsWithTimeRange) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + net::ChannelIDStore* store = network_context->url_request_context() + ->channel_id_service() + ->GetChannelIDStore(); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "google.com", base::Time::FromDoubleT(123), + crypto::ECPrivateKey::Create())); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "chromium.org", base::Time::FromDoubleT(456), + crypto::ECPrivateKey::Create())); + store->SetChannelID(std::make_unique<net::ChannelIDStore::ChannelID>( + "gmail.com", base::Time::FromDoubleT(789), + crypto::ECPrivateKey::Create())); + + ASSERT_EQ(3, store->GetChannelIDCount()); + + base::RunLoop run_loop1; + network_context->ClearChannelIds( + base::Time::FromDoubleT(450), base::Time::FromDoubleT(460), + nullptr /* filter */, base::BindOnce(run_loop1.QuitClosure())); + run_loop1.Run(); + + base::RunLoop run_loop2; + net::ChannelIDStore::ChannelIDList channel_ids; + store->GetAllChannelIDs( + base::BindRepeating(&GetAllChannelIdsCallback, &run_loop2, &channel_ids)); + run_loop2.Run(); + + std::vector<std::string> identifiers; + for (const auto& id : channel_ids) { + identifiers.push_back(id.server_identifier()); + } + EXPECT_THAT(identifiers, + testing::UnorderedElementsAre("google.com", "gmail.com")); +} + void SetCookieCallback(base::RunLoop* run_loop, bool* result_out, bool result) { *result_out = result; run_loop->Quit();
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index f5e1e8b..13653cf6 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -133,9 +133,9 @@ double upload_throughput; }; -// Used in NetworkContext.ClearHttpCache() to specify the resources to -// keep/delete based on their URLs. -struct ClearCacheUrlFilter { +// Used in some clearing methods of URL-keyed data to specify the resources to +// keep/delete. +struct ClearDataFilter { enum Type {DELETE_MATCHES, KEEP_MATCHES}; Type type; @@ -182,7 +182,18 @@ // in either direction by using null Time values for either argument. ClearHttpCache(mojo_base.mojom.Time start_time, mojo_base.mojom.Time end_time, - ClearCacheUrlFilter? filter) => (); + ClearDataFilter? filter) => (); + + // Clears channel IDs. A specific range of time can be specified with + // |start_time| and |end_time|. This supports unbounded deletes in either + // direction by using null Time values for either argument. + // + // If a non-null |filter| is specified, will clear only IDs matching the + // filter. Filtering by origins is not supported. If |filter| is non-null, + // |filter.origins| must be empty. + ClearChannelIds(mojo_base.mojom.Time start_time, + mojo_base.mojom.Time end_time, + ClearDataFilter? filter) => (); // Configures network conditions for the specified throttling profile. // The throttling will be applied only to requests that have
diff --git a/services/ui/ws/gpu_host.cc b/services/ui/ws/gpu_host.cc index 29bd6d0..2394ce4 100644 --- a/services/ui/ws/gpu_host.cc +++ b/services/ui/ws/gpu_host.cc
@@ -158,9 +158,13 @@ void DefaultGpuHost::DidInitialize( const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info) { + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) { gpu_info_ = gpu_info; gpu_feature_info_ = gpu_feature_info; + gpu_info_for_hardware_gpu_ = gpu_info_for_hardware_gpu; + gpu_feature_info_for_hardware_gpu_ = gpu_feature_info_for_hardware_gpu; delegate_->OnGpuServiceInitialized(); }
diff --git a/services/ui/ws/gpu_host.h b/services/ui/ws/gpu_host.h index e2f8b25..b6024b3 100644 --- a/services/ui/ws/gpu_host.h +++ b/services/ui/ws/gpu_host.h
@@ -96,8 +96,11 @@ #endif // defined(OS_CHROMEOS) // viz::mojom::GpuHost: - void DidInitialize(const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info) override; + void DidInitialize( + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info, + const gpu::GPUInfo& gpu_info_for_hardware_gpu, + const gpu::GpuFeatureInfo& gpu_feature_info_for_hardware_gpu) override; void DidFailInitialize() override; void DidCreateContextSuccessfully() override; void DidCreateOffscreenContext(const GURL& url) override; @@ -122,6 +125,12 @@ mojo::Binding<viz::mojom::GpuHost> gpu_host_binding_; gpu::GPUInfo gpu_info_; gpu::GpuFeatureInfo gpu_feature_info_; + + // What we would have gotten if we haven't fallen back to SwiftShader or + // pure software (in the viz case). + gpu::GPUInfo gpu_info_for_hardware_gpu_; + gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu_; + std::unique_ptr<viz::ServerGpuMemoryBufferManager> gpu_memory_buffer_manager_; viz::mojom::VizMainPtr viz_main_;
diff --git a/services/ui/ws/gpu_host_unittest.cc b/services/ui/ws/gpu_host_unittest.cc index 7da8f46..f7dbc5d 100644 --- a/services/ui/ws/gpu_host_unittest.cc +++ b/services/ui/ws/gpu_host_unittest.cc
@@ -54,7 +54,9 @@ nullptr /* watchdog_thread */, std::move(io_runner), gpu::GpuFeatureInfo(), - gpu::GpuPreferences()) {} + gpu::GpuPreferences(), + gpu::GPUInfo(), + gpu::GpuFeatureInfo()) {} } // namespace
diff --git a/services/viz/privileged/interfaces/gl/gpu_host.mojom b/services/viz/privileged/interfaces/gl/gpu_host.mojom index 3c8d839..eee8440b 100644 --- a/services/viz/privileged/interfaces/gl/gpu_host.mojom +++ b/services/viz/privileged/interfaces/gl/gpu_host.mojom
@@ -13,8 +13,13 @@ // Communication channel from the gpu process to the gpu host. This interface // should never have any sync function calls. interface GpuHost { + // If |gpu_info| and |gpu_feature_info| are for hardware GPU, then + // |gpu_info_for_hardware_gpu| and |gpu_feature_info_for_hardware_gpu| can + // be uninitialized data. DidInitialize(gpu.mojom.GpuInfo gpu_info, - gpu.mojom.GpuFeatureInfo gpu_feature_info); + gpu.mojom.GpuFeatureInfo gpu_feature_info, + gpu.mojom.GpuInfo gpu_info_for_hardware_gpu, + gpu.mojom.GpuFeatureInfo gpu_feature_info_for_hardware_gpu); DidFailInitialize(); DidCreateContextSuccessfully();
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index ef2591e..2417bd7 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -75,6 +75,7 @@ ] } + defines += [ "SK_USE_SKCMS" ] include_dirs += [ "//third_party/skia/third_party/skcms" ] if (skia_support_gpu) {
diff --git a/storage/browser/quota/client_usage_tracker.cc b/storage/browser/quota/client_usage_tracker.cc index 6d2e48cfc..2db8289 100644 --- a/storage/browser/quota/client_usage_tracker.cc +++ b/storage/browser/quota/client_usage_tracker.cc
@@ -144,7 +144,7 @@ void ClientUsageTracker::UpdateUsageCache(const GURL& origin, int64_t delta) { std::string host = net::GetHostOrSpecFromURL(origin); - if (cached_hosts_.find(host) != cached_hosts_.end()) { + if (base::ContainsKey(cached_hosts_, host)) { if (!IsUsageCacheEnabledForOrigin(origin)) return;
diff --git a/storage/browser/quota/client_usage_tracker.h b/storage/browser/quota/client_usage_tracker.h index a8f6e7e4..72460d2 100644 --- a/storage/browser/quota/client_usage_tracker.h +++ b/storage/browser/quota/client_usage_tracker.h
@@ -73,12 +73,9 @@ using HostUsageMap = std::map<std::string, UsageMap>; struct AccumulateInfo { - int pending_jobs; - int64_t limited_usage; - int64_t unlimited_usage; - - AccumulateInfo() - : pending_jobs(0), limited_usage(0), unlimited_usage(0) {} + int pending_jobs = 0; + int64_t limited_usage = 0; + int64_t unlimited_usage = 0; }; void AccumulateLimitedOriginUsage(AccumulateInfo* info,
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h index 3c261f2..7a4a4e53 100644 --- a/storage/browser/quota/quota_callbacks.h +++ b/storage/browser/quota/quota_callbacks.h
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/containers/flat_map.h" +#include "base/stl_util.h" #include "storage/browser/quota/quota_client.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" @@ -23,7 +24,7 @@ namespace storage { struct UsageInfo; -typedef std::vector<UsageInfo> UsageInfoEntries; +using UsageInfoEntries = std::vector<UsageInfo>; // Common callback types that are used throughout in the quota module. using GlobalUsageCallback = @@ -90,7 +91,7 @@ } bool HasCallbacks(const Key& key) const { - return (callback_map_.find(key) != callback_map_.end()); + return base::ContainsKey(callback_map_, key); } bool HasAnyCallbacks() const {
diff --git a/storage/browser/quota/quota_client.h b/storage/browser/quota/quota_client.h index 9b3b31a2..2d81df7 100644 --- a/storage/browser/quota/quota_client.h +++ b/storage/browser/quota/quota_client.h
@@ -79,7 +79,7 @@ }; // TODO(dmikurube): Replace it to std::vector for efficiency. -typedef std::list<QuotaClient*> QuotaClientList; +using QuotaClientList = std::list<QuotaClient*>; } // namespace storage
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index caea73c..e789830 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -15,6 +15,7 @@ #include "base/files/file_util.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "sql/connection.h" #include "sql/meta_table.h" #include "sql/statement.h" @@ -341,14 +342,12 @@ if (!LazyOpen(true)) return false; - typedef std::set<GURL>::const_iterator itr_type; - for (itr_type itr = origins.begin(), end = origins.end(); - itr != end; ++itr) { + for (const auto& origin : origins) { const char* kSql = "INSERT OR IGNORE INTO OriginInfoTable" " (origin, type) VALUES (?, ?)"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, itr->spec()); + statement.BindString(0, origin.spec()); statement.BindInt(1, static_cast<int>(type)); if (!statement.Run()) @@ -456,7 +455,7 @@ while (statement.Step()) { GURL url(statement.ColumnString(0)); - if (exceptions.find(url) != exceptions.end()) { + if (base::ContainsKey(exceptions, url)) { HistogramOriginType(IN_USE); continue; } @@ -687,7 +686,6 @@ if (current_version == 2) { QuotaTableImporter importer; - typedef std::vector<QuotaTableEntry> QuotaTableEntries; if (!DumpQuotaTable(base::BindRepeating(&QuotaTableImporter::Append, base::Unretained(&importer)))) { return false; @@ -697,9 +695,8 @@ sql::Transaction transaction(db_.get()); if (!transaction.Begin()) return false; - for (QuotaTableEntries::const_iterator iter = importer.entries.begin(); - iter != importer.entries.end(); ++iter) { - if (!InsertOrReplaceHostQuota(iter->host, iter->type, iter->quota)) + for (const auto& entry : importer.entries) { + if (!InsertOrReplaceHostQuota(entry.host, entry.type, entry.quota)) return false; } return transaction.Commit();
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc index baec00ed..62fbcd91 100644 --- a/storage/browser/quota/quota_database_unittest.cc +++ b/storage/browser/quota/quota_database_unittest.cc
@@ -74,7 +74,7 @@ EXPECT_TRUE(db.LazyOpen(true)); EXPECT_TRUE(db.db_.get()); - typedef EntryVerifier<QuotaTableEntry> Verifier; + using Verifier = EntryVerifier<QuotaTableEntry>; Verifier verifier(entries, entries + arraysize(entries)); EXPECT_TRUE(db.DumpQuotaTable( base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); @@ -399,7 +399,7 @@ AssignQuotaTable(db.db_.get(), begin, end); db.Commit(); - typedef EntryVerifier<QuotaTableEntry> Verifier; + using Verifier = EntryVerifier<QuotaTableEntry>; Verifier verifier(begin, end); EXPECT_TRUE(db.DumpQuotaTable( base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); @@ -408,7 +408,7 @@ void DumpOriginInfoTable(const base::FilePath& kDbFile) { base::Time now(base::Time::Now()); - typedef QuotaDatabase::OriginInfoTableEntry Entry; + using Entry = QuotaDatabase::OriginInfoTableEntry; Entry kTableEntries[] = { Entry(GURL("http://go/"), kTemporary, 2147483647, now, now), Entry(GURL("http://oo/"), kTemporary, 0, now, now), @@ -422,7 +422,7 @@ AssignOriginInfoTable(db.db_.get(), begin, end); db.Commit(); - typedef EntryVerifier<Entry> Verifier; + using Verifier = EntryVerifier<Entry>; Verifier verifier(begin, end); EXPECT_TRUE(db.DumpOriginInfoTable( base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); @@ -431,7 +431,7 @@ void GetOriginInfo(const base::FilePath& kDbFile) { const GURL kOrigin = GURL("http://go/"); - typedef QuotaDatabase::OriginInfoTableEntry Entry; + using Entry = QuotaDatabase::OriginInfoTableEntry; Entry kTableEntries[] = { Entry(kOrigin, kTemporary, 100, base::Time(), base::Time())}; Entry* begin = kTableEntries;
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc index c217f1e..d3315014 100644 --- a/storage/browser/quota/quota_manager.cc +++ b/storage/browser/quota/quota_manager.cc
@@ -101,12 +101,10 @@ *unlimited_origins = 0; if (!policy) return; - for (std::set<GURL>::const_iterator itr = origins.begin(); - itr != origins.end(); - ++itr) { - if (policy->IsStorageProtected(*itr)) + for (const auto& origin : origins) { + if (policy->IsStorageProtected(origin)) ++*protected_origins; - if (policy->IsStorageUnlimited(*itr)) + if (policy->IsStorageUnlimited(origin)) ++*unlimited_origins; } } @@ -512,10 +510,9 @@ void AddEntries(StorageType type, UsageTracker* tracker) { std::map<std::string, int64_t> host_usage; tracker->GetCachedHostsUsage(&host_usage); - for (std::map<std::string, int64_t>::const_iterator iter = - host_usage.begin(); - iter != host_usage.end(); ++iter) { - entries_.push_back(UsageInfo(iter->first, type, iter->second)); + for (const auto& host_usage_pair : host_usage) { + entries_.push_back( + UsageInfo(host_usage_pair.first, type, host_usage_pair.second)); } if (--remaining_trackers_ == 0) CallCompleted(); @@ -561,10 +558,9 @@ void Run() override { error_count_ = 0; remaining_clients_ = manager()->clients_.size(); - for (QuotaClientList::iterator iter = manager()->clients_.begin(); - iter != manager()->clients_.end(); ++iter) { - if (quota_client_mask_ & (*iter)->id()) { - (*iter)->DeleteOriginData( + for (auto* client : manager()->clients_) { + if (quota_client_mask_ & client->id()) { + client->DeleteOriginData( url::Origin::Create(origin_), type_, base::BindOnce(&OriginDataDeleter::DidDeleteOriginData, weak_factory_.GetWeakPtr())); @@ -649,9 +645,8 @@ void Run() override { error_count_ = 0; remaining_clients_ = manager()->clients_.size(); - for (QuotaClientList::iterator iter = manager()->clients_.begin(); - iter != manager()->clients_.end(); ++iter) { - (*iter)->GetOriginsForHost( + for (auto* client : manager()->clients_) { + client->GetOriginsForHost( type_, host_, base::BindOnce(&HostDataDeleter::DidGetOriginsForHost, weak_factory_.GetWeakPtr())); @@ -696,11 +691,9 @@ void ScheduleOriginsDeletion() { remaining_deleters_ = origins_.size(); - for (std::set<GURL>::const_iterator p = origins_.begin(); - p != origins_.end(); - ++p) { + for (const auto& origin : origins_) { OriginDataDeleter* deleter = new OriginDataDeleter( - manager(), *p, type_, quota_client_mask_, false, + manager(), origin, type_, quota_client_mask_, false, base::BindOnce(&HostDataDeleter::DidDeleteOriginData, weak_factory_.GetWeakPtr())); deleter->Start(); @@ -1078,9 +1071,9 @@ if (temporary_storage_evictor_) { std::map<std::string, int64_t> stats; temporary_storage_evictor_->GetStatistics(&stats); - for (std::map<std::string, int64_t>::iterator p = stats.begin(); - p != stats.end(); ++p) { - (*statistics)[p->first] = base::Int64ToString(p->second); + for (const auto& origin_usage_pair : stats) { + (*statistics)[origin_usage_pair.first] = + base::Int64ToString(origin_usage_pair.second); } } }
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h index 07512996..8dc6ffdc 100644 --- a/storage/browser/quota/quota_manager.h +++ b/storage/browser/quota/quota_manager.h
@@ -24,6 +24,7 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/sequenced_task_runner_helpers.h" +#include "base/stl_util.h" #include "storage/browser/quota/quota_callbacks.h" #include "storage/browser/quota/quota_client.h" #include "storage/browser/quota/quota_database.h" @@ -185,7 +186,7 @@ void NotifyOriginInUse(const GURL& origin); void NotifyOriginNoLongerInUse(const GURL& origin); bool IsOriginInUse(const GURL& origin) const { - return origins_in_use_.find(origin) != origins_in_use_.end(); + return base::ContainsKey(origins_in_use_, origin); } void SetUsageCacheEnabled(QuotaClient::ID client_id,
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc index b1b60d7..05853a1 100644 --- a/storage/browser/quota/quota_manager_unittest.cc +++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -80,9 +80,9 @@ class QuotaManagerTest : public testing::Test { protected: - typedef QuotaManager::QuotaTableEntry QuotaTableEntry; - typedef QuotaManager::QuotaTableEntries QuotaTableEntries; - typedef QuotaManager::OriginInfoTableEntries OriginInfoTableEntries; + using QuotaTableEntry = QuotaManager::QuotaTableEntry; + using QuotaTableEntries = QuotaManager::QuotaTableEntries; + using OriginInfoTableEntries = QuotaManager::OriginInfoTableEntries; public: QuotaManagerTest() @@ -1484,12 +1484,9 @@ DumpOriginInfoTable(); scoped_task_environment_.RunUntilIdle(); - typedef OriginInfoTableEntries::const_iterator iterator; - for (iterator itr(origin_info_entries().begin()), - end(origin_info_entries().end()); - itr != end; ++itr) { - if (itr->type == kTemp) - EXPECT_NE(std::string("http://foo.com/"), itr->origin.spec()); + for (const auto& entry : origin_info_entries()) { + if (entry.type == kTemp) + EXPECT_NE(std::string("http://foo.com/"), entry.origin.spec()); } GetGlobalUsage(kTemp); @@ -1613,11 +1610,8 @@ scoped_task_environment_.RunUntilIdle(); bool found_origin_in_database = false; - typedef OriginInfoTableEntries::const_iterator iterator; - for (iterator itr(origin_info_entries().begin()), - end(origin_info_entries().end()); - itr != end; ++itr) { - if (itr->type == kTemp && itr->origin == "http://foo.com/") { + for (const auto& entry : origin_info_entries()) { + if (entry.type == kTemp && entry.origin == "http://foo.com/") { found_origin_in_database = true; break; } @@ -1785,16 +1779,14 @@ DumpOriginInfoTable(); scoped_task_environment_.RunUntilIdle(); - typedef OriginInfoTableEntries::const_iterator iterator; - for (iterator itr(origin_info_entries().begin()), - end(origin_info_entries().end()); - itr != end; ++itr) { - if (itr->type == kTemp) { - EXPECT_NE(std::string("http://foo.com/"), itr->origin.spec()); - EXPECT_NE(std::string("http://foo.com:1/"), itr->origin.spec()); - EXPECT_NE(std::string("https://foo.com/"), itr->origin.spec()); - EXPECT_NE(std::string("http://bar.com/"), itr->origin.spec()); - } + for (const auto& entry : origin_info_entries()) { + if (entry.type != kTemp) + continue; + + EXPECT_NE(std::string("http://foo.com/"), entry.origin.spec()); + EXPECT_NE(std::string("http://foo.com:1/"), entry.origin.spec()); + EXPECT_NE(std::string("https://foo.com/"), entry.origin.spec()); + EXPECT_NE(std::string("http://bar.com/"), entry.origin.spec()); } GetGlobalUsage(kTemp); @@ -1881,14 +1873,12 @@ DumpOriginInfoTable(); scoped_task_environment_.RunUntilIdle(); - typedef OriginInfoTableEntries::const_iterator iterator; - for (iterator itr(origin_info_entries().begin()), - end(origin_info_entries().end()); - itr != end; ++itr) { - if (itr->type == kTemp) { - EXPECT_NE(std::string("http://foo.com/"), itr->origin.spec()); - EXPECT_NE(std::string("http://bar.com/"), itr->origin.spec()); - } + for (const auto& entry : origin_info_entries()) { + if (entry.type != kTemp) + continue; + + EXPECT_NE(std::string("http://foo.com/"), entry.origin.spec()); + EXPECT_NE(std::string("http://bar.com/"), entry.origin.spec()); } GetGlobalUsage(kTemp); @@ -1954,7 +1944,7 @@ for (size_t i = 0; i < arraysize(kData); ++i) { if (kData[i].type == kTemp) - EXPECT_TRUE(origins.find(GURL(kData[i].origin)) != origins.end()); + EXPECT_TRUE(base::ContainsKey(origins, GURL(kData[i].origin))); } } @@ -2122,13 +2112,10 @@ }; std::set<QuotaTableEntry> entries(kEntries, kEntries + arraysize(kEntries)); - typedef QuotaTableEntries::const_iterator iterator; - for (iterator itr(quota_entries().begin()), end(quota_entries().end()); - itr != end; ++itr) { - SCOPED_TRACE(testing::Message() - << "host = " << itr->host << ", " - << "quota = " << itr->quota); - EXPECT_EQ(1u, entries.erase(*itr)); + for (const auto& quota_entry : quota_entries()) { + SCOPED_TRACE(testing::Message() << "host = " << quota_entry.host << ", " + << "quota = " << quota_entry.quota); + EXPECT_EQ(1u, entries.erase(quota_entry)); } EXPECT_TRUE(entries.empty()); } @@ -2153,25 +2140,22 @@ DumpOriginInfoTable(); scoped_task_environment_.RunUntilIdle(); - typedef std::pair<GURL, StorageType> TypedOrigin; - typedef std::pair<TypedOrigin, int> Entry; + using TypedOrigin = std::pair<GURL, StorageType>; + using Entry = std::pair<TypedOrigin, int>; const Entry kEntries[] = { make_pair(make_pair(GURL("http://example.com/"), kTemp), 1), make_pair(make_pair(GURL("http://example.com/"), kPerm), 2), }; std::set<Entry> entries(kEntries, kEntries + arraysize(kEntries)); - typedef OriginInfoTableEntries::const_iterator iterator; - for (iterator itr(origin_info_entries().begin()), - end(origin_info_entries().end()); - itr != end; ++itr) { + for (const auto& origin_info : origin_info_entries()) { SCOPED_TRACE(testing::Message() - << "host = " << itr->origin << ", " - << "type = " << static_cast<int>(itr->type) << ", " - << "used_count = " << itr->used_count); + << "host = " << origin_info.origin << ", " + << "type = " << static_cast<int>(origin_info.type) << ", " + << "used_count = " << origin_info.used_count); EXPECT_EQ(1u, entries.erase( - make_pair(make_pair(itr->origin, itr->type), - itr->used_count))); + make_pair(make_pair(origin_info.origin, origin_info.type), + origin_info.used_count))); } EXPECT_TRUE(entries.empty()); }
diff --git a/storage/browser/quota/quota_task.cc b/storage/browser/quota/quota_task.cc index 5ec6145..8e10a880 100644 --- a/storage/browser/quota/quota_task.cc +++ b/storage/browser/quota/quota_task.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" using base::TaskRunner; @@ -68,7 +69,7 @@ } void QuotaTaskObserver::UnregisterTask(QuotaTask* task) { - DCHECK(running_quota_tasks_.find(task) != running_quota_tasks_.end()); + DCHECK(base::ContainsKey(running_quota_tasks_, task)); running_quota_tasks_.erase(task); }
diff --git a/storage/browser/quota/quota_task.h b/storage/browser/quota/quota_task.h index 2ae85f14..4ed23d5c 100644 --- a/storage/browser/quota/quota_task.h +++ b/storage/browser/quota/quota_task.h
@@ -69,7 +69,7 @@ void RegisterTask(QuotaTask* task); void UnregisterTask(QuotaTask* task); - typedef std::set<QuotaTask*> TaskSet; + using TaskSet = std::set<QuotaTask*>; TaskSet running_quota_tasks_; }; }
diff --git a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc index 75353de..b4acd69 100644 --- a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc +++ b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" +#include "base/stl_util.h" #include "base/test/scoped_task_environment.h" #include "storage/browser/quota/quota_manager.h" #include "storage/browser/quota/quota_temporary_storage_evictor.h" @@ -75,9 +76,8 @@ int64_t GetUsage() const { int64_t total_usage = 0; - for (std::map<GURL, int64_t>::const_iterator p = origins_.begin(); - p != origins_.end(); ++p) - total_usage += p->second; + for (const auto& origin_usage_pair : origins_) + total_usage += origin_usage_pair.second; return total_usage; } @@ -105,7 +105,7 @@ // Simulates an access to |origin|. It reorders the internal LRU list. // It internally uses AddOrigin(). void AccessOrigin(const GURL& origin) { - std::map<GURL, int64_t>::iterator found = origins_.find(origin); + const auto& found = origins_.find(origin); EXPECT_TRUE(origins_.end() != found); AddOrigin(origin, found->second); } @@ -122,7 +122,7 @@ private: int64_t EnsureOriginRemoved(const GURL& origin) { int64_t origin_usage; - if (origins_.find(origin) == origins_.end()) + if (!base::ContainsKey(origins_, origin)) return -1; else origin_usage = origins_[origin];
diff --git a/storage/browser/quota/special_storage_policy.h b/storage/browser/quota/special_storage_policy.h index f8a1253..dc0f37c 100644 --- a/storage/browser/quota/special_storage_policy.h +++ b/storage/browser/quota/special_storage_policy.h
@@ -25,7 +25,7 @@ class STORAGE_EXPORT SpecialStoragePolicy : public base::RefCountedThreadSafe<SpecialStoragePolicy> { public: - typedef int StoragePolicy; + using StoragePolicy = int; enum ChangeFlags { STORAGE_PROTECTED = 1 << 0, STORAGE_UNLIMITED = 1 << 1,
diff --git a/storage/browser/quota/storage_monitor.cc b/storage/browser/quota/storage_monitor.cc index aa0d897..9665aac 100644 --- a/storage/browser/quota/storage_monitor.cc +++ b/storage/browser/quota/storage_monitor.cc
@@ -27,17 +27,17 @@ void StorageObserverList::AddObserver( StorageObserver* observer, const StorageObserver::MonitorParams& params) { - ObserverState& observer_state = observers_[observer]; + ObserverState& observer_state = observer_state_map_[observer]; observer_state.origin = params.filter.origin; observer_state.rate = params.rate; } void StorageObserverList::RemoveObserver(StorageObserver* observer) { - observers_.erase(observer); + observer_state_map_.erase(observer); } int StorageObserverList::ObserverCount() const { - return observers_.size(); + return observer_state_map_.size(); } void StorageObserverList::OnStorageChange(const StorageObserver::Event& event) { @@ -45,10 +45,8 @@ TRACE_EVENT0("io", "HostStorageObserversStorageObserverList::OnStorageChange"); - for (StorageObserverStateMap::iterator it = observers_.begin(); - it != observers_.end(); ++it) { - it->second.requires_update = true; - } + for (auto& observer_state_pair : observer_state_map_) + observer_state_pair.second.requires_update = true; MaybeDispatchEvent(event); } @@ -62,24 +60,25 @@ base::TimeDelta min_delay = base::TimeDelta::Max(); bool all_observers_notified = true; - for (StorageObserverStateMap::iterator it = observers_.begin(); - it != observers_.end(); ++it) { - if (!it->second.requires_update) + for (auto& observer_state_pair : observer_state_map_) { + StorageObserver* observer = observer_state_pair.first; + ObserverState& state = observer_state_pair.second; + + if (!state.requires_update) continue; base::TimeTicks current_time = base::TimeTicks::Now(); - base::TimeDelta delta = current_time - it->second.last_notification_time; - if (it->second.last_notification_time.is_null() || - delta >= it->second.rate) { - it->second.requires_update = false; - it->second.last_notification_time = current_time; + base::TimeDelta delta = current_time - state.last_notification_time; + if (state.last_notification_time.is_null() || delta >= state.rate) { + state.requires_update = false; + state.last_notification_time = current_time; - if (it->second.origin == event.filter.origin) { + if (state.origin == event.filter.origin) { // crbug.com/349708 TRACE_EVENT0("io", "StorageObserverList::MaybeDispatchEvent OnStorageEvent1"); - it->first->OnStorageEvent(event); + observer->OnStorageEvent(event); } else { // When the quota and usage of an origin is requested, QuotaManager // returns the quota and usage of the host. Multiple origins can map to @@ -87,17 +86,17 @@ // event matches the |origin| specified by the observer when it was // registered. StorageObserver::Event dispatch_event(event); - dispatch_event.filter.origin = it->second.origin; + dispatch_event.filter.origin = state.origin; // crbug.com/349708 TRACE_EVENT0("io", "StorageObserverList::MaybeDispatchEvent OnStorageEvent2"); - it->first->OnStorageEvent(dispatch_event); + observer->OnStorageEvent(dispatch_event); } } else { all_observers_notified = false; - base::TimeDelta delay = it->second.rate - delta; + base::TimeDelta delay = state.rate - delta; if (delay < min_delay) min_delay = delay; } @@ -118,8 +117,8 @@ } void StorageObserverList::ScheduleUpdateForObserver(StorageObserver* observer) { - DCHECK(base::ContainsKey(observers_, observer)); - observers_[observer].requires_update = true; + DCHECK(base::ContainsKey(observer_state_map_, observer)); + observer_state_map_[observer].requires_update = true; } void StorageObserverList::DispatchPendingEvent() { @@ -324,10 +323,8 @@ } void StorageMonitor::RemoveObserver(StorageObserver* observer) { - for (auto it = storage_type_observers_map_.begin(); - it != storage_type_observers_map_.end(); ++it) { - it->second->RemoveObserver(observer); - } + for (auto& type_observers_pair : storage_type_observers_map_) + type_observers_pair.second->RemoveObserver(observer); } const StorageTypeObservers* StorageMonitor::GetStorageTypeObservers(
diff --git a/storage/browser/quota/storage_monitor.h b/storage/browser/quota/storage_monitor.h index ee90bf94..c17b249 100644 --- a/storage/browser/quota/storage_monitor.h +++ b/storage/browser/quota/storage_monitor.h
@@ -60,11 +60,11 @@ ObserverState(); }; - typedef std::map<StorageObserver*, ObserverState> StorageObserverStateMap; + using StorageObserverStateMap = std::map<StorageObserver*, ObserverState>; void DispatchPendingEvent(); - StorageObserverStateMap observers_; + StorageObserverStateMap observer_state_map_; base::OneShotTimer notification_timer_; StorageObserver::Event pending_event_;
diff --git a/storage/browser/quota/storage_monitor_unittest.cc b/storage/browser/quota/storage_monitor_unittest.cc index 5ba01b7..5d7b63ea 100644 --- a/storage/browser/quota/storage_monitor_unittest.cc +++ b/storage/browser/quota/storage_monitor_unittest.cc
@@ -9,6 +9,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/stl_util.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "net/base/url_util.h" @@ -128,10 +129,8 @@ int GetRequiredUpdatesCount(const StorageObserverList& observer_list) { int count = 0; - for (StorageObserverList::StorageObserverStateMap::const_iterator it = - observer_list.observers_.begin(); - it != observer_list.observers_.end(); ++it) { - if (it->second.requires_update) + for (const auto& observer_state_pair : observer_list.observer_state_map_) { + if (observer_state_pair.second.requires_update) ++count; } @@ -144,11 +143,9 @@ void SetLastNotificationTime(StorageObserverList& observer_list, StorageObserver* observer) { - ASSERT_TRUE(observer_list.observers_.find(observer) != - observer_list.observers_.end()); - + ASSERT_TRUE(base::ContainsKey(observer_list.observer_state_map_, observer)); StorageObserverList::ObserverState& state = - observer_list.observers_[observer]; + observer_list.observer_state_map_[observer]; state.last_notification_time = base::TimeTicks::Now() - state.rate; } @@ -184,7 +181,7 @@ // Tests for StorageObserverList: -typedef StorageMonitorTestBase StorageObserverListTest; +using StorageObserverListTest = StorageMonitorTestBase; // Test dispatching events to one observer. TEST_F(StorageObserverListTest, DispatchEventToSingleObserver) { @@ -309,7 +306,7 @@ // Tests for HostStorageObservers: -typedef StorageTestWithManagerBase HostStorageObserversTest; +using HostStorageObserversTest = StorageTestWithManagerBase; // Verify that HostStorageObservers is initialized after the first usage change. TEST_F(HostStorageObserversTest, InitializeOnUsageChange) { @@ -487,7 +484,7 @@ // Tests for StorageTypeObservers: -typedef StorageTestWithManagerBase StorageTypeObserversTest; +using StorageTypeObserversTest = StorageTestWithManagerBase; // Test adding and removing observers. TEST_F(StorageTypeObserversTest, AddRemoveObservers) {
diff --git a/storage/browser/quota/usage_tracker_unittest.cc b/storage/browser/quota/usage_tracker_unittest.cc index bdaa02f..3e641b8a 100644 --- a/storage/browser/quota/usage_tracker_unittest.cc +++ b/storage/browser/quota/usage_tracker_unittest.cc
@@ -80,10 +80,8 @@ GetOriginsCallback callback) override { EXPECT_EQ(StorageType::kTemporary, type); std::set<url::Origin> origins; - for (UsageMap::const_iterator itr = usage_map_.begin(); - itr != usage_map_.end(); ++itr) { - origins.insert(url::Origin::Create(itr->first)); - } + for (const auto& origin_usage_pair : origin_usage_map_) + origins.insert(url::Origin::Create(origin_usage_pair.first)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), origins)); } @@ -93,10 +91,9 @@ GetOriginsCallback callback) override { EXPECT_EQ(StorageType::kTemporary, type); std::set<url::Origin> origins; - for (UsageMap::const_iterator itr = usage_map_.begin(); - itr != usage_map_.end(); ++itr) { - if (net::GetHostOrSpecFromURL(itr->first) == host) - origins.insert(url::Origin::Create(itr->first)); + for (const auto& origin_usage_pair : origin_usage_map_) { + if (net::GetHostOrSpecFromURL(origin_usage_pair.first) == host) + origins.insert(url::Origin::Create(origin_usage_pair.first)); } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), origins)); @@ -106,7 +103,7 @@ StorageType type, DeletionCallback callback) override { EXPECT_EQ(StorageType::kTemporary, type); - usage_map_.erase(origin.GetURL()); + origin_usage_map_.erase(origin.GetURL()); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), QuotaStatusCode::kOk)); } @@ -116,24 +113,22 @@ } int64_t GetUsage(const GURL& origin) { - UsageMap::const_iterator found = usage_map_.find(origin); - if (found == usage_map_.end()) + auto found = origin_usage_map_.find(origin); + if (found == origin_usage_map_.end()) return 0; return found->second; } void SetUsage(const GURL& origin, int64_t usage) { - usage_map_[origin] = usage; + origin_usage_map_[origin] = usage; } int64_t UpdateUsage(const GURL& origin, int64_t delta) { - return usage_map_[origin] += delta; + return origin_usage_map_[origin] += delta; } private: - typedef std::map<GURL, int64_t> UsageMap; - - UsageMap usage_map_; + std::map<GURL, int64_t> origin_usage_map_; DISALLOW_COPY_AND_ASSIGN(MockQuotaClient); };
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 40c1d708..a9837b26 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -3610,9 +3610,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_browser_tests", + "name": "not_site_per_process_browser_tests", "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4159,9 +4159,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_interactive_ui_tests", + "name": "not_site_per_process_interactive_ui_tests", "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4493,9 +4493,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_sync_integration_tests", + "name": "not_site_per_process_sync_integration_tests", "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -4552,9 +4552,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_unit_tests", + "name": "not_site_per_process_unit_tests", "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -8197,6 +8197,31 @@ } ] }, + "test": "cacheinvalidation_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "capture_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04" + } + ], + "shards": 2 + }, "test": "crypto_unittests" }, { @@ -8209,6 +8234,30 @@ } ] }, + "test": "google_apis_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04" + } + ] + }, + "test": "midi_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04" + } + ] + }, "test": "sql_unittests" }, { @@ -8228,12 +8277,164 @@ "linux-annotator-rel": { "scripts": [ { - "name": "check_network_annotation_auditor", - "script": "check_network_annotation_auditor.py" + "name": "test_traffic_annotation_auditor", + "script": "test_traffic_annotation_auditor.py" } ] }, "linux-blink-heap-incremental-marking": { + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "blink_heap_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cacheinvalidation_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "capture_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "components_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "crypto_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "google_apis_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "gpu_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ipc_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "jingle_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "media_blink_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "media_service_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "media_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "midi_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "net_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "services_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "skia_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "sql_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ui_base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "unit_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "url_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "webkit_unit_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "wtf_unittests" + } + ], "isolated_scripts": [ { "args": [
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 64eca9d..033c096 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5800,6 +5800,26 @@ { "args": [ "--test-launcher-batch-limit=400", + "--deqp-egl-display-type=angle-vulkan" + ], + "name": "angle_deqp_gles2_vulkan_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-384.90", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ], + "shards": 4 + }, + "test": "angle_deqp_gles2_tests", + "use_xvfb": false + }, + { + "args": [ + "--test-launcher-batch-limit=400", "--deqp-egl-display-type=angle-gl" ], "name": "angle_deqp_gles31_gl_tests", @@ -15226,6 +15246,26 @@ { "args": [ "--test-launcher-batch-limit=400", + "--deqp-egl-display-type=angle-vulkan" + ], + "name": "angle_deqp_gles2_vulkan_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3-23.21.13.8816", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 4 + }, + "test": "angle_deqp_gles2_tests", + "use_xvfb": false + }, + { + "args": [ + "--test-launcher-batch-limit=400", "--deqp-egl-display-type=angle-d3d11" ], "name": "angle_deqp_gles31_d3d11_tests", @@ -18377,6 +18417,26 @@ }, "test": "angle_deqp_gles2_tests", "use_xvfb": false + }, + { + "args": [ + "--test-launcher-batch-limit=400", + "--deqp-egl-display-type=angle-vulkan" + ], + "name": "angle_deqp_gles2_vulkan_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6613", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-GPU" + } + ], + "shards": 4 + }, + "test": "angle_deqp_gles2_tests", + "use_xvfb": false } ], "isolated_scripts": []
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 1a394a1a..103b005 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -695,9 +695,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_browser_tests", + "name": "not_site_per_process_browser_tests", "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -1023,9 +1023,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_interactive_ui_tests", + "name": "not_site_per_process_interactive_ui_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -1189,9 +1189,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_sync_integration_tests", + "name": "not_site_per_process_sync_integration_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -1223,9 +1223,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_unit_tests", + "name": "not_site_per_process_unit_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -1505,9 +1505,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_browser_tests", + "name": "not_site_per_process_browser_tests", "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -1834,9 +1834,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_interactive_ui_tests", + "name": "not_site_per_process_interactive_ui_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -2003,9 +2003,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_sync_integration_tests", + "name": "not_site_per_process_sync_integration_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -2031,9 +2031,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_unit_tests", + "name": "not_site_per_process_unit_tests", "swarming": { "can_use_on_swarming_builders": true },
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 0f45ef3..4866f29 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -57,9 +57,6 @@ "test": "boringssl_ssl_tests" }, { - "args": [ - "--test-launcher-jobs=1" - ], "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -539,9 +536,6 @@ "test": "boringssl_ssl_tests" }, { - "args": [ - "--test-launcher-jobs=1" - ], "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -997,9 +991,6 @@ "test": "blink_platform_unittests" }, { - "args": [ - "--test-launcher-jobs=1" - ], "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -1480,9 +1471,6 @@ "test": "boringssl_ssl_tests" }, { - "args": [ - "--test-launcher-jobs=1" - ], "swarming": { "can_use_on_swarming_builders": true, "shards": 10
diff --git a/testing/buildbot/client.v8.chromium.json b/testing/buildbot/client.v8.chromium.json index f46b991..c1b8bfb 100644 --- a/testing/buildbot/client.v8.chromium.json +++ b/testing/buildbot/client.v8.chromium.json
@@ -18,9 +18,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_browser_tests", + "name": "not_site_per_process_browser_tests", "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -212,9 +212,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_unit_tests", + "name": "not_site_per_process_unit_tests", "swarming": { "can_use_on_swarming_builders": true }, @@ -292,9 +292,9 @@ }, { "args": [ - "--site-per-process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_browser_tests", + "name": "not_site_per_process_browser_tests", "swarming": { "can_use_on_swarming_builders": true, "shards": 10 @@ -469,9 +469,9 @@ }, { "args": [ - "--site_per_process" + "--disable-site-isolation-trials" ], - "name": "site_per_process_unit_tests", + "name": "not_site_per_process_unit_tests", "swarming": { "can_use_on_swarming_builders": true },
diff --git a/testing/buildbot/filters/mash.ash_unittests.filter b/testing/buildbot/filters/mash.ash_unittests.filter index a1da907a..4b97800 100644 --- a/testing/buildbot/filters/mash.ash_unittests.filter +++ b/testing/buildbot/filters/mash.ash_unittests.filter
@@ -39,6 +39,8 @@ -DisplayManagerTest.SoftwareMirrorModeBasics -DisplayManagerTest.UpdateMouseCursorAfterRotateZoom -DisplayManagerTestDisableMultiMirroring.SoftwareMirroringWithCompositingCursor +-DisplayManagerTest.SoftwareMirrorRotationForTablet +-DisplayManagerTest.SoftwareMirrorRotationForNonTablet # TODO: Docked magnifier needs reflector to work in mash. # https://crbug.com/814481. @@ -47,6 +49,7 @@ -AccessibilityControllerSigninTest.EnableOnLoginScreenAndLogin/2 -DockedMagnifierTest.AddRemoveDisplays -DockedMagnifierTest.DisplaysWorkAreas +-DockedMagnifierTest.FocusChangeEvents -DockedMagnifierTest.HighContrastMode -DockedMagnifierTest.MutuallyExclusiveMagnifiers -DockedMagnifierTest.TestEnableAndDisable
diff --git a/testing/buildbot/filters/mash.browser_tests.filter b/testing/buildbot/filters/mash.browser_tests.filter index dad8300..54895a4 100644 --- a/testing/buildbot/filters/mash.browser_tests.filter +++ b/testing/buildbot/filters/mash.browser_tests.filter
@@ -295,6 +295,7 @@ -*ECKEncryptedMediaTest.* -MSE_ClearKey/EncryptedMediaTest.* -MSE_ExternalClearKey/EncryptedMediaTest.* +-AudioPlayerBrowserTest.* -AudioPlayerBrowserTestInGuestMode.OpenAudioOnDownloads -AutoplayExtensionBrowserTest.AutoplayAllowed -MediaEngagementBrowserTest.* @@ -305,6 +306,7 @@ -ExtensionResourceRequestPolicyTest.Video -DeferredMediaBrowserTest.BackgroundMediaIsDeferred -DeclarativeNetRequestResourceTypeBrowserTest.Test1/0 +-VideoPlayerBrowserTest.* -VideoPlayerBrowserTestInGuestMode.OpenSingleVideoOnDownloads -IsolatedAppTest.SubresourceCookieIsolation -PageLoadMetricsBrowserTest.* @@ -329,6 +331,7 @@ -OpenFileDialog/FileManagerBrowserTest.* -GearMenu/FileManagerBrowserTest.Test/3 -GearMenu/FileManagerBrowserTest.Test/0 +-CreateNewFolder/FileManagerBrowserTest.* -TabindexFocusDownloads/FileManagerBrowserTestWithLegacyEventDispatch.Test/0 -TabindexFocusDownloads/FileManagerBrowserTestWithLegacyEventDispatch.Test/1 -DeclarativeNetRequestResourceTypeBrowserTest.Test1/1 @@ -336,3 +339,4 @@ -DeclarativeNetRequestResourceTypeBrowserTest.Test2/1 -MediaEngagementSessionRestoreBrowserTest.RestoredSession_Playback_MEI -AutoplayExtensionBrowserTest.* +-ChromeTracingDelegateBrowserTestOnStartup.StartupTracingThrottle
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 0d3a3ae3..9b5a178a 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -303,31 +303,6 @@ '--gtest_filter=-SaveType/SavePageMultiFrameBrowserTest.ObjectElements/0', ], }, - # chromium.mac - 'Mac10.10 Tests': { - # TODO(crbug.com/828031): Remove once diagnosed and fixed. - 'args': [ - '--test-launcher-jobs=1', - ], - }, - 'Mac10.11 Tests': { - # TODO(crbug.com/828031): Remove once diagnosed and fixed. - 'args': [ - '--test-launcher-jobs=1', - ], - }, - 'Mac10.12 Tests': { - # TODO(crbug.com/828031): Remove once diagnosed and fixed. - 'args': [ - '--test-launcher-jobs=1', - ], - }, - 'Mac10.13 Tests': { - # TODO(crbug.com/828031): Remove once diagnosed and fixed. - 'args': [ - '--test-launcher-jobs=1', - ], - }, # chromium.memory 'Linux ASan LSan Tests (1)': { # These are very slow on the ASAN trybot for some reason. @@ -2661,7 +2636,7 @@ 'Linux MSan Tests', # https://crbug.com/831676 ], }, - 'site_per_process_browser_tests': { + 'not_site_per_process_browser_tests': { 'remove_from': [ # chromium.fyi 'Site Isolation Android', @@ -2726,38 +2701,25 @@ 'Linux Tests (dbg)(1)(32)', ], }, - 'site_per_process_interactive_ui_tests': { + 'not_site_per_process_interactive_ui_tests': { 'remove_from': [ # chromium.linux 'Linux Tests (dbg)(1)(32)', ], }, - 'site_per_process_sync_integration_tests': { + 'not_site_per_process_sync_integration_tests': { 'remove_from': [ # chromium.linux 'Linux Tests (dbg)(1)(32)', ], }, - 'site_per_process_unit_tests': { + 'not_site_per_process_unit_tests': { 'remove_from': [ # chromium.fyi 'Site Isolation Android', # chromium.linux 'Linux Tests (dbg)(1)(32)', ], - 'modifications': { - 'Linux - Future': { - 'args': [ - '--site-per-process', - ], - }, - 'Linux - Future (dbg)': { - # TODO(dpranke): this should be --site-per-process. - 'args': [ - '--site_per_process', - ], - }, - }, }, 'site_per_process_webkit_layout_tests': { 'remove_from': [ @@ -3496,7 +3458,7 @@ }, }, 'Mac10.13 Tests': { - # TODO (crbug.com/833020)(jbudorick,dpranke): Switch this to 10.13. + # TODO(jbudorick,dpranke): Switch this to 10.13. # TODO(kbr): if the Swarming dimensions were explicitly specified for # all jobs then this wouldn't be needed. However, note that this bot
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 5b796a7..1289271f 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -328,9 +328,9 @@ } }, - 'check_network_annotation_auditor_script': { - 'check_network_annotation_auditor': { - 'script': 'check_network_annotation_auditor.py', + 'test_traffic_annotation_auditor_script': { + 'test_traffic_annotation_auditor': { + 'script': 'test_traffic_annotation_auditor.py', }, }, @@ -349,7 +349,15 @@ }, 'chromeos_gtests': { - 'crypto_unittests': {}, + 'cacheinvalidation_unittests': {}, + 'capture_unittests': {}, + 'crypto_unittests': { + 'swarming': { + 'shards': 2, + }, + }, + 'midi_unittests': {}, + 'google_apis_unittests': {}, 'sql_unittests': {}, 'url_unittests': {}, }, @@ -712,9 +720,9 @@ 'remoting_unittests': {}, 'services_unittests': {}, - 'site_per_process_browser_tests': { + 'not_site_per_process_browser_tests': { 'args': [ - '--site-per-process' + '--disable-site-isolation-trials' ], 'swarming': { 'shards': 10, @@ -734,7 +742,10 @@ ], 'test': 'content_unittests', }, - 'site_per_process_unit_tests': { + 'not_site_per_process_unit_tests': { + 'args': [ + '--disable-site-isolation-trials' + ], 'test': 'unit_tests', }, 'sync_integration_tests': {}, @@ -1465,9 +1476,9 @@ }, 'site_isolation_chromium_gtests': { - 'site_per_process_browser_tests': { + 'not_site_per_process_browser_tests': { 'args': [ - '--site-per-process' + '--disable-site-isolation-trials' ], 'swarming': { 'shards': 10, @@ -1487,9 +1498,9 @@ ], 'test': 'content_unittests', }, - 'site_per_process_unit_tests': { + 'not_site_per_process_unit_tests': { 'args': [ - '--site-per-process', + '--disable-site-isolation-trials' ], 'test': 'unit_tests', }, @@ -1520,15 +1531,15 @@ ], 'test': 'extensions_unittests', }, - 'site_per_process_interactive_ui_tests': { + 'not_site_per_process_interactive_ui_tests': { 'args': [ - '--site-per-process', + '--disable-site-isolation-trials' ], 'test': 'interactive_ui_tests', }, - 'site_per_process_sync_integration_tests': { + 'not_site_per_process_sync_integration_tests': { 'args': [ - '--site-per-process', + '--disable-site-isolation-trials' ], 'test': 'sync_integration_tests', },
diff --git a/testing/buildbot/trybot_analyze_config.json b/testing/buildbot/trybot_analyze_config.json index c0985e2..14b49bc 100644 --- a/testing/buildbot/trybot_analyze_config.json +++ b/testing/buildbot/trybot_analyze_config.json
@@ -61,7 +61,6 @@ "third_party/jstemplate/.*(css|html|js)", "third_party/mocha/.*(css|html|js)", "third_party/polymer/v1_0/components-chromium/.*(css|html|js)", - "third_party/typ/.*", "third_party/web-animations-js/.*(css|html|js)", "third_party/zlib/google/test/data/.*", "tools/clang/scripts/update.py",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index ebca56d..7e83785 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -905,7 +905,7 @@ }, 'linux-annotator-rel': { 'test_suites': { - 'scripts': 'check_network_annotation_auditor_script', + 'scripts': 'test_traffic_annotation_auditor_script', } }, 'mac-views-rel': { @@ -1026,6 +1026,7 @@ }, 'linux-blink-heap-incremental-marking': { 'test_suites': { + 'gtest_tests': 'chromium_gtests', 'isolated_scripts': 'chromium_webkit_isolated_scripts', }, }, @@ -1218,14 +1219,19 @@ }, }, 'Site Isolation Linux': { - # TODO(dpranke): Remove this builder once the tests are running on - # the main 'Linux Tests' bot; base_unittests is a placeholder + # TODO(lukasza, dpranke): Remove this bot once site-per-process has + # been turned on by default for a while (e.g. once + # https://crrev.com/c/981019 "sticks"). + # base_unittests is a placeholder # to keep the builder from building "all". 'additional_compile_targets': [ 'base_unittests', ], }, 'Site Isolation Win': { + # TODO(lukasza, dpranke): Remove this bot once site-per-process has + # been turned on by default for a while (e.g. once + # https://crrev.com/c/981019 "sticks"). 'test_suites': { 'gtest_tests': 'site_isolation_win_fyi_gtests', },
diff --git a/testing/scripts/check_network_annotations.py b/testing/scripts/check_network_annotations.py index 1edccf1..8aeeae78d 100755 --- a/testing/scripts/check_network_annotations.py +++ b/testing/scripts/check_network_annotations.py
@@ -3,7 +3,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""//testing/scripts wrapper for the network traffic annotations checks.""" +"""//testing/scripts wrapper for the network traffic annotations checks. +This script is used to run check_annotations.py on the trybots to ensure that +all network traffic annotations have correct syntax and semantics, and all +functions requiring annotations have one.""" import json import os
diff --git a/testing/scripts/headless_python_unittests.py b/testing/scripts/headless_python_unittests.py index f551b162..05a2f94 100755 --- a/testing/scripts/headless_python_unittests.py +++ b/testing/scripts/headless_python_unittests.py
@@ -14,7 +14,7 @@ def main_run(args): typ_path = os.path.abspath(os.path.join( os.path.dirname(__file__), os.path.pardir, os.path.pardir, - 'third_party', 'typ')) + 'third_party', 'catapult', 'third_party', 'typ')) _AddToPathIfNeeded(typ_path) import typ
diff --git a/testing/scripts/check_network_annotation_auditor.py b/testing/scripts/test_traffic_annotation_auditor.py similarity index 81% rename from testing/scripts/check_network_annotation_auditor.py rename to testing/scripts/test_traffic_annotation_auditor.py index 5002383..279d020 100755 --- a/testing/scripts/check_network_annotation_auditor.py +++ b/testing/scripts/test_traffic_annotation_auditor.py
@@ -3,8 +3,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""//testing/scripts wrapper for the network traffic annotation auditor -checks.""" +"""//testing/scripts wrapper for the network traffic annotation auditor checks. +This script is used to run traffic_annotation_auditor_tests.py on an FYI bot to +check that traffic_annotation_auditor has the same results when heuristics that +help it run fast and spam free on trybots are disabled.""" import json import os
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 799f1511..a9f06b3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3480,6 +3480,24 @@ ] } ], + "SitePerProcess": [ + { + "platforms": [ + "chromeos", + "linux", + "win", + "mac" + ], + "experiments": [ + { + "name": "SitePerProcess_Enabled", + "enable_features": [ + "site-per-process" + ] + } + ] + } + ], "SocketReadIfReady": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 68614183..1ec8781 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -145,7 +145,9 @@ crbug.com/591099 css2.1/t1205-c564-list-img-00-b-g.html [ Failure ] crbug.com/591099 css3/blending/background-blend-mode-overlapping-accelerated-elements.html [ Failure ] crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ] -crbug.com/714962 css3/filters/effect-reference-zoom-hw.html [ Failure Timeout ] +crbug.com/591099 css3/filters/effect-brightness-clamping.html [ Failure ] +crbug.com/591099 css3/filters/effect-brightness.html [ Failure ] +crbug.com/714962 css3/filters/effect-reference-zoom-hw.html [ Failure ] crbug.com/591099 css3/filters/multiple-references-id-mutate-crash-2.html [ Crash ] crbug.com/591099 css3/flexbox/child-overflow.html [ Failure ] crbug.com/591099 css3/flexbox/flex-flow-border.html [ Failure ] @@ -212,8 +214,6 @@ crbug.com/591099 editing/selection/linux_selection_color.html [ Failure ] crbug.com/591099 editing/selection/mixed-editability-10.html [ Failure ] crbug.com/591099 editing/selection/modify_extend/extend_by_character.html [ Failure ] -crbug.com/714962 editing/selection/modify_extend/extend_forward_line_crash.html [ Failure Pass ] -crbug.com/714962 editing/selection/modify_move/move-by-paragraph.html [ Failure Pass ] crbug.com/714962 editing/selection/modify_move/move-forward-after-line-break.html [ Failure ] crbug.com/591099 editing/selection/move-left-right.html [ Pass Timeout ] crbug.com/714962 editing/selection/offset-from-point-complex-scripts.html [ Failure ] @@ -632,7 +632,7 @@ crbug.com/591099 external/wpt/css/css-writing-modes/wm-propagation-body-006.xht [ Failure ] crbug.com/591099 external/wpt/css/cssom-view/elementFromPoint-002.html [ Failure ] crbug.com/591099 external/wpt/css/cssom-view/elementFromPoint-003.html [ Failure ] -crbug.com/591099 external/wpt/css/cssom/interfaces.html [ Timeout ] +crbug.com/591099 external/wpt/css/cssom/interfaces.html [ Pass Timeout ] crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass ] crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml [ Failure ] @@ -801,7 +801,7 @@ crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-block-formatting-context.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html [ Failure ] -crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html [ Timeout ] +crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html [ Failure Timeout ] crbug.com/591099 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-non-snap-to-lines.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-menu.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Failure ] @@ -816,7 +816,6 @@ crbug.com/591099 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Timeout ] crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.html [ Timeout ] crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Timeout ] -crbug.com/591099 external/wpt/offscreen-canvas/compositing/2d.composite.globalAlpha.canvaspattern.worker.html [ Crash Pass ] crbug.com/591099 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.html [ Crash ] crbug.com/591099 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker.html [ Pass ] crbug.com/591099 external/wpt/payment-request/payment-allowed-by-feature-policy.https.sub.html [ Pass ] @@ -1393,7 +1392,7 @@ crbug.com/591099 fast/table/percent-height-content-in-fixed-height-border-box-sized-cell-with-collapsed-border-on-table.html [ Failure ] crbug.com/591099 fast/table/percent-height-content-in-fixed-height-border-box-sized-cell-with-collapsed-border.html [ Failure ] crbug.com/591099 fast/table/percent-height-content-in-fixed-height-content-box-sized-cell.html [ Failure ] -crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ] +crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ] crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ] @@ -1531,7 +1530,7 @@ crbug.com/591099 fast/text/whitespace/normal-after-nowrap-breaking.html [ Failure ] crbug.com/591099 fast/text/zero-width-characters-complex-script.html [ Failure ] crbug.com/591099 fast/text/zero-width-characters.html [ Failure ] -crbug.com/591099 fast/webgl/canvas-toDataURL-premul-overflow.html [ Failure Pass ] +crbug.com/591099 fast/webgl/texImage-imageBitmap-from-video-resize.html [ Timeout ] crbug.com/591099 fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure ] crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ] crbug.com/714962 fast/writing-mode/background-vertical-lr.html [ Failure ] @@ -1593,14 +1592,14 @@ crbug.com/591099 http/tests/devtools/console/console-search.js [ Timeout ] crbug.com/591099 http/tests/devtools/console/console-uncaught-promise.js [ Failure ] crbug.com/591099 http/tests/devtools/console/console-viewport-control.js [ Failure ] -crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Pass Timeout ] -crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ] +crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Timeout ] +crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Timeout ] crbug.com/591099 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Pass Timeout ] crbug.com/714962 http/tests/devtools/editor/text-editor-formatter.js [ Pass Timeout ] crbug.com/591099 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Pass Timeout ] crbug.com/591099 http/tests/devtools/editor/text-editor-word-jumps.js [ Pass ] crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-4.js [ Crash ] -crbug.com/591099 http/tests/devtools/elements/elements-inspect-iframe-from-different-domain.js [ Timeout ] +crbug.com/591099 http/tests/devtools/elements/elements-inspect-iframe-from-different-domain.js [ Pass Timeout ] crbug.com/591099 http/tests/devtools/elements/elements-panel-rewrite-href.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside-scroll.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside.js [ Failure ] @@ -1619,7 +1618,7 @@ crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Failure ] crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Failure ] crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ] -crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Pass Timeout ] +crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Timeout ] crbug.com/591099 http/tests/incremental/slow-utf8-text.pl [ Pass Timeout ] crbug.com/591099 http/tests/loading/nested_bad_objects.php [ Failure ] crbug.com/591099 http/tests/loading/preload-picture-nested.html [ Failure ] @@ -1650,7 +1649,9 @@ crbug.com/591099 ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-001.htm [ Failure ] crbug.com/824918 ietestcenter/css3/multicolumn/column-width-applies-to-010.htm [ Failure ] crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ] +crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ] crbug.com/591099 images/color-profile-image-shape.html [ Failure ] +crbug.com/591099 images/color-profile-munsell-adobe-to-srgb.html [ Failure ] crbug.com/591099 images/percent-height-image.html [ Failure ] crbug.com/591099 inspector-protocol/accessibility/accessibility-ignoredNodes.js [ Timeout ] crbug.com/714962 inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Failure ] @@ -2057,9 +2058,12 @@ crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-shape.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-layer-filter.html [ Timeout ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-layer.html [ Failure ] +crbug.com/591099 virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-reflection.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/percent-height-image.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Pass ] +crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-filter.html [ Timeout ] +crbug.com/591099 virtual/gpu/fast/canvas/canvas-composite-video-shadow.html [ Timeout ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Pass ] crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html [ Failure ] @@ -2072,14 +2076,13 @@ crbug.com/714962 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-with-delegatesFocus.html [ Timeout ] crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ] -crbug.com/591099 virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Failure Pass ] crbug.com/591099 virtual/modern-media-controls/media/controls/modern/tap-to-hide-controls.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/drag-in-frames.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/hr-timestamp/input-events.html [ Failure Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/keyboardevent-getModifierState.html [ Timeout ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-latching.html [ Pass Timeout ] -crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ] +crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-event-buttons-attribute.html [ Timeout ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-relative-position.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseevent-getModifierState.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index c433964c..ce38a1d 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1225,6 +1225,7 @@ crbug.com/738613 paint/invalidation/compositing/background-attachment-local-composited.html [ Failure ] crbug.com/738613 paint/invalidation/compositing/background-attachment-local-equivalent.html [ Failure ] crbug.com/738613 paint/invalidation/compositing/new-stacking-context.html [ Failure ] +crbug.com/738613 paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited.html [ Failure ] crbug.com/738613 paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer.html [ Failure ] crbug.com/738613 paint/invalidation/compositing/updating-scrolling-content.html [ Failure ] crbug.com/738613 paint/invalidation/scroll/flipped-blocks-writing-mode-scroll.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests index 515ecd6..f7798f6 100644 --- a/third_party/WebKit/LayoutTests/NeverFixTests +++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -1827,9 +1827,6 @@ crbug.com/457718 external/wpt/css/css-pseudo/marker-color.html [ WontFix ] crbug.com/457718 external/wpt/css/css-pseudo/marker-font-properties.html [ WontFix ] -# https://github.com/w3c/web-platform-tests/issues/8633 -external/wpt/css/css-style-attr/style-attr-braces-002-quirks.htm [ WontFix ] - # Requires --use-fake-ui-for-media-stream to run. external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html [ WontFix ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 8a7756c..68b1708 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -4102,3 +4102,6 @@ crbug.com/833100 [ Mac ] external/wpt/battery-status/battery-full-manual.https.html [ Failure ] crbug.com/834446 [ Linux ] http/tests/misc/performance-memory.html [ Pass Failure ] + +# Sheriff 2018-04-23 +crbug.com/833331 [ Win10 ] inspector-protocol/page/pageNavigateToFragment.js [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.png b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.png new file mode 100644 index 0000000..b854fe31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.txt b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.txt similarity index 72% rename from third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.txt rename to third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.txt index 6f6a6a4..f2711c3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.txt +++ b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-clamping-expected.txt
@@ -3,20 +3,28 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutImage {IMG} at (0,0) size 160x90 LayoutText {#text} at (160,75) size 4x19 text run at (160,75) width 4: " " + LayoutImage {IMG} at (164,0) size 160x90 LayoutText {#text} at (324,75) size 4x19 text run at (324,75) width 4: " " + LayoutImage {IMG} at (328,0) size 160x90 LayoutText {#text} at (488,75) size 4x19 text run at (488,75) width 4: " " + LayoutImage {IMG} at (492,0) size 160x90 LayoutText {#text} at (652,75) size 4x19 text run at (652,75) width 4: " " + LayoutImage {IMG} at (0,95) size 160x90 LayoutText {#text} at (160,170) size 4x19 text run at (160,170) width 4: " " + LayoutImage {IMG} at (164,95) size 160x90 LayoutText {#text} at (324,170) size 4x19 text run at (324,170) width 4: " " + LayoutImage {IMG} at (328,95) size 160x90 LayoutText {#text} at (488,170) size 4x19 text run at (488,170) width 4: " " + LayoutImage {IMG} at (492,95) size 160x90 LayoutText {#text} at (652,170) size 4x19 text run at (652,170) width 4: " " LayoutText {#text} at (160,265) size 4x19 @@ -26,22 +34,6 @@ LayoutText {#text} at (488,265) size 4x19 text run at (488,265) width 4: " " LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 160x90 - LayoutImage {IMG} at (0,0) size 160x90 -layer at (172,8) size 160x90 - LayoutImage {IMG} at (164,0) size 160x90 -layer at (336,8) size 160x90 - LayoutImage {IMG} at (328,0) size 160x90 -layer at (500,8) size 160x90 - LayoutImage {IMG} at (492,0) size 160x90 -layer at (8,103) size 160x90 - LayoutImage {IMG} at (0,95) size 160x90 -layer at (172,103) size 160x90 - LayoutImage {IMG} at (164,95) size 160x90 -layer at (336,103) size 160x90 - LayoutImage {IMG} at (328,95) size 160x90 -layer at (500,103) size 160x90 - LayoutImage {IMG} at (492,95) size 160x90 layer at (8,198) size 160x90 LayoutImage {IMG} at (0,190) size 160x90 layer at (172,198) size 160x90
diff --git a/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.png b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.png new file mode 100644 index 0000000..c55ea7364 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.txt b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.txt similarity index 83% rename from third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.txt rename to third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.txt index 404ad28..dc33dfb6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.txt +++ b/third_party/WebKit/LayoutTests/css3/filters/effect-brightness-expected.txt
@@ -3,10 +3,13 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutImage {IMG} at (0,0) size 160x90 LayoutText {#text} at (160,75) size 4x19 text run at (160,75) width 4: " " + LayoutImage {IMG} at (164,0) size 160x90 LayoutText {#text} at (324,75) size 4x19 text run at (324,75) width 4: " " + LayoutImage {IMG} at (328,0) size 160x90 LayoutText {#text} at (488,75) size 4x19 text run at (488,75) width 4: " " LayoutText {#text} at (652,75) size 4x19 @@ -16,12 +19,6 @@ LayoutText {#text} at (324,170) size 4x19 text run at (324,170) width 4: " " LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 160x90 - LayoutImage {IMG} at (0,0) size 160x90 -layer at (172,8) size 160x90 - LayoutImage {IMG} at (164,0) size 160x90 -layer at (336,8) size 160x90 - LayoutImage {IMG} at (328,0) size 160x90 layer at (500,8) size 160x90 LayoutImage {IMG} at (492,0) size 160x90 layer at (8,103) size 160x90
diff --git a/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing-invalid.html b/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing-invalid.html index b5bfc37..3f31679b 100644 --- a/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing-invalid.html +++ b/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing-invalid.html
@@ -49,6 +49,7 @@ assert_invalid_value("filter", "brightness(0.5 0.5)"); // Too many parameters assert_invalid_value("filter", "brightness(0.5, 0.5)"); // Too many parameters and commas assert_invalid_value("filter", "brightness(0.5,)"); // Trailing comma +assert_invalid_value("filter", "brightness(-1.1)"); // Parameter is negative assert_invalid_value("filter", "contrast(10px)"); // Length instead of number assert_invalid_value("filter", "contrast(0.5 0.5)"); // Too many parameters
diff --git a/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing.html b/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing.html index b84155a..4f37c948 100644 --- a/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing.html +++ b/third_party/WebKit/LayoutTests/css3/filters/filter-property-parsing.html
@@ -68,7 +68,6 @@ assert_valid_value("filter", "brightness(0)"); // Zero value assert_valid_value("filter", "brightness()"); // No arguments assert_valid_value("filter", "brightness(0.5) brightness(0.25)"); // Multiple values -assert_valid_value("filter", "brightness(-1.1)"); // Parameter less than -100% assert_valid_value("filter", "brightness(101%)"); // Parameter more than 100% assert_valid_value("filter", "contrast(1)"); // Integer value
diff --git a/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-number.html b/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-number.html deleted file mode 100644 index 192a004..0000000 --- a/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-number.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style></style> -<script> -'use strict'; - -test(() => { - const CSSFilterFunctionNegativeBrightness = 2193; // From web_feature.mojom - var style = document.querySelector('style'); - style.textContent = "* { filter: brightness(1); }"; - assert_false(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); - style.textContent = "* { filter: brightness(0); }"; - assert_false(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); - style.textContent = "* { filter: brightness(-1); }"; - assert_true(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); -}, "'filter' with negative brightness is use counted."); -</script>
diff --git a/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-percentage.html b/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-percentage.html deleted file mode 100644 index a903835..0000000 --- a/third_party/WebKit/LayoutTests/css3/filters/usecounter-negative-brightness-percentage.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style></style> -<script> -'use strict'; - -test(() => { - const CSSFilterFunctionNegativeBrightness = 2193; // From enums.xml - var style = document.querySelector('style'); - style.textContent = "* { filter: brightness(1%); }"; - assert_false(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); - style.textContent = "* { filter: brightness(0%); }"; - assert_false(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); - style.textContent = "* { filter: brightness(-1%); }"; - assert_true(internals.isUseCounted(document, CSSFilterFunctionNegativeBrightness)); -}, "'filter' with negative brightness percentage is use counted."); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index aebef17..3560c34 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -100159,6 +100159,16 @@ {} ] ], + "console/console-tests-historical.any-expected.txt": [ + [ + {} + ] + ], + "console/console-tests-historical.any.worker-expected.txt": [ + [ + {} + ] + ], "content-security-policy/OWNERS": [ [ {} @@ -117624,11 +117634,6 @@ {} ] ], - "css/css-fonts/variations/font-variation-settings-parsing-expected.txt": [ - [ - {} - ] - ], "css/css-fonts/variations/font-weight-parsing-expected.txt": [ [ {} @@ -162909,6 +162914,11 @@ {} ] ], + "webaudio/resources/biquad-testing.js": [ + [ + {} + ] + ], "webaudio/resources/convolution-testing.js": [ [ {} @@ -177287,6 +177297,16 @@ {} ] ], + "console/console-tests-historical.any.js": [ + [ + "/console/console-tests-historical.any.html", + {} + ], + [ + "/console/console-tests-historical.any.worker.html", + {} + ] + ], "console/console-time-label-conversion.any.js": [ [ "/console/console-time-label-conversion.any.html", @@ -177297,16 +177317,6 @@ {} ] ], - "console/console-timeline-timelineEnd-historical.any.js": [ - [ - "/console/console-timeline-timelineEnd-historical.any.html", - {} - ], - [ - "/console/console-timeline-timelineEnd-historical.any.worker.html", - {} - ] - ], "content-security-policy/base-uri/base-uri-allow.sub.html": [ [ "/content-security-policy/base-uri/base-uri-allow.sub.html", @@ -205299,6 +205309,12 @@ {} ] ], + "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html": [ + [ + "/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html", + {} + ] + ], "html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html": [ [ "/html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html", @@ -233424,7 +233440,9 @@ "upgrade-insecure-requests/link-upgrade.sub.https.html": [ [ "/upgrade-insecure-requests/link-upgrade.sub.https.html", - {} + { + "timeout": "long" + } ] ], "upgrade-insecure-requests/websocket-upgrade.https.html": [ @@ -234663,6 +234681,90 @@ {} ] ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html", + {} + ] + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html": [ + [ + "/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html", + {} + ] + ], "webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html": [ [ "/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html", @@ -256204,12 +256306,20 @@ "9ad845184a6dd40b1ab64992ca514dbf4736c930", "testharness" ], - "console/console-time-label-conversion.any.js": [ - "5e2ca9e9dca88c6de32408b461f3f4c54c586031", + "console/console-tests-historical.any-expected.txt": [ + "6dfddeb4f5e1664d0d01b5b0009972541416124d", + "support" + ], + "console/console-tests-historical.any.js": [ + "ee18f8a672534b478ca15990026638a73588fcf4", "testharness" ], - "console/console-timeline-timelineEnd-historical.any.js": [ - "ca938829b5946f26348e237379a4f3e9ec945e40", + "console/console-tests-historical.any.worker-expected.txt": [ + "6dfddeb4f5e1664d0d01b5b0009972541416124d", + "support" + ], + "console/console-time-label-conversion.any.js": [ + "5e2ca9e9dca88c6de32408b461f3f4c54c586031", "testharness" ], "content-security-policy/OWNERS": [ @@ -289125,11 +289235,11 @@ "testharness" ], "css/css-fonts/variations/font-shorthand-expected.txt": [ - "ebc1d4d3ccac459d39cf416f0caccb6cb512d048", + "156c1b3adc21bc9082e7c50e2a92a9400dead394", "support" ], "css/css-fonts/variations/font-shorthand.html": [ - "7e193d5e25424699652e64b419e1d1384370e3a4", + "683248c8b0e361e82d59df2ba3b94b4d9ee20479", "testharness" ], "css/css-fonts/variations/font-stretch-expected.txt": [ @@ -289156,12 +289266,8 @@ "ec4b475a9bd04601161398ae21207967881a8f28", "testharness" ], - "css/css-fonts/variations/font-variation-settings-parsing-expected.txt": [ - "a390811f0a3c8361d132226e914c18e78bc3cee1", - "support" - ], "css/css-fonts/variations/font-variation-settings-parsing.html": [ - "bc12bf7fdec6a81a95df8c66c6387f4857b4a284", + "0b43e98e0151065bc60d82fd6f00ae0fbeb966d5", "testharness" ], "css/css-fonts/variations/font-weight-interpolation.html": [ @@ -334557,7 +334663,7 @@ "support" ], "html/browsers/browsing-the-web/unloading-documents/unload/007.html": [ - "bfb39279cb1e49176f4c77e0253dd92642f53f34", + "ac12d25b792d284b377e889565351f626df7627e", "testharness" ], "html/browsers/browsing-the-web/unloading-documents/unload/008-1.html": [ @@ -349852,6 +349958,10 @@ "93f2cc8f3e88e0cbf508acd64f9a28bdcaff25b0", "testharness" ], + "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html": [ + "b579ff5a32f582bc6baf42bfff08d36dafc94c8f", + "testharness" + ], "html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html": [ "32455a1418d94fa68368bae3b1c0291204f6b4e3", "testharness" @@ -378761,7 +378871,7 @@ "testharness" ], "upgrade-insecure-requests/link-upgrade.sub.https.html": [ - "0c7c3915c24e355f3353a242843c76bb17b13c62", + "d8279d5c8b46259643bd960374398ea4d8a455f8", "testharness" ], "upgrade-insecure-requests/link-upgrade/basic-link-no-upgrade.sub.html": [ @@ -380176,6 +380286,10 @@ "914a0268776de98f3b608babfa5699a93a2cd723", "support" ], + "webaudio/resources/biquad-testing.js": [ + "148a402f0a212c8b37bc377c5c9f7091d653bb7c", + "support" + ], "webaudio/resources/convolution-testing.js": [ "4a0ae6b3701147d16cb91e5660e1f4909d022d06", "support" @@ -380440,6 +380554,62 @@ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-allpass.html": [ + "5e614c338cde7788c8f88200c8e5540c8ddd7fe0", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html": [ + "13549ae0edffb8b64ad57a0767cf1eaa98a45c48", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-bandpass.html": [ + "85b51950563a14ec76a971d79b31b42c677d6185", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html": [ + "3675c5430229774a8079eae866a355ca0793103b", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html": [ + "68a2545839beaacebaf65286829174375435a83f", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highpass.html": [ + "f20705cb15906fa78f3db321d57b568478ffdb1c", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-highshelf.html": [ + "9fa170eb3b99552faf418b7efb84cb9e39ddf5d0", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowpass.html": [ + "8e300cd5b95c753ee234cb1256f5ec1295492d2e", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-lowshelf.html": [ + "8addf4c6790feaeb028f31224cccd98c6e5fb7ee", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-notch.html": [ + "0fe79eda36594125827af62d3a8abfd884b0a1d3", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-peaking.html": [ + "8b66bfd29e8ea0b6405810d9d738331a7869e9a0", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html": [ + "e15e696492076d522c1052ae890b37f52e7bd27b", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html": [ + "f24a473f695c2d10788ba7d50728259a08ed53c8", + "testharness" + ], + "webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html": [ + "348376a643b765700342e9620e1346d432a28131", + "testharness" + ], "webaudio/the-audio-api/the-channelmergernode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any-expected.txt new file mode 100644 index 0000000..dea7bb5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL 'timeline' function should not exist on the console object assert_equals: console.timeline should be undefined expected (undefined) undefined but got (function) function "function timeline() { [native code] }" +FAIL 'timelineEnd' function should not exist on the console object assert_equals: console.timelineEnd should be undefined expected (undefined) undefined but got (function) function "function timelineEnd() { [native code] }" +FAIL 'markTimeline' function should not exist on the console object assert_equals: console.markTimeline should be undefined expected (undefined) undefined but got (function) function "function markTimeline() { [native code] }" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.js b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.js new file mode 100644 index 0000000..4c4d4c2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.js
@@ -0,0 +1,19 @@ +/** + * These tests assert the non-existence of certain + * legacy Console methods that are not included in + * the specification: http://console.spec.whatwg.org/ + */ + +"use strict"; + +test(() => { + assert_equals(console.timeline, undefined, "console.timeline should be undefined"); +}, "'timeline' function should not exist on the console object"); + +test(() => { + assert_equals(console.timelineEnd, undefined, "console.timelineEnd should be undefined"); +}, "'timelineEnd' function should not exist on the console object"); + +test(() => { + assert_equals(console.markTimeline, undefined, "console.markTimeline should be undefined"); +}, "'markTimeline' function should not exist on the console object");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.worker-expected.txt new file mode 100644 index 0000000..dea7bb5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/console/console-tests-historical.any.worker-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL 'timeline' function should not exist on the console object assert_equals: console.timeline should be undefined expected (undefined) undefined but got (function) function "function timeline() { [native code] }" +FAIL 'timelineEnd' function should not exist on the console object assert_equals: console.timelineEnd should be undefined expected (undefined) undefined but got (function) function "function timelineEnd() { [native code] }" +FAIL 'markTimeline' function should not exist on the console object assert_equals: console.markTimeline should be undefined expected (undefined) undefined but got (function) function "function markTimeline() { [native code] }" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/console/console-timeline-timelineEnd-historical.any.js b/third_party/WebKit/LayoutTests/external/wpt/console/console-timeline-timelineEnd-historical.any.js deleted file mode 100644 index 038c715..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/console/console-timeline-timelineEnd-historical.any.js +++ /dev/null
@@ -1,9 +0,0 @@ -"use strict"; - -test(() => { - assert_equals(console.timeline, undefined, "console.timeline should be undefined"); -}, "'timeline' function should not exist on the console object"); - -test(() => { - assert_equals(console.timelineEnd, undefined, "console.timelineEnd should be undefined"); -}, "'timelineEnd' function should not exist on the console object"); \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand-expected.txt index 81811c1b..06ed337 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand-expected.txt
@@ -7,10 +7,10 @@ FAIL Font shorthand: Font weight specified as calc(), value smaller than 1 assert_equals: Font shorthand expected weight: Font weight specified as calc(), value smaller than 1 expected "1" but got "400" FAIL Font shorthand: Font weight specified as calc(), value greater than 1000 assert_equals: Font shorthand expected weight: Font weight specified as calc(), value greater than 1000 expected "1000" but got "400" PASS Font shorthand: 'oblique' with positive angle -PASS Font shorthand: 'oblique' with hegative angle +PASS Font shorthand: 'oblique' with negative angle FAIL Font shorthand: 'oblique' without slant angle assert_equals: Font shorthand expected style: 'oblique' without slant angle expected "oblique" but got "italic" -FAIL Font shorthand: 'oblique' with negative angle, value out of range assert_equals: Font shorthand: 'oblique' with negative angle, value out of range expected false but got true FAIL Font shorthand: 'oblique' with positive angle, value out of range assert_equals: Font shorthand: 'oblique' with positive angle, value out of range expected false but got true +FAIL Font shorthand: 'oblique' with negative angle, value out of range assert_equals: Font shorthand: 'oblique' with negative angle, value out of range expected false but got true FAIL Font shorthand: 'oblique' followed by valid small weight assert_equals: Font shorthand expected style: 'oblique' followed by valid small weight expected "oblique" but got "italic" FAIL Font shorthand: 'oblique' followed by valid large weight assert_equals: Font shorthand expected style: 'oblique' followed by valid large weight expected "oblique" but got "italic" PASS Font shorthand: 'oblique' with positive angle followed by valid weight
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand.html index 1b15957..33ce74f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-shorthand.html
@@ -26,10 +26,10 @@ // font-style { value: "oblique 45deg 24px Arial", isValid:true, expectedStyle: "oblique 45deg", message: "'oblique' with positive angle" }, - { value: "oblique -45deg 24px Arial", isValid:true, expectedStyle: "oblique -45deg", message: "'oblique' with hegative angle" }, + { value: "oblique -45deg 24px Arial", isValid:true, expectedStyle: "oblique -45deg", message: "'oblique' with negative angle" }, { value: "oblique 24px Arial", isValid:true, expectedStyle: "oblique", message: "'oblique' without slant angle" }, - { value: "oblique 100deg 24px Arial", isValid:false, message: "'oblique' with negative angle, value out of range" }, - { value: "oblique -100deg 24px Arial", isValid:false, message: "'oblique' with positive angle, value out of range" }, + { value: "oblique 100deg 24px Arial", isValid:false, message: "'oblique' with positive angle, value out of range" }, + { value: "oblique -100deg 24px Arial", isValid:false, message: "'oblique' with negative angle, value out of range" }, // font-weight and font-style combined { value: "oblique 50 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"50", message: "'oblique' followed by valid small weight" },
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing-expected.txt deleted file mode 100644 index 13100bb..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing-expected.txt +++ /dev/null
@@ -1,41 +0,0 @@ -This is a testharness.js-based test. -FAIL Property value: Axis tag with valid non-letter ascii characters assert_equals: Axis tag with valid non-letter ascii characters expected "\"9 ~A\" -45, \"wght\" 1000" but got "\"wght\" 1000, \"9 ~A\" -45" -FAIL Property value: Invalid character below allowed range (first char) assert_equals: Invalid character below allowed range (first char) expected "normal" but got "\"wght\" 1000, \"9 ~A\" -45" -FAIL Property value: Invalid character above allowed range (mid char) assert_equals: Invalid character above allowed range (mid char) expected "normal" but got "\"wght\" 1000, \"9 ~A\" -45" -FAIL Property value: Axis values in scientific form are valid assert_equals: Axis values in scientific form are valid expected "\"slnt\" -45, \"wght\" 1000" but got "\"wght\" 1000, \"slnt\" -45" -PASS Property value: 'normal' value is valid -PASS Property value: Tag with less than 4 characters is invalid -PASS Property value: Tag with more than 4 characters is invalid -PASS Property value: Trailing comma is invalid -PASS Property value: Unquoted tags are invalid -PASS Property value: Unmatched quotes around tag are invalid -PASS Property value: Tag without value isinvalid -PASS Property value: Value without tag is invalid -PASS Property value: Value before tag is invalid -PASS Property value: Missing comma between axes is invalid -PASS Property value: Calculations should be supported -PASS Property value: Units should not be supported -PASS Property value: Units should not be supported (in calc) -PASS Property value: Percentages should not be supported -PASS Property value: Percentages should not be supported (in calc) -PASS @supports: Axis tag with valid non-letter ascii characters -PASS @supports: Invalid character below allowed range (first char) -PASS @supports: Invalid character above allowed range (mid char) -PASS @supports: Axis values in scientific form are valid -PASS @supports: 'normal' value is valid -PASS @supports: Tag with less than 4 characters is invalid -PASS @supports: Tag with more than 4 characters is invalid -PASS @supports: Trailing comma is invalid -PASS @supports: Unquoted tags are invalid -PASS @supports: Unmatched quotes around tag are invalid -PASS @supports: Tag without value isinvalid -PASS @supports: Value without tag is invalid -PASS @supports: Value before tag is invalid -PASS @supports: Missing comma between axes is invalid -PASS @supports: Calculations should be supported -PASS @supports: Units should not be supported -PASS @supports: Units should not be supported (in calc) -PASS @supports: Percentages should not be supported -PASS @supports: Percentages should not be supported (in calc) -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing.html index 93c6ec0..3d6bc5f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/variations/font-variation-settings-parsing.html
@@ -11,10 +11,10 @@ <script> var valueParserTests = [ - { value: "'wght' 1000, '9 ~A' -45", expectedComputedValue: "\"9 ~A\" -45, \"wght\" 1000", isValid: true, message: "Axis tag with valid non-letter ascii characters" }, + { value: "'wght' 1000, '9 ~A' -45", expectedComputedValue: "\"wght\" 1000, \"9 ~A\" -45", isValid: true, message: "Axis tag with valid non-letter ascii characters" }, { value: "'\u001Fbdc' 123", expectedComputedValue: "", isValid: false, message: "Invalid character below allowed range (first char)"}, { value: "'abc\u007F' 123", expectedComputedValue: "", isValid: false, message: "Invalid character above allowed range (mid char)"}, - { value: "'wght' 1e3, 'slnt' -450.0e-1 ", expectedComputedValue: "\"slnt\" -45, \"wght\" 1000", isValid: true, message: "Axis values in scientific form are valid" }, + { value: "'wght' 1e3, 'slnt' -450.0e-1 ", expectedComputedValue: "\"wght\" 1000, \"slnt\" -45", isValid: true, message: "Axis values in scientific form are valid" }, { value: "normal", expectedComputedValue: "normal", isValid: true, message: "'normal' value is valid" }, { value: "'a' 1234", expectedComputedValue: "", isValid: false, message: "Tag with less than 4 characters is invalid"}, { value: "'abcde' 1234", expectedComputedValue: "", isValid: false, message: "Tag with more than 4 characters is invalid"}, @@ -35,6 +35,8 @@ valueParserTests.forEach(function (testCase) { test(() => { var element = document.getElementById("value-parser-test"); + // Reset to empty in order for testing to continue in case the next test would not parse as valid + element.style.fontVariationSettings = ""; element.style.fontVariationSettings = testCase.value; var computed = window.getComputedStyle(element).fontVariationSettings; if (testCase.isValid) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/007.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/007.html index 0d5b72e0..4a2fed5f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/007.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/007.html
@@ -4,17 +4,17 @@ <script src="/resources/testharnessreport.js"></script> <div id="log"></div> <script> -var t = async_test(undefined, {timeout:2000}); +var t = async_test(); var loaded = false; var unload_fired = false; var timeout_fired = false; function start_test() { - setTimeout(t.step_func(function() { - assert_true(unload_fired); - assert_false(timeout_fired); - t.done() + step_timeout(t.step_func(function() { + assert_true(unload_fired); + assert_false(timeout_fired); + t.done() }), 1000); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html new file mode 100644 index 0000000..e0e3ec8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>import() inside compiled strings inside a classic script</title> +<link rel="help" href="https://github.com/whatwg/html/pull/3163"> +<link rel="help" href="https://github.com/tc39/ecma262/issues/871#issuecomment-292493142"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +"use strict"; + +self.ran = false; + +promise_test(t => { + t.add_cleanup(() => { + self.ran = false; + }) + + return Promise.resolve(`import("../imports-a.js?1").then(() => { self.ran = true; })`) + .then(eval) + .then(() => { + assert_true(self.ran); + }); +}, "Evaled the script via eval, successful import"); + +promise_test(t => { + t.add_cleanup(() => { + self.ran = false; + }) + + return Promise.resolve(`import("bad-specifier?1").catch(() => { self.ran = true; })`) + .then(eval) + .then(() => { + assert_true(self.ran); + }); +}, "Evaled the script via eval, failed import"); + +promise_test(t => { + t.add_cleanup(() => { + self.ran = false; + }) + + return Promise.resolve(`return import("../imports-a.js?2").then(() => { self.ran = true; })`) + .then(Function) + .then(Function.prototype.call.bind(Function.prototype.call)) + .then(() => { + assert_true(self.ran); + }); +}, "Evaled the script via Function, successful import"); + +promise_test(t => { + t.add_cleanup(() => { + self.ran = false; + }) + + return Promise.resolve(`return import("bad-specifier?2").catch(() => { self.ran = true; })`) + .then(Function) + .then(Function.prototype.call.bind(Function.prototype.call)) + .then(() => { + assert_true(self.ran); + }); +}, "Evaled the script via Function, failed import"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html new file mode 100644 index 0000000..316067c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html
@@ -0,0 +1,104 @@ +<!DOCTYPE html> +<title>Service Worker: Service-Worker-Allowed header</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="resources/test-helpers.sub.js"></script> +<script> + +const host_info = get_host_info(); + +// Returns a URL for a service worker script whose Service-Worker-Allowed +// header value is set to |allowed_path|. If |origin| is specified, that origin +// is used. +function build_script_url(allowed_path, origin) { + const script = 'resources/empty-worker.js'; + const url = origin ? `${origin}${base_path()}${script}` : script; + return `${url}?pipe=header(Service-Worker-Allowed,${allowed_path})`; +} + +promise_test(async t => { + const script = build_script_url('/allowed-path'); + const scope = '/allowed-path'; + const registration = await service_worker_unregister_and_register( + t, script, scope); + assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); + assert_equals(registration.scope, normalizeURL(scope)); + return registration.unregister(); +}, 'Registering within Service-Worker-Allowed path'); + +promise_test(async t => { + const script = build_script_url(new URL('/allowed-path', document.location)); + const scope = '/allowed-path'; + const registration = await service_worker_unregister_and_register( + t, script, scope); + assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); + assert_equals(registration.scope, normalizeURL(scope)); + return registration.unregister(); +}, 'Registering within Service-Worker-Allowed path (absolute URL)'); + +promise_test(async t => { + const script = build_script_url('../allowed-path-with-parent'); + const scope = 'allowed-path-with-parent'; + const registration = await service_worker_unregister_and_register( + t, script, scope); + assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); + assert_equals(registration.scope, normalizeURL(scope)); + return registration.unregister(); +}, 'Registering within Service-Worker-Allowed path with parent reference'); + +promise_test(async t => { + const script = build_script_url('../allowed-path'); + const scope = '/disallowed-path'; + await service_worker_unregister(t, scope); + return promise_rejects(t, + 'SecurityError', + navigator.serviceWorker.register(script, {scope: scope}), + 'register should fail'); +}, 'Registering outside Service-Worker-Allowed path'); + +promise_test(async t => { + const script = build_script_url('../allowed-path-with-parent'); + const scope = '/allowed-path-with-parent'; + await service_worker_unregister(t, scope); + return promise_rejects(t, + 'SecurityError', + navigator.serviceWorker.register(script, {scope: scope}), + 'register should fail'); +}, 'Registering outside Service-Worker-Allowed path with parent reference'); + +promise_test(async t => { + const script = build_script_url( + host_info.HTTPS_REMOTE_ORIGIN + '/'); + const scope = 'resources/this-scope-is-normally-allowed' + const registration = await service_worker_unregister_and_register( + t, script, scope); + assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); + assert_equals(registration.scope, normalizeURL(scope)); + return registration.unregister(); +}, 'Service-Worker-Allowed is cross-origin to script, registering on a normally allowed scope'); + +promise_test(async t => { + const script = build_script_url( + host_info.HTTPS_REMOTE_ORIGIN + '/'); + const scope = '/this-scope-is-normally-disallowed' + const registration = await service_worker_unregister_and_register( + t, script, scope); + assert_true(registration instanceof ServiceWorkerRegistration, 'registered'); + assert_equals(registration.scope, normalizeURL(scope)); + return registration.unregister(); +}, 'Service-Worker-Allowed is cross-origin to script, registering on a normally disallowed scope'); + +promise_test(async t => { + const script = build_script_url( + host_info.HTTPS_REMOTE_ORIGIN + '/cross-origin/', + host_info.HTTPS_REMOTE_ORIGIN); + const scope = '/cross-origin/'; + await service_worker_unregister(t, scope); + return promise_rejects(t, + 'SecurityError', + navigator.serviceWorker.register(script, {scope: scope}), + 'register should fail'); +}, 'Service-Worker-Allowed is cross-origin to page, same-origin to script'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js index b815442..f5ba5a3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-serviceworker.js
@@ -31,9 +31,18 @@ return; } - // (3) The worker does a fetch() to simple.txt. Indicate that this service + // (3) The worker does an importScripts() to import-scripts-echo.py. Indicate + // that this service worker handled the request. + if (evt.request.url.indexOf('import-scripts-echo.py') != -1) { + const msg = encodeURIComponent(`${name} saw importScripts from the worker`); + evt.respondWith(fetch(`import-scripts-echo.py?msg=${msg}`)); + return; + } + + // (4) The worker does a fetch() to simple.txt. Indicate that this service // worker handled the request. if (evt.request.url.indexOf('simple.txt') != -1) { evt.respondWith(new Response(`${name} saw the fetch from the worker`)); + return; } });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-webworker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-webworker.js index 7863af7..d602f23 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-webworker.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/worker-interception-redirect-webworker.js
@@ -18,11 +18,23 @@ if (!greeting) greeting = 'the shared worker script was served from network'; +// Call importScripts() which fills |echo_output| with a string indicating +// whether a service worker intercepted the importScripts() request. +let echo_output; +const import_scripts_msg = encodeURIComponent( + 'importScripts: served from network'); +const import_scripts_url = + new URL(`import-scripts-echo.py?msg=${import_scripts_msg}`, resources_url); +importScripts(import_scripts_url); +const import_scripts_greeting = echo_output; + self.onconnect = async function(e) { const port = e.ports[0]; port.start(); port.postMessage(greeting); + port.postMessage(import_scripts_greeting); + const fetch_url = new URL('simple.txt', resources_url); const response = await fetch(fetch_url); const text = await response.text();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt index 1f76f58..2529f00e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. PASS initialize global state FAIL request to sw1 scope gets network redirect to sw2 scope assert_equals: expected "the shared worker script was served from network" but got "sw2 saw the request for the worker script" -FAIL request to sw1 scope gets network redirect to out-of-scope assert_equals: expected "fetch(): sw1 saw the fetch from the worker" but got "fetch(): a simple text file\n" +FAIL request to sw1 scope gets network redirect to out-of-scope assert_equals: expected "sw1 saw importScripts from the worker" but got "importScripts: served from network" PASS request to sw1 scope gets service-worker redirect to sw2 scope -FAIL request to sw1 scope gets service-worker redirect to out-of-scope assert_equals: expected "fetch(): sw1 saw the fetch from the worker" but got "fetch(): a simple text file\n" +FAIL request to sw1 scope gets service-worker redirect to out-of-scope assert_equals: expected "sw1 saw importScripts from the worker" but got "importScripts: served from network" PASS cleanup global state Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https.html index 4e79eac1..654495f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/worker-interception-redirect.https.html
@@ -32,8 +32,8 @@ // 3. The request is redirected to scope2 or out-of-scope. // 4. The worker posts message to the page describing where the final response // was served from (service worker or network). -// 5. The worker does a fetch(), and posts back the response, which describes -// where the fetch response was served from. +// 5. The worker does an importScripts() and fetch(), and posts back the +// responses, which describe where the responses where served from. // // Currently this only tests shared worker but dedicated worker tests should be // added in a future patch. @@ -109,7 +109,8 @@ function worker_redirect_test(worker_url, expected_main_resource_message, - expected_subresource_message, + expected_import_scripts_message, + expected_fetch_message, description) { promise_test(async t => { // Create a frame to load the worker from. This way we can remove the frame @@ -126,43 +127,44 @@ const data = await get_message_from_worker(w); assert_equals(data, expected_main_resource_message); - // The worker does a fetch() after it starts up. Expect a message from the - // worker indicating which service worker provided the response for the - // fetch(), if any. - // - // Note: for some reason, Firefox would pass all these tests if a - // postMessage ping/pong step is added before the fetch(). I.e., if the - // page does postMessage() and the worker does fetch() in response to the - // ping, the fetch() is properly intercepted. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=1452528. (Chrome can't pass - // the tests either way.) - const message = get_message_from_worker(w); - const data2 = await message; - assert_equals(data2, expected_subresource_message); + // The worker does an importScripts(). Expect a message from the worker + // indicating which service worker provided the response for the + // importScripts(), if any. + const import_scripts_message = await get_message_from_worker(w); + assert_equals(import_scripts_message, expected_import_scripts_message); + + // The worker does a fetch(). Expect a message from the worker indicating + // which service worker provided the response for the fetch(), if any. + const fetch_message = await get_message_from_worker(w); + assert_equals(fetch_message, expected_fetch_message); }, description); } worker_redirect_test( build_worker_url('network', 'scope2'), 'the shared worker script was served from network', + 'sw1 saw importScripts from the worker', 'fetch(): sw1 saw the fetch from the worker', 'request to sw1 scope gets network redirect to sw2 scope'); worker_redirect_test( build_worker_url('network', 'out-scope'), 'the shared worker script was served from network', + 'sw1 saw importScripts from the worker', 'fetch(): sw1 saw the fetch from the worker', 'request to sw1 scope gets network redirect to out-of-scope'); worker_redirect_test( build_worker_url('serviceworker', 'scope2'), 'sw2 saw the request for the worker script', + 'sw2 saw importScripts from the worker', 'fetch(): sw2 saw the fetch from the worker', 'request to sw1 scope gets service-worker redirect to sw2 scope'); worker_redirect_test( build_worker_url('serviceworker', 'out-scope'), 'the shared worker script was served from network', + 'sw1 saw importScripts from the worker', 'fetch(): sw1 saw the fetch from the worker', 'request to sw1 scope gets service-worker redirect to out-of-scope'); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/upgrade-insecure-requests/link-upgrade.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/upgrade-insecure-requests/link-upgrade.sub.https.html index 6b315c8..46788e8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/upgrade-insecure-requests/link-upgrade.sub.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/upgrade-insecure-requests/link-upgrade.sub.https.html
@@ -2,6 +2,7 @@ <html> <head> + <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -56,7 +57,7 @@ }); }); - test.step_timeout(function(){test.force_timeout()}, 5000); + test.step_timeout(function(){test.force_timeout()}, 10000); } </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/harness/results.html b/third_party/WebKit/LayoutTests/fast/harness/results.html index c5777608..2fd1d29a 100644 --- a/third_party/WebKit/LayoutTests/fast/harness/results.html +++ b/third_party/WebKit/LayoutTests/fast/harness/results.html
@@ -326,6 +326,7 @@ <label id="CRASH"><input type="checkbox">Crash <span></span></label> <label id="TIMEOUT"><input type="checkbox">Timeout <span></span></label> <label id="TEXT"><input type="checkbox">Text failure <span></span></label> + <label id="HARNESS"><input type="checkbox">Harness failure <span></span></label> <label id="IMAGE"><input type="checkbox">Image failure <span></span></label> <label id="IMAGE_TEXT"><input type="checkbox">Image+text failure <span></span></label> <label id="SKIP"><input type="checkbox">Skipped <span></span></label> @@ -873,10 +874,14 @@ return test => { if (!queryFilter(test) || !textFilter(test)) return false; + let resultKey = test.is_testharness_test ? "HARNESS" : test.actualFinal; // Ignore all results except final one, or not? - if (!(test.actualFinal in this.resultCounts)) - this.resultCounts[test.actualFinal] = 0; - this.resultCounts[test.actualFinal]++; + if (!(resultKey in this.resultCounts)) + this.resultCounts[resultKey] = 0; + this.resultCounts[resultKey]++; + if (test.actualFinal == "TEXT" && test.is_testharness_test) { + return filterMap.has("HARNESS"); + } return filterMap.has(test.actualFinal); }; },
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt new file mode 100644 index 0000000..e7fea51 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt
@@ -0,0 +1,18 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "rect": [8, 8, 100, 100], + "reason": "appeared" + } + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/hdr/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/hdr/color-jpeg-with-color-profile-expected.png deleted file mode 100644 index 010e16b5..0000000 --- a/third_party/WebKit/LayoutTests/hdr/color-jpeg-with-color-profile-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions-expected.txt index 6cfaf4b..e50f0c6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions-expected.txt
@@ -107,7 +107,7 @@ Found: body Checking 'document [ 'bo' -Not Found: 'body'] +Found: 'body'], displayed as 'body' Checking 'function hey(should' Not Found: shouldNotFindThisFunction @@ -161,4 +161,77 @@ Checking 'fun' Found: function +Checking '"stringwithscary!@#$%^&*()\"'`~+-=".char' +Found: charAt + +Checking '("hello" + "goodbye").char' +Found: charAt + +Checking '({7: "string"})[3 + 4].char' +Found: charAt + +Checking 'cantTouchThis++; "string".char' +Found: charAt + +Checking 'cantTouchThis++ + "string".char' +Found: charAt + +Checking 'var x = "string".char' +Found: charAt + +Checking '({abc: 123}).a' +Found: abc + +Checking '{dontFindLabels: 123}.dont' +Not Found: dontFindLabels + +Checking 'const x = 5; {dontFindLabels: 123}.dont' +Not Found: dontFindLabels + +Checking 'const x = {abc: 123}.a' +Found: abc + +Checking 'x = {abc: 123}.' +Found: abc + +Checking '[1,2,3].j' +Found: join + +Checking 'document.body[{abc: "children"}.abc].' +Found: length + +Checking 'new Date.' +Found: UTC +Not Found: toUTCString + +Checking 'new Date().' +Not Found: UTC +Found: toUTCString + +Checking 'const x = {7: "hi"}[3+4].' +Found: anchor + +Checking '["length"]["length"].' +Found: toExponential + +Checking '(await "no completions").' +Not Found: toString + +Checking '(++cantTouchThis).' + +Checking '(cantTouchThis -= 2).' + +Checking 'new dontRunThis.' + +Checking 'new dontRunThis().' + +Checking '(new dontRunThis).' + +Checking '(dontRunThis`asdf`).' + +Checking 'dontRunThis().' + +Checking 'stall().' +error: Execution was terminated +
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions.js index 1da6a99a..abc03fe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-correct-suggestions.js
@@ -26,6 +26,13 @@ "'single-qouted'": true, "notDangerous();": true } + var cantTouchThis = false; + function dontRunThis() { + cantTouchThis = true; + } + function stall() { + while(true); + } `); var consoleEditor; @@ -35,7 +42,7 @@ * @param {!Array<string>} expected * @param {boolean=} force */ - function testCompletions(text, expected, force) { + async function testCompletions(text, expected, force) { var cursorPosition = text.indexOf('|'); if (cursorPosition < 0) @@ -44,35 +51,40 @@ consoleEditor.setText(text.replace('|', '')); consoleEditor.setSelection(TextUtils.TextRange.createFromLocation(0, cursorPosition)); consoleEditor._autocompleteController.autocomplete(force); - return TestRunner.addSnifferPromise(consoleEditor._autocompleteController, '_onSuggestionsShownForTest').then(checkExpected); + var message = + 'Checking \'' + text.replace('\n', '\\n').replace('\r', '\\r') + '\''; - /** - * @param {!Array<{text: string, title: string}>} suggestions - */ - function checkExpected(suggestions) { - var completions = new Map(suggestions.map(suggestion => [suggestion, suggestion.text])).inverse(); - var message = 'Checking \'' + text.replace('\n', '\\n').replace('\r', '\\r') + '\''; + if (force) + message += ' forcefully'; - if (force) - message += ' forcefully'; + TestRunner.addResult(message); + const suggestions = await TestRunner.addSnifferPromise( + consoleEditor._autocompleteController, '_onSuggestionsShownForTest'); + var completions = + new Map(suggestions.map(suggestion => [suggestion, suggestion.text])) + .inverse(); - TestRunner.addResult(message); - for (var i = 0; i < expected.length; i++) { - if (completions.has(expected[i])) { - for (var completion of completions.get(expected[i])) { - if (completion.title) - TestRunner.addResult('Found: ' + expected[i] + ', displayed as ' + completion.title); - else - TestRunner.addResult('Found: ' + expected[i]); - } - } else { - TestRunner.addResult('Not Found: ' + expected[i]); + for (var i = 0; i < expected.length; i++) { + if (completions.has(expected[i])) { + for (var completion of completions.get(expected[i])) { + if (completion.title) + TestRunner.addResult( + 'Found: ' + expected[i] + ', displayed as ' + completion.title); + else + TestRunner.addResult('Found: ' + expected[i]); } + } else { + TestRunner.addResult('Not Found: ' + expected[i]); } - - TestRunner.addResult(''); } + + if (await TestRunner.evaluateInPagePromise('cantTouchThis') !== false) { + TestRunner.addResult('ERROR! Side effects were detected!'); + await TestRunner.evaluateInPagePromise('cantTouchThis = false'); + } + + TestRunner.addResult(''); } function sequential(tests) { @@ -85,7 +97,8 @@ } sequential([ - () => ConsoleTestRunner.waitUntilConsoleEditorLoaded().then(e => consoleEditor = e), + () => ConsoleTestRunner.waitUntilConsoleEditorLoaded().then( + e => consoleEditor = e), () => testCompletions('window.do', ['document']), () => testCompletions('win', ['window']), () => testCompletions('window["doc', ['"document"]']), @@ -93,7 +106,9 @@ () => testCompletions('window["document"]["body"].textC', ['textContent']), () => testCompletions('document.body.inner', ['innerText', 'innerHTML']), () => testCompletions('document["body"][window.do', ['document']), - () => testCompletions('document["body"][window["document"].body.childNodes[0].text', ['textContent']), + () => testCompletions( + 'document["body"][window["document"].body.childNodes[0].text', + ['textContent']), () => testCompletions('templateString`asdf`should', ['shouldNotFindThis']), () => testCompletions('window.document.BODY', ['body']), () => testCompletions('window.dOcUmE', ['document']), @@ -109,10 +124,16 @@ () => testCompletions('["should', ['shouldNotFindThisFunction']), () => testCompletions('shou', ['should not find this']), () => testCompletions('myMap.get(', ['"first")', '"second")', '"third")']), - () => testCompletions('myMap.get(\'', ['\'first\')', '\'second\')', '\'third\')']), + () => testCompletions( + 'myMap.get(\'', ['\'first\')', '\'second\')', '\'third\')']), () => testCompletions('myMap.set(\'firs', ['\'first\', ']), - () => testCompletions('myMap.set(should', ['shouldFindThisFunction', 'shouldNotFindThis', '"shouldNotFindThis")']), - () => testCompletions('myMap.delete(\'', ['\'first\')', '\'second\')', '\'third\')']), + () => testCompletions( + 'myMap.set(should', + [ + 'shouldFindThisFunction', 'shouldNotFindThis', '"shouldNotFindThis")' + ]), + () => testCompletions( + 'myMap.delete(\'', ['\'first\')', '\'second\')', '\'third\')']), () => testCompletions('document. bo', ['body']), () => testCompletions('document.\tbo', ['body']), () => testCompletions('document.\nbo', ['body']), @@ -128,12 +149,44 @@ () => testCompletions('complicatedObject["foo', ['"foo-bar"]']), () => testCompletions('complicatedObject["foo-', ['"foo-bar"]']), () => testCompletions('complicatedObject["foo-bar', ['"foo-bar"]']), - () => testCompletions('complicatedObject["\'sing', ['"\'single-qouted\'"]']), - () => testCompletions('complicatedObject[\'\\\'sing', ['\'\\\'single-qouted\\\'\']']), - () => testCompletions('complicatedObject["\'single-qou', ['"\'single-qouted\'"]']), - () => testCompletions('complicatedObject["\\"double-qouted\\"', ['"\\"double-qouted\\""]']), - () => testCompletions('complicatedObject["notDangerous();', ['"notDangerous();"]']), - () => testCompletions('queryOb', ["queryObjects"]), - () => testCompletions('fun', ['function']) + () => + testCompletions('complicatedObject["\'sing', ['"\'single-qouted\'"]']), + () => testCompletions( + 'complicatedObject[\'\\\'sing', ['\'\\\'single-qouted\\\'\']']), + () => testCompletions( + 'complicatedObject["\'single-qou', ['"\'single-qouted\'"]']), + () => testCompletions( + 'complicatedObject["\\"double-qouted\\"', ['"\\"double-qouted\\""]']), + () => testCompletions( + 'complicatedObject["notDangerous();', ['"notDangerous();"]']), + () => testCompletions('queryOb', ['queryObjects']), + () => testCompletions('fun', ['function']), + () => testCompletions( + '"stringwithscary!@#$%^&*()\\"\'`~+-=".char', ['charAt']), + () => testCompletions('("hello" + "goodbye").char', ['charAt']), + () => testCompletions('({7: "string"})[3 + 4].char', ['charAt']), + () => testCompletions('cantTouchThis++; "string".char', ['charAt']), + () => testCompletions('cantTouchThis++ + "string".char', ['charAt']), + () => testCompletions('var x = "string".char', ['charAt']), + () => testCompletions('({abc: 123}).a', ['abc']), + () => testCompletions('{dontFindLabels: 123}.dont', ['dontFindLabels']), + () => testCompletions('const x = 5; {dontFindLabels: 123}.dont', ['dontFindLabels']), + () => testCompletions('const x = {abc: 123}.a', ['abc']), + () => testCompletions('x = {abc: 123}.', ['abc']), + () => testCompletions('[1,2,3].j', ['join']), + () => testCompletions('document.body[{abc: "children"}.abc].', ['length']), + () => testCompletions('new Date.', ['UTC', 'toUTCString']), + () => testCompletions('new Date().', ['UTC', 'toUTCString']), + () => testCompletions('const x = {7: "hi"}[3+4].', ['anchor']), + () => testCompletions('["length"]["length"].', ['toExponential']), + () => testCompletions('(await "no completions").', ['toString']), + () => testCompletions('(++cantTouchThis).', []), + () => testCompletions('(cantTouchThis -= 2).', []), + () => testCompletions('new dontRunThis.', []), + () => testCompletions('new dontRunThis().', []), + () => testCompletions('(new dontRunThis).', []), + () => testCompletions('(dontRunThis`asdf`).', []), + () => testCompletions('dontRunThis().', []), + () => testCompletions('stall().', []), ]).then(TestRunner.completeTest); })();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/modules-load-elements-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/modules-load-elements-expected.txt index 7874819..6f84aa0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/modules-load-elements-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/modules-load-elements-expected.txt
@@ -4,6 +4,7 @@ color_picker elements event_listeners + formatter inline_editor object_ui Now with animations pane
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/service-worker-allowed-worker.php b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/service-worker-allowed-worker.php deleted file mode 100644 index 0bd5d72c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/service-worker-allowed-worker.php +++ /dev/null
@@ -1,6 +0,0 @@ -<?php -header('Content-Type: application/javascript'); -if (isset($_GET['ServiceWorkerAllowed'])) { - header('Service-Worker-Allowed: ' . $_GET['ServiceWorkerAllowed']); -} -?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/service-worker-allowed.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/service-worker-allowed.html deleted file mode 100644 index 419b8a4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/service-worker-allowed.html +++ /dev/null
@@ -1,83 +0,0 @@ -<!DOCTYPE html> -<!-- This test should be upstreamed to WPT if an existing test - isn't there yet. ---> -<title>Service Worker: Service-Worker-Allowed header</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/get-host-info.js"></script> -<script src="resources/test-helpers.js"></script> -<script> - -var host_info = get_host_info(); - -promise_test(function(t) { - var script = 'resources/service-worker-allowed-worker.php' + - '?ServiceWorkerAllowed=/allowed-path'; - var scope = '/allowed-path'; - return navigator.serviceWorker.register(script, {scope: scope}) - .then(function(registration) { - assert_true( - registration instanceof ServiceWorkerRegistration, - 'Successfully registered.'); - assert_equals( - registration.scope, - normalizeURL(scope), - 'Registering within Service-Worker-Allowed path should pass'); - service_worker_unregister_and_done(t, scope); - }) - }, 'Registering within Service-Worker-Allowed path'); - -promise_test(function(t) { - var script = 'resources/service-worker-allowed-worker.php' + - '?ServiceWorkerAllowed=../allowed-path-with-parent'; - var scope = 'allowed-path-with-parent'; - return navigator.serviceWorker.register(script, {scope: scope}) - .then(function(registration) { - assert_true( - registration instanceof ServiceWorkerRegistration, - 'Successfully registered.'); - assert_equals( - registration.scope, - normalizeURL(scope), - 'Registering within Service-Worker-Allowed path with parent ' + - 'reference should pass'); - service_worker_unregister_and_done(t, scope); - }) - }, 'Registering within Service-Worker-Allowed path with parent reference'); - -promise_test(function(t) { - var script = 'resources/service-worker-allowed-worker.php' + - '?ServiceWorkerAllowed=/allowed-path'; - var scope = '/disallowed-path'; - return promise_rejects(t, - 'SecurityError', - navigator.serviceWorker.register(script, {scope: scope}), - 'Registering outside Service-Worker-Allowed path should fail'); - }, 'Registering outside Service-Worker-Allowed path'); - -promise_test(function(t) { - var script = 'resources/service-worker-allowed-worker.php' + - '?ServiceWorkerAllowed=../allowed-path-with-parent'; - var scope = '/allowed-path-with-parent'; - return promise_rejects(t, - 'SecurityError', - navigator.serviceWorker.register(script, {scope: scope}), - 'Registering outside Service-Worker-Allowed path with parent ' + - 'reference should fail'); - }, 'Registering outside Service-Worker-Allowed path with parent reference'); - -promise_test(function(t) { - var script = host_info.HTTPS_REMOTE_ORIGIN + - '/serviceworker/resources/' + - 'service-worker-allowed-worker.php' + - '?ServiceWorkerAllowed=' + - host_info.HTTP_REMOTE_ORIGIN + '/cross-origin/'; - var scope = '/cross-origin/'; - return promise_rejects(t, - 'SecurityError', - navigator.serviceWorker.register(script, {scope: scope}), - 'Registering cross-origin Service-Worker-Allowed should fail'); - }, 'Registering cross-origin Service-Worker-Allowed'); - -</script>
diff --git a/third_party/WebKit/LayoutTests/images/cHRM_color_spin-expected.png b/third_party/WebKit/LayoutTests/images/cHRM_color_spin-expected.png index a05298a..8f77312 100644 --- a/third_party/WebKit/LayoutTests/images/cHRM_color_spin-expected.png +++ b/third_party/WebKit/LayoutTests/images/cHRM_color_spin-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/images/color-jpeg-with-color-profile-expected.png index 977c381c..d416a0f 100644 --- a/third_party/WebKit/LayoutTests/images/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-animate-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-animate-expected.png index c34bf0f7..e2a4f45 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-animate-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-animate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-animate-rotate-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-animate-rotate-expected.png index cc3f2d5..b440db7 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-animate-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-animate-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-clip-text-expected.png index 12bc6570..ddc3ed7 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-background-clip-text-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-background-clip-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png index e0786182..ea3c052 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-image-repeat-expected.png index 7d888d9..96e0e064bf 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png index c5d0b0f0..6616565 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-border-fade-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-border-fade-expected.png index 5ae5650..f205c5e 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-border-fade-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-border-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-border-image-expected.png index e9925129..4dcd852 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-clip-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-clip-expected.png index 91aac89..485c157 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-clip-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-iframe-expected.png index 3c24c8e..4a74339 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-expected.png index 218f124d..69c072a 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-pattern-expected.png index 6f07c20..606ef99 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-image-object-fit-expected.png index ec2a82d..74b48b6 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-image-pseudo-content-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-image-pseudo-content-expected.png index 385f12f..91cf9a2 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-image-pseudo-content-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-image-pseudo-content-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-image-svg-resource-url-expected.png index a7328d1d..1fda3c6 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-layer-filter-expected.png deleted file mode 100644 index 3a67f62..0000000 --- a/third_party/WebKit/LayoutTests/images/color-profile-layer-filter-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-mask-image-svg-expected.png index 5a804fa..2652c65 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt index 33aac4f..d5d9e0d21 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -1,36 +1,36 @@ Color Actual Expected dE -------------------------------------------- -Dark Skin 114,80,64 115,80,64 1 +Dark Skin 115,80,64 115,80,64 0 Light Skin 195,150,130 195,151,130 1 -Blue Sky 94,123,156 94,123,156 0 -Foliage 88,108,65 88,108,65 0 +Blue Sky 94,123,157 94,123,156 1 +Foliage 89,108,65 88,108,65 1 Blue Flower 130,129,177 130,129,177 0 Bluish Green 100,190,171 100,190,171 0 -------------------------------------------- -Orange 217,121,37 217,122,37 1 -Purplish Blue 72,90,166 72,91,165 1 +Orange 216,122,37 217,122,37 1 +Purplish Blue 72,91,166 72,91,165 1 Moderate Red 194,84,97 194,84,98 1 -Purple 90,60,106 91,59,107 2 -Yellow Green 160,188,60 160,188,60 0 -Orange Yellow 231,163,42 230,163,42 1 +Purple 91,60,107 91,59,107 1 +Yellow Green 160,187,60 160,188,60 1 +Orange Yellow 230,163,42 230,163,42 0 -------------------------------------------- Blue 47,60,153 46,60,153 1 Green 70,149,69 71,150,69 1 -Red 177,45,56 177,44,56 1 +Red 177,44,56 177,44,56 0 Yellow 239,200,27 238,200,27 1 Magenta 187,82,147 187,82,148 1 -Cyan (*) 0,135,165 0,135,166 1 +Cyan (*) 0,135,166 0,135,166 0 -------------------------------------------- -White 243,242,236 243,242,237 1 -Neutral 8 202,202,200 201,201,201 2 +White 243,241,236 243,242,237 1 +Neutral 8 201,201,200 201,201,201 1 Neutral 6.5 160,161,160 161,161,161 1 -Neutral 5 123,121,120 122,122,121 2 +Neutral 5 123,122,121 122,122,121 1 Neutral 3.5 83,83,83 83,83,83 0 Black 50,50,50 50,49,50 1 -------------------------------------------- -Result: total RMS color error: 1.06 +Result: total RMS color error: 0.84 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-object-expected.png index 01bf3fd..0fc900f 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-svg-expected.png index 13240f5..1b3b00f 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-svg-foreign-object-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-svg-foreign-object-expected.png index b9d0f32..1f6702f 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-svg-foreign-object-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-svg-foreign-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/images/paletted-png-with-color-profile-expected.png index 46dcb35..2d73757 100644 --- a/third_party/WebKit/LayoutTests/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossless-expected.png b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossless-expected.png index b2eac244..07427f3e 100644 --- a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossless-expected.png +++ b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossless-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-alpha-expected.png b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-alpha-expected.png index 647765f..e110b42 100644 --- a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-alpha-expected.png +++ b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-alpha-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-expected.png b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-expected.png index 340a356..ef6f7f2 100644 --- a/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-expected.png +++ b/third_party/WebKit/LayoutTests/images/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt index 9b66622..023204c 100644 --- a/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt
@@ -3,24 +3,24 @@ -------------------------------------------- Dark Skin 115,80,64 115,80,64 0 Light Skin 195,151,130 195,151,130 0 -Blue Sky 93,123,156 94,123,156 1 +Blue Sky 94,123,156 94,123,156 0 Foliage 88,108,65 88,108,65 0 -Blue Flower 130,128,177 130,129,177 1 +Blue Flower 130,129,177 130,129,177 0 Bluish Green 100,190,171 100,190,171 0 -------------------------------------------- Orange 217,122,37 217,122,37 0 -Purplish Blue 71,91,165 72,91,165 1 -Moderate Red 194,83,98 194,84,98 1 -Purple 90,59,107 91,59,107 1 +Purplish Blue 72,91,165 72,91,165 0 +Moderate Red 194,84,98 194,84,98 0 +Purple 91,59,107 91,59,107 0 Yellow Green 160,188,60 160,188,60 0 Orange Yellow 230,163,42 230,163,42 0 -------------------------------------------- -Blue 47,60,153 46,60,153 1 +Blue 46,60,153 46,60,153 0 Green 71,150,69 71,150,69 0 Red 177,44,56 177,44,56 0 Yellow 238,200,27 238,200,27 0 Magenta 187,82,148 187,82,148 0 -Cyan (*) 35,134,166 0,135,166 35 +Cyan (*) 34,135,166 0,135,166 34 -------------------------------------------- White 243,242,237 243,242,237 0 Neutral 8 201,201,201 201,201,201 0 @@ -34,8 +34,8 @@ SG White 1/4 74,74,74 74,74,74 0 SG Black 4x 79,79,79 79,79,79 0 SG Black 2x 48,48,48 48,48,48 0 -SG Black 32,32,32 31,31,31 2 +SG Black 31,31,31 31,31,31 0 -------------------------------------------- -Result: total RMS color error: 0.58 +Result: total RMS color error: 0.00
diff --git a/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt709-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt709-to-srgb-expected.txt index d34b900..28fb191f 100644 --- a/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt709-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/media/color-profile-munsell-bt709-to-srgb-expected.txt
@@ -1,28 +1,28 @@ Color Actual Expected dE -------------------------------------------- -Dark Skin 114,80,64 115,80,64 1 -Light Skin 195,151,129 195,151,130 1 -Blue Sky 93,123,155 94,123,156 1 +Dark Skin 115,80,64 115,80,64 0 +Light Skin 195,151,130 195,151,130 0 +Blue Sky 94,123,156 94,123,156 0 Foliage 88,108,65 88,108,65 0 -Blue Flower 129,128,177 130,129,177 1 +Blue Flower 130,129,177 130,129,177 0 Bluish Green 100,190,171 100,190,171 0 -------------------------------------------- -Orange 218,122,37 217,122,37 1 -Purplish Blue 72,90,165 72,91,165 1 +Orange 217,122,37 217,122,37 0 +Purplish Blue 72,91,165 72,91,165 0 Moderate Red 194,84,98 194,84,98 0 -Purple 90,59,107 91,59,107 1 +Purple 91,59,107 91,59,107 0 Yellow Green 160,188,60 160,188,60 0 Orange Yellow 230,163,42 230,163,42 0 -------------------------------------------- Blue 46,60,153 46,60,153 0 -Green 71,150,68 71,150,69 1 +Green 72,150,69 71,150,69 1 Red 177,44,56 177,44,56 0 Yellow 238,200,28 238,200,27 1 Magenta 187,82,148 187,82,148 0 Cyan (*) 0,135,166 0,135,166 0 -------------------------------------------- -White 244,242,237 243,242,237 1 +White 243,242,237 243,242,237 0 Neutral 8 201,201,201 201,201,201 0 Neutral 6.5 161,161,161 161,161,161 0 Neutral 5 122,122,121 122,122,121 0 @@ -34,8 +34,8 @@ SG White 1/4 74,74,74 74,74,74 0 SG Black 4x 79,79,79 79,79,79 0 SG Black 2x 48,48,48 48,48,48 0 -SG Black 32,32,32 31,31,31 2 +SG Black 31,31,31 31,31,31 0 -------------------------------------------- -Result: total RMS color error: 0.68 +Result: total RMS color error: 0.26
diff --git a/third_party/WebKit/LayoutTests/media/color-profile-video-poster-image-expected.png b/third_party/WebKit/LayoutTests/media/color-profile-video-poster-image-expected.png index 6831dcc..459702f5 100644 --- a/third_party/WebKit/LayoutTests/media/color-profile-video-poster-image-expected.png +++ b/third_party/WebKit/LayoutTests/media/color-profile-video-poster-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/media/controls/modern/immersive-mode-adds-css-class.html b/third_party/WebKit/LayoutTests/media/controls/modern/immersive-mode-adds-css-class.html new file mode 100644 index 0000000..e221204d --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/modern/immersive-mode-adds-css-class.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<title>Test that enabling immersive mode adds the immersive mode CSS class.</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../media-controls.js"></script> +<video controls width=400 preload=metadata src="../../content/60_sec_video.webm"></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + const controls = mediaControls(video); + const immersiveModeCSSClass = "immersive-mode"; + + window.onload = t.step_func_done(() => { + assert_false(controls.classList.contains(immersiveModeCSSClass)); + enableImmersiveMode(t); + assert_true(controls.classList.contains(immersiveModeCSSClass)); + }); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/media-controls.js b/third_party/WebKit/LayoutTests/media/media-controls.js index 7276a0b..9cf97e5b 100644 --- a/third_party/WebKit/LayoutTests/media/media-controls.js +++ b/third_party/WebKit/LayoutTests/media/media-controls.js
@@ -512,3 +512,14 @@ if (window.internals) window.internals.setMediaControlsTestMode(video, true); } + +function enableImmersiveMode(t) { + if (!window.internals) + return; + + const oldImmersive = internals.settings.immersiveModeEnabled; + internals.settings.setImmersiveModeEnabled(true); + t.add_cleanup(() => { + window.internals.settings.setImmersiveModeEnabled(oldImmersive); + }); +}
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.html new file mode 100644 index 0000000..b94a0d1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div id="target" style="width: 100px; height: 100px; background: green; opacity: 0.5; will-change: transform"></div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.txt new file mode 100644 index 0000000..ecf68fdd --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited-expected.txt
@@ -0,0 +1,30 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow DIV id='target'", + "position": [8, 8], + "bounds": [100, 100], + "opacity": 0.5, + "contentsOpaque": true, + "backgroundColor": "#008000" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited.html new file mode 100644 index 0000000..6bb40bda --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/opacity-from-zero-to-non-zero-composited.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<div id="target" style="width: 100px; height: 100px; background: green; opacity: 0; will-change: opacity"></div> +<script src="../resources/text-based-repaint.js"></script> +<script> +function repaintTest() { + target.style.opacity = 0.5; +}; +onload = runRepaintAndPixelTest; +</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.html new file mode 100644 index 0000000..7b1d9694 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div id="target" style="width: 100px; height: 100px; background: green; opacity: 0.5"></div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt new file mode 100644 index 0000000..4bd0fc5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt
@@ -0,0 +1,29 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "rect": [8, 8, 100, 100], + "reason": "appeared" + } + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero.html b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero.html new file mode 100644 index 0000000..80fb10dc --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/opacity-from-zero-to-non-zero.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<div id="target" style="width: 100px; height: 100px; background: green; opacity: 0"></div> +<script src="resources/text-based-repaint.js"></script> +<script> +function repaintTest() { + target.style.opacity = 0.5; +}; +onload = runRepaintAndPixelTest; +</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png index 4841a87..fb4433a7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png index 723f8df..913be2b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png index 0d869b19c..f1a95e0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png index 2e5f8b90..46b2d26e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png index 9882b271..4823308 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png index 6697ab3..8fb52af 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png index 6697ab3..8fb52af 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png index 76955539..cdce972 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png index 652b7737..392453f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/relative-sized-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/relative-sized-image-expected.png index d3186cd..c96075f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/relative-sized-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/relative-sized-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index a3b73b5..609b97d3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png index 46ab63e..3393729 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index d1b1832..68c9ffb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 4eefb21..b6235f4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index 8d19156..a1ae12c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png index b224436e..238407ab 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.png index 909a964..b960b019 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png index 013dee13..c69f29e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.png index ebe27866..659d31bc 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/as-border-image/svg-as-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 0ba5f13..fa08e8c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 0ba5f13..fa08e8c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index ce9e386..7c9749a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/compositing/color-matching/image-color-matching-expected.png index 4841a87..fb4433a7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/relative-sized-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/relative-sized-image-expected.png index d3186cd..c96075f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/relative-sized-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/relative-sized-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index eddae93..3d5cc67 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png index 5acdf50f..76129de 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/182-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/182-expected.png index e6dd827a..8990f01 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png index 6021ce36e..64a6d47 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png index 919d5262..b6d4fa3a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/55-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/55-expected.png index 4a87365..f4dff0b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/alt-text-wrapping-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/alt-text-wrapping-expected.png index 1623f55..c63299c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/alt-text-wrapping-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/alt-text-wrapping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png index 49a5215..3f1ea99 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-shape-expected.png index 2d7fb3e..ef85bd5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index cbdd646d..146fb0c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index 1f0c7f9..b6d0183e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png index f4aaabc..5f1ce9a9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 5f8e12e..43f64621 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index 6ab0387..fb927f7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png index e203d9c..02f84f3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png index 2b62469..4a6e8ab 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png index 557780d..f8e945294 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 186f75d..5ed844d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png index b31a1555..c7dbd7d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index 3f82e16..d11b4b18 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png index d0f0a82..651f10e0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png index c37de0c..f3e5e7c2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png index 222cdc0..c6bad0b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/png-with-color-profile-expected.png index c37de0c..f3e5e7c2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png index ecc77c5..815fa00 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png index 123d4cc..1220492 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png index 6a0fc82b..379a0ff 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png index 77f19e9..f01d135 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png index a9185ba..e096b1a9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png index 8b99842..f19511ae 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png index 06d5b77..bcda162b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png index 51cf7a48..c448dc7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index 0ee153b..b62f060 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png index 46ab63e..3393729 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png index 81ed3529..d784298 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png index 08343bfa..0116084e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/12-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/12-55-expected.png index 28f50cd0..d519c40 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/182-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/182-expected.png index 778d6e47..c6e501582 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/2-dht-expected.png index cbe4ccc..cdc744ff 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/23-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/23-55-expected.png index 1d062a1..159be384 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/55-expected.png index b72a10f5..19a279a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index be03ed5a..465ab0f0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index b40aea6f..1e03484 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png index 1c785bd..87e7fb20 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png index e00db5a..c31892b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/12-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/12-55-expected.png index 591353d..3fbb622b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/182-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/182-expected.png index c401715..fd5780f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/2-dht-expected.png index 8c665b5..eaa1507 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/23-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/23-55-expected.png index 63a6c77..7db18a5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/55-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/55-expected.png index 15cc6a27..33b6f83 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/color-matching/image-color-matching-expected.png index 46ef26a..e3d8337e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png index 576c31e..616c172 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.txt index a7360dab..91f30ef 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.txt
@@ -3,20 +3,28 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutImage {IMG} at (0,0) size 160x90 LayoutText {#text} at (160,76) size 4x18 text run at (160,76) width 4: " " + LayoutImage {IMG} at (164,0) size 160x90 LayoutText {#text} at (324,76) size 4x18 text run at (324,76) width 4: " " + LayoutImage {IMG} at (328,0) size 160x90 LayoutText {#text} at (488,76) size 4x18 text run at (488,76) width 4: " " + LayoutImage {IMG} at (492,0) size 160x90 LayoutText {#text} at (652,76) size 4x18 text run at (652,76) width 4: " " + LayoutImage {IMG} at (0,94) size 160x90 LayoutText {#text} at (160,170) size 4x18 text run at (160,170) width 4: " " + LayoutImage {IMG} at (164,94) size 160x90 LayoutText {#text} at (324,170) size 4x18 text run at (324,170) width 4: " " + LayoutImage {IMG} at (328,94) size 160x90 LayoutText {#text} at (488,170) size 4x18 text run at (488,170) width 4: " " + LayoutImage {IMG} at (492,94) size 160x90 LayoutText {#text} at (652,170) size 4x18 text run at (652,170) width 4: " " LayoutText {#text} at (160,264) size 4x18 @@ -26,22 +34,6 @@ LayoutText {#text} at (488,264) size 4x18 text run at (488,264) width 4: " " LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 160x90 - LayoutImage {IMG} at (0,0) size 160x90 -layer at (172,8) size 160x90 - LayoutImage {IMG} at (164,0) size 160x90 -layer at (336,8) size 160x90 - LayoutImage {IMG} at (328,0) size 160x90 -layer at (500,8) size 160x90 - LayoutImage {IMG} at (492,0) size 160x90 -layer at (8,102) size 160x90 - LayoutImage {IMG} at (0,94) size 160x90 -layer at (172,102) size 160x90 - LayoutImage {IMG} at (164,94) size 160x90 -layer at (336,102) size 160x90 - LayoutImage {IMG} at (328,94) size 160x90 -layer at (500,102) size 160x90 - LayoutImage {IMG} at (492,94) size 160x90 layer at (8,196) size 160x90 LayoutImage {IMG} at (0,188) size 160x90 layer at (172,196) size 160x90
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png index 4e87f450..e31882c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.txt index 0b04f481..f9f99a4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.txt
@@ -3,10 +3,13 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutImage {IMG} at (0,0) size 160x90 LayoutText {#text} at (160,76) size 4x18 text run at (160,76) width 4: " " + LayoutImage {IMG} at (164,0) size 160x90 LayoutText {#text} at (324,76) size 4x18 text run at (324,76) width 4: " " + LayoutImage {IMG} at (328,0) size 160x90 LayoutText {#text} at (488,76) size 4x18 text run at (488,76) width 4: " " LayoutText {#text} at (652,76) size 4x18 @@ -16,12 +19,6 @@ LayoutText {#text} at (324,170) size 4x18 text run at (324,170) width 4: " " LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 160x90 - LayoutImage {IMG} at (0,0) size 160x90 -layer at (172,8) size 160x90 - LayoutImage {IMG} at (164,0) size 160x90 -layer at (336,8) size 160x90 - LayoutImage {IMG} at (328,0) size 160x90 layer at (500,8) size 160x90 LayoutImage {IMG} at (492,0) size 160x90 layer at (8,102) size 160x90
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-landscape-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-landscape-expected.png index b709b30..bdee278 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-landscape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-landscape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-portrait-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-portrait-expected.png index 9cde360..2450010f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-portrait-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/object-fit-grow-portrait-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/hdr/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/hdr/color-jpeg-with-color-profile-expected.png index dc798e6..b0157304 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/hdr/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/hdr/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-expected.png index 730f5689..3f444f3b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-png-expected.png index 730f5689..3f444f3b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-radius-expected.png index 75b980ef..536ad6b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-drag-image-expected.png index 4041fbf..1877f1a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-filter-expected.png index f35a381..0a1cce7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png index 04354ed..4599e3a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-canvas-svg-expected.png index fa863df7..b74c1f2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-expected.png index fdb2bd3..ce87d12 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-filter-all-expected.png index 1dcba1c..21762069 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-shape-expected.png index 18e442a..36f844d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-expected.png index 62a796c..6be5860b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-filter-expected.png index 0328d65..bc98a2d98 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png index e271aa1..70e5c536 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png index 5773e7e..0420e36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png index a8d5804..59603e2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/jpeg-with-color-profile-expected.png index a910e01..081fb43d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/png-suite/test-expected.png index 52971d4..1ba0f6a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/png-with-color-profile-expected.png index a910e01..081fb43d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png index e5b63e7..c47cc4b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt709-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt709-to-srgb-expected.png index ef22cc73..00f1817 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt709-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/color-profile-munsell-bt709-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/relative-sized-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/relative-sized-image-expected.png index 264692c9..98f9c11 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/relative-sized-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/relative-sized-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 7b62bbe..0c178899 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/mac/scrollbars/listbox-scrollbar-combinations-expected.png index ef18458..5c6a2d6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index 338ab9c9..2d06e16 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index c6305ab0..1081f954 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index 64fe637..feab784 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-03-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-03-t-expected.png index 1eacfb57..9656eb97 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-03-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/render-groups-03-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-06-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-06-t-expected.png index 5512436..5c624f3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-06-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-06-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-use-01-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-use-01-t-expected.png index 8989246..e42df63 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-use-01-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-use-01-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 33fbbe3c..2a707a8a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 33fbbe3c..2a707a8a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index 48d301818..dc07743 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/12-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/12-55-expected.png index b97be9a..81624be4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/182-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/182-expected.png index 9151d5cf..e95d6ba 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-comp-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-comp-expected.png index a9fd056..41cbc00 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-comp-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-comp-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-dht-expected.png index 0e84053..1dfbbac2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/23-55-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/23-55-expected.png index 42a15c7..219b98c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/55-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/55-expected.png index 8052391..009168c9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/alt-text-wrapping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/alt-text-wrapping-expected.png index 45b76a9..66552c89 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/alt-text-wrapping-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/alt-text-wrapping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cHRM_color_spin-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cHRM_color_spin-expected.png index ee9fc669..3cb080e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cHRM_color_spin-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cHRM_color_spin-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png index 7c21747..c701ee4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-expected.png index 0997ad0..f3d9aa21 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png index 93f8770..daab984 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png index 64946df..e8fb9f9d9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png index da1c765..0781009 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png index b98803b..278d2e6df 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png index b98803b..278d2e6df 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png index 138fb41..8634ca6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png index d99d4a1..be583ed 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-fade-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-fade-expected.png index 406b718..6262b35 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-expected.png index ca30f5d..d1aca332 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png index 656f25aa..eba2d9c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-radius-expected.png index 932bd71..f85bc2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-clip-expected.png index 680b124..297bba0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-drag-image-expected.png deleted file mode 100644 index 4041fbf..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-drag-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-filter-expected.png index 5a70f85..4302394e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png index e225a5f..1856caf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-iframe-expected.png index 4f70dc0..bf161fcc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png index ef1be3c..ac35d8e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png index c6a4f79..1acaed7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png index 7267722..a3c2794 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-expected.png index 4bed735..a381e34 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png index 0279054..e95f500 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png index df3e270ca..5a0af8e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png index 9003dca..2aa916d1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png index 0a170e9..f2898ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-shape-expected.png index 4680b08..d37198ed 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png index 3cbd3d7..c9e2d6f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-expected.png index 2f510006..9d78f301 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png index b48bc5a6..a6d7edc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png index 7449e80..e4b8d82 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index 7f4acd95..3db5261 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index 1133257..d9f6c808 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-object-expected.png index 5c3be24..4d3b985e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png index 36269ac3..578b7a2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png index 9acc6c6..a04312d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png index cbce017..2e453376 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png index 2e8c738..3bba5d2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png index 11bca861..c49ba960 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 5e39cd2..7320fa0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index 3d332f5..5b61c57 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/embed-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/embed-image-expected.png index 557fbb3..d000f36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/embed-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/embed-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-css-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-css-expected.png index 7697c5a..b8414e68 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-css-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-css-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-expected.png index 4662b0e3..789fe889 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png index acd6518..d50d8724 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png index 8755b31..c74b396 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png index da8ac52..ee14aa9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png index 2e5e3e9b..dd8768a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/icon-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/icon-decoding-expected.png index 52febaa..8a57593e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/icon-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/icon-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-in-map-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-in-map-expected.png index bde325f..4ff8833 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-in-map-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-in-map-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index b34c61e..2cb722d6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png index 316c7d1c..efcc8723 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index 30303d4..88db8a08 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png index 0071cba..b94f296 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png index d0b7a86..f3ef323 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png index f8c7ce0..ce0bc62e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png index 1d27571..1dae169b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png index 60a01a45..ff0cbdec 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png index d4419933..6b76056 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/object-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/object-image-expected.png index 557fbb3..d000f36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/object-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/object-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/optimize-contrast-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/optimize-contrast-image-expected.png index 31a5791..85002138 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/optimize-contrast-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/optimize-contrast-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png index 0ef5ffa..04a2e9f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-background-image-expected.png index e935025..1fb2cb9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-background-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-background-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-image-expected.png index 96a38aca..f9f84b5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-svg-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-svg-image-expected.png index 96a38aca..f9f84b5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-svg-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/pixelated-svg-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-suite/test-expected.png index d9bbf08..155f1acf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-with-color-profile-expected.png index d0b7a86..f3ef323 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png index 37b3534..e7605307 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png index 3c2cd91..4548b6a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png index e9252f82..3db20885 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png index ad5e60d..8b4b1a69 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png index 88ac75a..2bc7ee52 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png index 9e7c7b93..26c72e27 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png index c23e220..307b3c4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-expected.png index a682476..659d9a8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rendering-broken-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png index a73dfa00..d08b972 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png index 55ccac0..9477d1c0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png index 4768b44b..e2c3a47b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png index 8def3fc1..3291d1c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png index e80354db..e092eae 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png index 39fad3f0..90b6c01c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png deleted file mode 100644 index 4041fbf..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png index b07fb43b..d5a320b2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png index a247452..2c7240b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index 91e8ebe..56bc7239 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png index 6629831..95cfee37 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.png deleted file mode 100644 index 7ff4f1fb..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-clamping-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.png deleted file mode 100644 index bc170793..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-brightness-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-landscape-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-landscape-expected.png index e1a9ecf..2c8735a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-landscape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-landscape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-portrait-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-portrait-expected.png index a336166..990e6aa 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-portrait-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/object-fit-grow-portrait-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/hdr/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/hdr/color-jpeg-with-color-profile-expected.png new file mode 100644 index 0000000..4b4f516 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/hdr/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png index 462ff19..1791e22 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png index 462ff19..1791e22 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png index 6bd21bd4..8819722 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png index 2cabbc5..559bc71 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png index 1006e4e8..e4ebd49 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png index 61f2f036..9509441 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png index c6175ef..37d1018 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png index 41f18a4..b626c2fd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png index cc8f2a8..33e8b7a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png index 73bfa97..ba91fe5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-expected.png index 773fe03..9ba26be 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png new file mode 100644 index 0000000..f8474a4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png index adc1e7e..945f5f86 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png index 7d0f474..0fc6fb9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png index 110f0905..2e31f1d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png index dc6e487..73fc748 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png index 6a46e06..d87ed9d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png index dc6e487..73fc748 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png index b39df69..56fed97 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png index 7536943..a57a704 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/relative-sized-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/relative-sized-image-expected.png index c6982de6..4032f40 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/relative-sized-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/relative-sized-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 1438968..b3c4353 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png index bca7646..db7c0fa 100644 --- a/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index e16c166..3d68e10 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 4cfc291bc..3ef52ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index 2d01404..dea0407 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png index 189e179..5fac091a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.png index 294778293..3b360771 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png index 0c9c64a..0817841 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.png index f93e22e..a741647 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/as-border-image/svg-as-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 32621864..321b79b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 32621864..321b79b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index fb208257..7ad92b8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/embed-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png similarity index 62% rename from third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/embed-image-expected.png rename to third_party/WebKit/LayoutTests/platform/win/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png index 7de47b7..82a9934 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/embed-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/12-55-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/12-55-expected.png index 85d800d..a4fa8ba9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/182-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/182-expected.png index dcd5193..bb007d7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-comp-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-comp-expected.png index f91ad61..ed6cabc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-comp-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-comp-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-dht-expected.png index 355a5ef..5644139 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/23-55-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/23-55-expected.png index 1c51798..7ce6c74 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/55-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/55-expected.png index 1a56e13..7d6d863 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/alt-text-wrapping-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/alt-text-wrapping-expected.png index d686f21c..f25fae3a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/alt-text-wrapping-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/alt-text-wrapping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cHRM_color_spin-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cHRM_color_spin-expected.png index 416770e..ba190996 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cHRM_color_spin-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cHRM_color_spin-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png index 55facf1..625cebe6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-expected.png index b97b58cb..b89a6cea 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png index b9539943..43d32f378 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-animate-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png index a510c6a..604b6ba 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png index 05fa6fd..e034550f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png index f088e1c6..aa09b7e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png index f088e1c6..aa09b7e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png index a0985bef..9efd713 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png index dcb0a110..82de4cc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-expected.png index b6f705a..3698134 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png index e5e9afe..d3c5f894 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-radius-expected.png index e3f1e4f6b..1af2cae 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-clip-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-clip-expected.png index 4b95886..71bd9eb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png deleted file mode 100644 index 2cabbc5..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-drag-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-filter-expected.png index 1131e67..edf22e9d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png index d6af957..da83da3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-iframe-expected.png index ef00d05..51ba7d8c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png index 7ad48ab..a06941a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png index 8795e47..984d56f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png index f7b6c8c9..df7348e5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-expected.png index 0f4d904..e10c55fa 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png index a66da2f..ab61329 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png index 8de832b..8c2dc00 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png index ba531d4f..472e5b1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-profile-match-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png index 8dafd58b2..5edd28c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-pseudo-content-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-shape-expected.png index 03d92b9..a315ecb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png index b23c684b..884bb811 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png index cb1053e..7feaec5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png index 18116b2..0cf8fae 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png index 63e8efb..dc59b33 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index 4510056d..159484f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index 4f2d82d..b47a2070 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-object-expected.png index d62b027..d2212ca 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png index 215a67b..def379a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png index d23c017..c39c534 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png index 57e0e8e..f739a06 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-foreign-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png index 18f3390..1cd9f2d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png index d002a41f..40e51f7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 810abe1..5bdaf81 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index 833ec0f..c631562 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/embed-image-expected.png similarity index 64% rename from third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png rename to third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/embed-image-expected.png index e9ab31c5d..7271cb0 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/embed-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-css-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-css-expected.png index 968dab9..f2fa05b87 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-css-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-css-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-expected.png index 2b5db08..f834a47c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png index 0f12397..0e7c0995 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png index 8582f36..bb4dc1f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png index 91aa9b1..488290b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png index 5e295e4..628dd7a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/gray-scale-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/icon-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/icon-decoding-expected.png index f0a0074..7177158 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/icon-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/icon-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-in-map-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-in-map-expected.png index bff28676..c886d37 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-in-map-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-in-map-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 450008d15..608f7225 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png index 8e50d8e7..0b2b524 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index ef4d877..36691a2f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png index ea2ebfa6..bae8603 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png index 7281be9c8..97400ee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png index ae99322..16a687b8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-image-decoding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png index 665b7b2b..d2d3a16 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png index 2eaf859..ae862e5e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/missing-image-border-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png index 2920bca..ea84319 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/motion-jpeg-single-frame-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/object-image-expected.png similarity index 64% copy from third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png copy to third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/object-image-expected.png index e9ab31c5d..7271cb0 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/pixelated-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/object-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/optimize-contrast-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/optimize-contrast-image-expected.png index 1ea2d6c9..5fd83fd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/optimize-contrast-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/optimize-contrast-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png index 466af017..c0e6c3f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-background-image-expected.png index 453b2e7..bd9bf417 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-background-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-background-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-image-expected.png index fefe80ea..c29bcde 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-svg-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-svg-image-expected.png index fefe80ea..c29bcde 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-svg-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/pixelated-svg-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-suite/test-expected.png index 72214f2..5ec9c68a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-with-color-profile-expected.png index 7281be9c8..97400ee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png index 2c0ba59..c43a2b2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png index 3174ad71..dd6d96b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png index 897bc47..5af1de591 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png index e1ee6ed4..698e209 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png index 6ba45f7..2472af7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png index a224c58a..613ac8d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png index aa100b88..3b020b45 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-empty-alt-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-expected.png index 145aaba..b3f5833 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rendering-broken-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png index 3e222979..33c62b9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-jpeg-with-adobe-marker-only-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png index 3756bd7d..4ed84b7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/rgb-png-with-cmyk-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png index a469759b..f5bdfa6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossless-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png index e72e869..1a1eef6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-alpha-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png index 86c0697..e6f4d463 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png index e4524ab..cb484f3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/ycbcr-with-cmyk-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png index a2299bd..42c21f6d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png index dd08d51..968c9ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index 3f5a57e..c60e8a8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index dc25387..b984ef5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index dde633d..e7145f7 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png index 5b79efb..d0df32fc 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png index 5b79efb..d0df32fc 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/as-image/image-preserveAspectRatio-all-expected.png b/third_party/WebKit/LayoutTests/svg/as-image/image-preserveAspectRatio-all-expected.png index 5e28f16..9156792 100644 --- a/third_party/WebKit/LayoutTests/svg/as-image/image-preserveAspectRatio-all-expected.png +++ b/third_party/WebKit/LayoutTests/svg/as-image/image-preserveAspectRatio-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/group-opacity-expected.png b/third_party/WebKit/LayoutTests/svg/custom/group-opacity-expected.png index 98607db..b0a2d82 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/group-opacity-expected.png +++ b/third_party/WebKit/LayoutTests/svg/custom/group-opacity-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectRatio-all-expected.png index 85036846..14251b69 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectRatio-all-expected.png +++ b/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectRatio-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectratio-expected.png b/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectratio-expected.png index 3d0de88b..9c05380 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectratio-expected.png +++ b/third_party/WebKit/LayoutTests/svg/filters/feImage-preserveAspectratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/filters/filter-source-position-expected.png b/third_party/WebKit/LayoutTests/svg/filters/filter-source-position-expected.png index 15b5d1c5..3392c33 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/filter-source-position-expected.png +++ b/third_party/WebKit/LayoutTests/svg/filters/filter-source-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/filters/filteredImage-expected.png b/third_party/WebKit/LayoutTests/svg/filters/filteredImage-expected.png index ade998f..ebceb68b 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/filteredImage-expected.png +++ b/third_party/WebKit/LayoutTests/svg/filters/filteredImage-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png deleted file mode 100644 index 9d4fec8..0000000 --- a/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/toDataURL-color-managed-round-trip-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/disable-spv175/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt b/third_party/WebKit/LayoutTests/virtual/disable-spv175/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt new file mode 100644 index 0000000..14e45807 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/disable-spv175/paint/invalidation/opacity-from-zero-to-non-zero-expected.txt
@@ -0,0 +1,35 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "rect": [8, 8, 100, 100], + "reason": "subtree" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "reason": "subtree" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-simple-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-simple-expected.png index 8e7f901..5a8e74c 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-simple-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-simple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-sizing-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-sizing-expected.png index 7352347..fafc52b0 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-sizing-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-sizing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/gif-short-app-extension-string-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/gif-short-app-extension-string-expected.png index e6345867..f44ff0a6 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/gif-short-app-extension-string-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/gif-short-app-extension-string-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/object-image-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/object-image-expected.png deleted file mode 100644 index 7de47b7..0000000 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/object-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/png-color-profile-ignore-gamma-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/png-color-profile-ignore-gamma-expected.png index 7afe737a..3017e77 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/png-color-profile-ignore-gamma-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/png-color-profile-ignore-gamma-expected.png Binary files differ
diff --git a/third_party/WebKit/Tools/Scripts/merge-layout-test-results b/third_party/WebKit/Tools/Scripts/merge-layout-test-results index 1b0d6b0..41865e7f 100755 --- a/third_party/WebKit/Tools/Scripts/merge-layout-test-results +++ b/third_party/WebKit/Tools/Scripts/merge-layout-test-results
@@ -4,226 +4,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import argparse -import json -import logging -import os -import stat -import shutil import sys -import tempfile -import time -from webkitpy.common.system.filesystem import FileSystem -from webkitpy.common.system.log_utils import configure_logging -from webkitpy.layout_tests import merge_results +from webkitpy.layout_tests.merge_results import main -# The output JSON has the following arguments overwritten with a value from -# build properties. This occurs when '--build-properties' argument is provided -# and is mainly used when merging on build bots to provide better information -# about the build to the test results server. -# Format is a list of ('result json key', 'build property key'). -RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY = [ - ("build_number", "buildnumber"), - ("builder_name", "buildername"), - ("chromium_revision", "got_revision_cp"), -] - - -# ------------------------------------------------------------------------ -def ensure_empty_dir(fs, directory, allow_existing, remove_existing): - """Ensure an empty directory exists. - - Args: - allow_existing (bool): Allow the empty directory to already exist. - remove_existing (bool): Remove the contents if the directory - already exists. - """ - if not fs.exists(directory): - fs.maybe_make_directory(directory) - return - - logging.warning('Output directory exists %r', directory) - if not allow_existing: - raise IOError( - ('Output directory %s exists!\n' - 'Use --allow-existing-output-directory to continue') % directory) - - if remove_existing and not fs.remove_contents(directory): - raise IOError( - ('Unable to remove output directory %s contents!\n' - 'See log output for errors.') % directory) - - -def main(argv): - - parser = argparse.ArgumentParser() - parser.description = """\ -Merges sharded layout test results into a single output directory. -""" - parser.epilog = """\ - -If a post merge script is given, it will be run on the resulting merged output -directory. The script will be given the arguments plus -'--results_dir <output_directory>'. -""" - - parser.add_argument( - '-v', '--verbose', action='store_true', - help='Output information about merging progress.') - - parser.add_argument( - '--results-json-override-value', - nargs=2, metavar=('KEY', 'VALUE'), default=[], - action='append', - help='Override the value of a value in the result style JSON file ' - '(--result-jsons-override-value layout_test_dirs /tmp/output).') - parser.add_argument( - '--results-json-allow-unknown-if-matching', - action='store_true', default=False, - help='Allow unknown values in the result.json file as long as the ' - 'value match on all shards.') - - parser.add_argument( - '--output-directory', - help='Directory to create the merged results in.') - parser.add_argument( - '--allow-existing-output-directory', - action='store_true', default=False, - help='Allow merging results into a directory which already exists.') - parser.add_argument( - '--remove-existing-output-directory', - action='store_true', default=False, - help='Remove merging results into a directory which already exists.') - parser.add_argument( - '--input-directories', nargs='+', - help='Directories to merge the results from.') - - # Swarming Isolated Merge Script API - # script.py \ - # --build-properties /s/build.json \ - # --output-json /tmp/output.json \ - # --task-output-dir /path/to/task/output/dir \ - # shard0/output.json \ - # shard1/output.json - parser.add_argument( - '-o', '--output-json', - help='(Swarming Isolated Merge Script API) Output JSON file to create.') - parser.add_argument( - '--build-properties', - help='(Swarming Isolated Merge Script API) Build property JSON file provided by recipes.') - parser.add_argument( - '--task-output-dir', - help='(Swarming Isolated Merge Script API) Directory containing all swarming task results.') - parser.add_argument( - '--results-json-override-with-build-property', - nargs=2, metavar=('RESULT_JSON_KEY', 'BUILD_PROPERTY_KEY'), default=[], - action='append', - help='Override the value of a value in the result style JSON file ' - '(--result-jsons-override-value layout_test_dirs /tmp/output).') - parser.add_argument( - '--summary-json', - help='(Swarming Isolated Merge Script API) Summary of shard state running on swarming.' - '(Output of the swarming.py collect --task-summary-json=XXX command.)') - - # Script to run after merging the directories together. Normally used with archive_layout_test_results.py - # scripts/slave/chromium/archive_layout_test_results.py \ - # --results-dir /b/rr/tmpIcChUS/w/layout-test-results \ - # --build-dir /b/rr/tmpIcChUS/w/src/out \ - # --build-number 3665 \ - # --builder-name 'WebKit Linux - RandomOrder' \ - # --gs-bucket gs://chromium-layout-test-archives \ - # --staging-dir /b/c/chrome_staging \ - # --slave-utils-gsutil-py-path /b/rr/tmpIcChUS/rw/scripts/slave/.recipe_deps/depot_tools/gsutil.py - # in dir /b/rr/tmpIcChUS/w - parser.add_argument( - '--post-merge-script', - nargs='*', - help='Script to call after the results have been merged.') - - # The position arguments depend on if we are using the isolated merge - # script API mode or not. - parser.add_argument( - 'positional', nargs='*', - help='output.json from shards.') - - args = parser.parse_args(argv) - if args.verbose: - logging_level = logging.DEBUG - else: - logging_level = logging.INFO - configure_logging(logging_level=logging_level) - - # Map the isolate arguments back to our output / input arguments. - if args.output_json: - logging.info('Running with isolated arguments') - assert args.positional - - # TODO(tansell): Once removed everywhere, these lines can be removed. - # For now we just check nobody is supply arguments we didn't expect. - if args.results_json_override_with_build_property: - for result_key, build_prop_key in args.results_json_override_with_build_property: - assert (result_key, build_prop_key) in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY, ( - "%s not in %s" % (result_key, RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY)) - - if not args.output_directory: - args.output_directory = os.getcwd() - args.allow_existing_output_directory = True - args.remove_existing_output_directory = True - - assert not args.input_directories - args.input_directories = [os.path.dirname(f) for f in args.positional] - args.positional = [] - - # Allow skipping the --input-directories bit, for example, - # merge-layout-test-results -o outputdir shard0 shard1 shard2 - if args.positional and not args.input_directories: - args.input_directories = args.positional - - if not args.output_directory: - args.output_directory = tempfile.mkdtemp(suffix='webkit_layout_test_results.') - - assert args.output_directory - assert args.input_directories - - results_json_value_overrides = {} - if args.build_properties: - build_properties = json.loads(args.build_properties) - - for result_key, build_prop_key in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY: - if build_prop_key not in build_properties: - logging.warn('Required build property key "%s" was not found!', build_prop_key) - continue - results_json_value_overrides[result_key] = build_properties[build_prop_key] - logging.debug('results_json_value_overrides: %r', results_json_value_overrides) - - merger = merge_results.LayoutTestDirMerger( - results_json_value_overrides=results_json_value_overrides, - results_json_allow_unknown_if_matching=args.results_json_allow_unknown_if_matching) - - ensure_empty_dir( - FileSystem(), - args.output_directory, - allow_existing=args.allow_existing_output_directory, - remove_existing=args.remove_existing_output_directory) - - merger.merge(args.output_directory, args.input_directories) - - merged_output_json = os.path.join(args.output_directory, 'output.json') - if os.path.exists(merged_output_json) and args.output_json: - logging.debug( - 'Copying output.json from %s to %s', merged_output_json, args.output_json) - shutil.copyfile(merged_output_json, args.output_json) - - if args.post_merge_script: - logging.debug('Changing directory to %s', args.output_directory) - os.chdir(args.output_directory) - - post_script = list(args.post_merge_script) - post_script.append('--result-dir', args.output_directory) - - logging.info('Running post merge script %r', post_script) - os.execlp(post_script) - main(sys.argv[1:])
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py index 8ed9abd0..9539cef 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py
@@ -72,7 +72,8 @@ def get_typ_dir(): - return os.path.join(get_chromium_src_dir(), 'third_party', 'typ') + return os.path.join(get_chromium_src_dir(), 'third_party', 'catapult', + 'third_party', 'typ') def get_blinkpy_thirdparty_dir():
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/merge_results.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/merge_results.py index 3caa944..a53054d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/merge_results.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/merge_results.py
@@ -28,18 +28,34 @@ objects work together is to look at the unit tests. """ +import argparse import collections import json import logging +import os import pprint import re +import shutil +import tempfile import types from webkitpy.common.system.filesystem import FileSystem +from webkitpy.common.system.log_utils import configure_logging _log = logging.getLogger(__name__) +# The output JSON has the following arguments overwritten with a value from +# build properties. This occurs when '--build-properties' argument is provided +# and is mainly used when merging on build bots to provide better information +# about the build to the test results server. +# Format is a list of ('result json key', 'build property key'). +RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY = [ + ("build_number", "buildnumber"), + ("builder_name", "buildername"), + ("chromium_revision", "got_revision_cp"), +] + # Classes for recursively merging a JSON like dictionary together. # ------------------------------------------------------------------------ @@ -625,3 +641,199 @@ self.add_helper( FilenameRegexMatch(r'full_results_jsonp\.js$'), results_json_file_merger) + + +# ------------------------------------------------------------------------ +def ensure_empty_dir(fs, directory, allow_existing, remove_existing): + """Ensure an empty directory exists. + + Args: + allow_existing (bool): Allow the empty directory to already exist. + remove_existing (bool): Remove the contents if the directory + already exists. + """ + if not fs.exists(directory): + fs.maybe_make_directory(directory) + return + + logging.warning('Output directory exists %r', directory) + if not allow_existing: + raise IOError( + ('Output directory %s exists!\n' + 'Use --allow-existing-output-directory to continue') % directory) + + if remove_existing and not fs.remove_contents(directory): + raise IOError( + ('Unable to remove output directory %s contents!\n' + 'See log output for errors.') % directory) + + +def main(argv): + + parser = argparse.ArgumentParser() + parser.description = """\ +Merges sharded layout test results into a single output directory. +""" + parser.epilog = """\ + +If a post merge script is given, it will be run on the resulting merged output +directory. The script will be given the arguments plus +'--results_dir <output_directory>'. +""" + + parser.add_argument( + '-v', '--verbose', action='store_true', + help='Output information about merging progress.') + + parser.add_argument( + '--results-json-override-value', + nargs=2, metavar=('KEY', 'VALUE'), default=[], + action='append', + help='Override the value of a value in the result style JSON file ' + '(--result-jsons-override-value layout_test_dirs /tmp/output).') + parser.add_argument( + '--results-json-allow-unknown-if-matching', + action='store_true', default=False, + help='Allow unknown values in the result.json file as long as the ' + 'value match on all shards.') + + parser.add_argument( + '--output-directory', + help='Directory to create the merged results in.') + parser.add_argument( + '--allow-existing-output-directory', + action='store_true', default=False, + help='Allow merging results into a directory which already exists.') + parser.add_argument( + '--remove-existing-output-directory', + action='store_true', default=False, + help='Remove merging results into a directory which already exists.') + parser.add_argument( + '--input-directories', nargs='+', + help='Directories to merge the results from.') + + # Swarming Isolated Merge Script API + # script.py \ + # --build-properties /s/build.json \ + # --output-json /tmp/output.json \ + # --task-output-dir /path/to/task/output/dir \ + # shard0/output.json \ + # shard1/output.json + parser.add_argument( + '-o', '--output-json', + help='(Swarming Isolated Merge Script API) Output JSON file to create.') + parser.add_argument( + '--build-properties', + help='(Swarming Isolated Merge Script API) Build property JSON file provided by recipes.') + parser.add_argument( + '--task-output-dir', + help='(Swarming Isolated Merge Script API) Directory containing all swarming task results.') + parser.add_argument( + '--results-json-override-with-build-property', + nargs=2, metavar=('RESULT_JSON_KEY', 'BUILD_PROPERTY_KEY'), default=[], + action='append', + help='Override the value of a value in the result style JSON file ' + '(--result-jsons-override-value layout_test_dirs /tmp/output).') + parser.add_argument( + '--summary-json', + help='(Swarming Isolated Merge Script API) Summary of shard state running on swarming.' + '(Output of the swarming.py collect --task-summary-json=XXX command.)') + + # Script to run after merging the directories together. Normally used with archive_layout_test_results.py + # scripts/slave/chromium/archive_layout_test_results.py \ + # --results-dir /b/rr/tmpIcChUS/w/layout-test-results \ + # --build-dir /b/rr/tmpIcChUS/w/src/out \ + # --build-number 3665 \ + # --builder-name 'WebKit Linux - RandomOrder' \ + # --gs-bucket gs://chromium-layout-test-archives \ + # --staging-dir /b/c/chrome_staging \ + # --slave-utils-gsutil-py-path /b/rr/tmpIcChUS/rw/scripts/slave/.recipe_deps/depot_tools/gsutil.py + # in dir /b/rr/tmpIcChUS/w + parser.add_argument( + '--post-merge-script', + nargs='*', + help='Script to call after the results have been merged.') + + # The position arguments depend on if we are using the isolated merge + # script API mode or not. + parser.add_argument( + 'positional', nargs='*', + help='output.json from shards.') + + args = parser.parse_args(argv) + if args.verbose: + logging_level = logging.DEBUG + else: + logging_level = logging.INFO + configure_logging(logging_level=logging_level) + + # Map the isolate arguments back to our output / input arguments. + if args.output_json: + logging.info('Running with isolated arguments') + assert args.positional + + # TODO(tansell): Once removed everywhere, these lines can be removed. + # For now we just check nobody is supply arguments we didn't expect. + if args.results_json_override_with_build_property: + for result_key, build_prop_key in args.results_json_override_with_build_property: + assert (result_key, build_prop_key) in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY, ( + "%s not in %s" % (result_key, RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY)) + + if not args.output_directory: + args.output_directory = os.getcwd() + args.allow_existing_output_directory = True + args.remove_existing_output_directory = True + + assert not args.input_directories + args.input_directories = [os.path.dirname(f) for f in args.positional] + args.positional = [] + + # Allow skipping the --input-directories bit, for example, + # merge-layout-test-results -o outputdir shard0 shard1 shard2 + if args.positional and not args.input_directories: + args.input_directories = args.positional + + if not args.output_directory: + args.output_directory = tempfile.mkdtemp(suffix='webkit_layout_test_results.') + + assert args.output_directory + assert args.input_directories + + results_json_value_overrides = {} + if args.build_properties: + build_properties = json.loads(args.build_properties) + + for result_key, build_prop_key in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY: + if build_prop_key not in build_properties: + logging.warn('Required build property key "%s" was not found!', build_prop_key) + continue + results_json_value_overrides[result_key] = build_properties[build_prop_key] + logging.debug('results_json_value_overrides: %r', results_json_value_overrides) + + merger = LayoutTestDirMerger( + results_json_value_overrides=results_json_value_overrides, + results_json_allow_unknown_if_matching=args.results_json_allow_unknown_if_matching) + + ensure_empty_dir( + FileSystem(), + args.output_directory, + allow_existing=args.allow_existing_output_directory, + remove_existing=args.remove_existing_output_directory) + + merger.merge(args.output_directory, args.input_directories) + + merged_output_json = os.path.join(args.output_directory, 'output.json') + if os.path.exists(merged_output_json) and args.output_json: + logging.debug( + 'Copying output.json from %s to %s', merged_output_json, args.output_json) + shutil.copyfile(merged_output_json, args.output_json) + + if args.post_merge_script: + logging.debug('Changing directory to %s', args.output_directory) + os.chdir(args.output_directory) + + post_script = list(args.post_merge_script) + post_script.append('--result-dir', args.output_directory) + + logging.info('Running post merge script %r', post_script) + os.execlp(post_script)
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index 0c4d98df..88b247d3 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1674,7 +1674,6 @@ kPaintTimingObserved = 2190, kPaintTimingRequested = 2191, kHTMLMediaElementMediaPlaybackRateOutOfRange = 2192, - kCSSFilterFunctionNegativeBrightness = 2193, kCookieSet = 2194, kCookieGet = 2195, kGeolocationDisabledByFeaturePolicy = 2196,
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 8330424..8330794a 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -122,7 +122,7 @@ timeline_->ResetForTesting(); element_ = GetDocument().CreateElementForBinding("test"); - helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings); + helper_.Initialize(nullptr, nullptr, nullptr); base_url_ = "http://www.test.com/"; } @@ -333,9 +333,6 @@ } private: - static void ConfigureSettings(WebSettings* settings) { - settings->SetAcceleratedCompositingEnabled(true); - } FrameTestHelpers::WebViewHelper helper_; std::string base_url_; };
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc index d00f16f..f28dd5c 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
@@ -100,13 +100,8 @@ parsed_value = CSSPropertyParserHelpers::ConsumePercent(args, kValueRangeAll); if (!parsed_value) { - parsed_value = - CSSPropertyParserHelpers::ConsumeNumber(args, kValueRangeAll); - } - if (parsed_value && - ToCSSPrimitiveValue(parsed_value)->GetDoubleValue() < 0) { - // crbug.com/776208: Negative values are not allowed by spec. - context.Count(WebFeature::kCSSFilterFunctionNegativeBrightness); + parsed_value = CSSPropertyParserHelpers::ConsumeNumber( + args, kValueRangeNonNegative); } } else if (filter_type == CSSValueHueRotate) { parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc index de65d552..9416c98f 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -418,7 +418,7 @@ case CSSPropertyAnimation: return GetLayeredShorthandValue(animationShorthand()); case CSSPropertyBorderSpacing: - return BorderSpacingValue(borderSpacingShorthand()); + return Get2Values(borderSpacingShorthand()); case CSSPropertyBackgroundPosition: return GetLayeredShorthandValue(backgroundPositionShorthand()); case CSSPropertyBackgroundRepeat: @@ -462,11 +462,11 @@ case CSSPropertyGap: return GetShorthandValue(gapShorthand()); case CSSPropertyPlaceContent: - return GetAlignmentShorthandValue(placeContentShorthand()); + return Get2Values(placeContentShorthand()); case CSSPropertyPlaceItems: - return GetAlignmentShorthandValue(placeItemsShorthand()); + return Get2Values(placeItemsShorthand()); case CSSPropertyPlaceSelf: - return GetAlignmentShorthandValue(placeSelfShorthand()); + return Get2Values(placeSelfShorthand()); case CSSPropertyFont: return FontValue(); case CSSPropertyFontVariant: @@ -530,20 +530,6 @@ } } -String StylePropertySerializer::BorderSpacingValue( - const StylePropertyShorthand& shorthand) const { - const CSSValue* horizontal_value = - property_set_.GetPropertyCSSValue(*shorthand.properties()[0]); - const CSSValue* vertical_value = - property_set_.GetPropertyCSSValue(*shorthand.properties()[1]); - - String horizontal_value_css_text = horizontal_value->CssText(); - String vertical_value_css_text = vertical_value->CssText(); - if (horizontal_value_css_text == vertical_value_css_text) - return horizontal_value_css_text; - return horizontal_value_css_text + ' ' + vertical_value_css_text; -} - void StylePropertySerializer::AppendFontLonghandValueIfNotNormal( const CSSProperty& property, StringBuilder& result) const { @@ -965,14 +951,6 @@ return res; } -String StylePropertySerializer::GetAlignmentShorthandValue( - const StylePropertyShorthand& shorthand) const { - String value = GetCommonValue(shorthand); - if (value.IsNull() || value.IsEmpty()) - return GetShorthandValue(shorthand); - return value; -} - String StylePropertySerializer::BorderPropertyValue() const { const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand()};
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.h b/third_party/blink/renderer/core/css/style_property_serializer.h index a8d15f6..f558b99 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.h +++ b/third_party/blink/renderer/core/css/style_property_serializer.h
@@ -44,13 +44,11 @@ private: String GetCommonValue(const StylePropertyShorthand&) const; - String GetAlignmentShorthandValue(const StylePropertyShorthand&) const; String BorderPropertyValue() const; String BorderImagePropertyValue() const; String GetLayeredShorthandValue(const StylePropertyShorthand&) const; String Get2Values(const StylePropertyShorthand&) const; String Get4Values(const StylePropertyShorthand&) const; - String BorderSpacingValue(const StylePropertyShorthand&) const; String PageBreakPropertyValue(const StylePropertyShorthand&) const; String GetShorthandValue(const StylePropertyShorthand&, String separator = " ") const;
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index b2f7201a..3ce64bd 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -191,7 +191,7 @@ // Custom Elements // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-register // FIXME: The registerElement return type should be Function. - [CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options); + [RuntimeEnabled=CustomElementsV0, CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options); // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate // FIXME: The typeExtension arguments should not be nullable. [CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or Dictionary)? options);
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc index 6298bb2..de16957 100644 --- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc +++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -288,7 +288,7 @@ EditingState* editing_state, ShouldAssumeContentIsAlwaysEditable should_assume_content_is_always_editable) { - DCHECK_NE(GetDocument().body(), ref_child); + ABORT_EDITING_COMMAND_IF(GetDocument().body() == ref_child); ABORT_EDITING_COMMAND_IF(!ref_child->parentNode()); // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets // needs to be audited. See http://crbug.com/590369 for more details.
diff --git a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc index a3ebbda..fab7d12 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc
@@ -4,9 +4,11 @@ #include "third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h" +#include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/selection_template.h" #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h" +#include "third_party/blink/renderer/core/editing/testing/selection_sample.h" namespace blink { @@ -55,4 +57,32 @@ GetSelectionTextFromBody()); } +// https://crbug.com/835020 +TEST_F(InsertParagraphSeparatorCommandTest, CrashWithCaptionBeforeBody) { + // The bug reproduces only with |designMode == 'on'| + GetDocument().setDesignMode("on"); + InsertStyleElement(""); + SetBodyContent("<style>*{max-width:inherit;display:initial;}</style>"); + + // Insert <caption> between head and body + Element* caption = GetDocument().CreateElementForBinding("caption"); + caption->SetInnerHTMLFromString("AxBxC"); + GetDocument().documentElement()->insertBefore(caption, GetDocument().body()); + + Selection().SetSelection( + SelectionInDOMTree::Builder() + .SetBaseAndExtent(EphemeralRange::RangeOfContents(*caption)) + .Build(), + SetSelectionOptions()); + + InsertParagraphSeparatorCommand* command = + InsertParagraphSeparatorCommand::Create(GetDocument()); + // Shouldn't crash inside. + EXPECT_FALSE(command->Apply()); + EXPECT_EQ( + "<body><style><br>|*{max-width:inherit;display:initial;}</style></body>", + SelectionSample::GetSelectionText(*GetDocument().documentElement(), + Selection().GetSelectionInDOMTree())); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc index 0e80978..fd957f4 100644 --- a/third_party/blink/renderer/core/editing/iterators/character_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/character_iterator.cc
@@ -58,7 +58,7 @@ } template <typename Strategy> -Document* CharacterIteratorAlgorithm<Strategy>::OwnerDocument() const { +const Document& CharacterIteratorAlgorithm<Strategy>::OwnerDocument() const { return text_iterator_.OwnerDocument(); } @@ -90,12 +90,13 @@ template <typename Strategy> PositionTemplate<Strategy> CharacterIteratorAlgorithm<Strategy>::GetPositionBefore() const { - const Node& node = *text_iterator_.CurrentContainer(); if (text_iterator_.AtEnd()) { DCHECK_EQ(run_offset_, 0); return PositionTemplate<Strategy>( - node, text_iterator_.StartOffsetInCurrentContainer()); + text_iterator_.CurrentContainer(), + text_iterator_.StartOffsetInCurrentContainer()); } + const Node& node = *text_iterator_.GetNode(); DCHECK_GE(text_iterator_.length(), 1); if (node.IsTextNode()) { const int offset = text_iterator_.StartOffsetInCurrentContainer(); @@ -107,13 +108,14 @@ template <typename Strategy> PositionTemplate<Strategy> CharacterIteratorAlgorithm<Strategy>::GetPositionAfter() const { - const Node& node = *text_iterator_.CurrentContainer(); if (text_iterator_.AtEnd()) { DCHECK_EQ(run_offset_, 0); return PositionTemplate<Strategy>( - node, text_iterator_.EndOffsetInCurrentContainer()); + text_iterator_.CurrentContainer(), + text_iterator_.EndOffsetInCurrentContainer()); } DCHECK_GE(text_iterator_.length(), 1); + const Node& node = *text_iterator_.GetNode(); if (node.IsTextNode()) { const int offset = text_iterator_.StartOffsetInCurrentContainer(); return PositionTemplate<Strategy>(node, offset + run_offset_ + 1);
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator.h b/third_party/blink/renderer/core/editing/iterators/character_iterator.h index 180e55d..e3c8bdf 100644 --- a/third_party/blink/renderer/core/editing/iterators/character_iterator.h +++ b/third_party/blink/renderer/core/editing/iterators/character_iterator.h
@@ -64,7 +64,7 @@ int CharacterOffset() const { return offset_; } - Document* OwnerDocument() const; + const Document& OwnerDocument() const; const Node* CurrentContainer() const; int StartOffset() const; int EndOffset() const;
diff --git a/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc b/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc index 3146a0a7..3022d0e 100644 --- a/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc
@@ -72,4 +72,43 @@ EXPECT_EQ(Position(text_node, 3), result.EndPosition()); } +TEST_F(CharacterIteratorTest, GetPositionWithBR) { + SetBodyContent("a<br>b"); + + const Element& body = *GetDocument().body(); + CharacterIterator it(EphemeralRange::RangeOfContents(body)); + + const Node& text_a = *body.firstChild(); + const Node& br = *GetDocument().QuerySelector("br"); + const Node& text_b = *body.lastChild(); + + EXPECT_EQ(Position(text_a, 0), it.GetPositionBefore()); + EXPECT_EQ(Position(text_a, 1), it.GetPositionAfter()); + EXPECT_EQ(Position(text_a, 0), it.StartPosition()); + EXPECT_EQ(Position(text_a, 1), it.EndPosition()); + + ASSERT_FALSE(it.AtEnd()); + it.Advance(1); + EXPECT_EQ(Position::BeforeNode(br), it.GetPositionBefore()); + EXPECT_EQ(Position::AfterNode(br), it.GetPositionAfter()); + EXPECT_EQ(Position(body, 1), it.StartPosition()); + EXPECT_EQ(Position(body, 2), it.EndPosition()); + + ASSERT_FALSE(it.AtEnd()); + it.Advance(1); + EXPECT_EQ(Position(text_b, 0), it.GetPositionBefore()); + EXPECT_EQ(Position(text_b, 1), it.GetPositionAfter()); + EXPECT_EQ(Position(text_b, 0), it.StartPosition()); + EXPECT_EQ(Position(text_b, 1), it.EndPosition()); + + ASSERT_FALSE(it.AtEnd()); + it.Advance(1); + EXPECT_EQ(Position(body, 3), it.GetPositionBefore()); + EXPECT_EQ(Position(body, 3), it.GetPositionAfter()); + EXPECT_EQ(Position(body, 3), it.StartPosition()); + EXPECT_EQ(Position(body, 3), it.EndPosition()); + + EXPECT_TRUE(it.AtEnd()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/search_buffer.cc b/third_party/blink/renderer/core/editing/iterators/search_buffer.cc index 94451b5..8a66dd1 100644 --- a/third_party/blink/renderer/core/editing/iterators/search_buffer.cc +++ b/third_party/blink/renderer/core/editing/iterators/search_buffer.cc
@@ -334,7 +334,7 @@ for (SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwards_iterator( EphemeralRangeTemplate<Strategy>( PositionTemplate<Strategy>::FirstPositionInNode( - *it.OwnerDocument()), + it.OwnerDocument()), PositionTemplate<Strategy>(it.CurrentContainer(), it.StartOffset()))); !backwards_iterator.AtEnd(); backwards_iterator.Advance()) {
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc index e6e63a9..e2bb42e 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -219,9 +219,7 @@ TextIteratorAlgorithm<Strategy>::~TextIteratorAlgorithm() { if (!handle_shadow_root_) return; - Document* document = OwnerDocument(); - if (!document) - return; + const Document& document = OwnerDocument(); if (behavior_.ForInnerText()) UseCounter::Count(document, WebFeature::kInnerTextWithShadowTree); if (behavior_.ForSelectionToString()) @@ -825,31 +823,21 @@ } // otherwise, return the end of the overall range we were given - if (end_container_) - return EphemeralRangeTemplate<Strategy>( - PositionTemplate<Strategy>(end_container_, end_offset_)); - - return EphemeralRangeTemplate<Strategy>(); + return EphemeralRangeTemplate<Strategy>( + PositionTemplate<Strategy>(end_container_, end_offset_)); } template <typename Strategy> -Document* TextIteratorAlgorithm<Strategy>::OwnerDocument() const { - if (text_state_.PositionNode()) - return &text_state_.PositionNode()->GetDocument(); - if (end_container_) - return &end_container_->GetDocument(); - return nullptr; +const Document& TextIteratorAlgorithm<Strategy>::OwnerDocument() const { + return end_container_->GetDocument(); } template <typename Strategy> const Node* TextIteratorAlgorithm<Strategy>::GetNode() const { - if (text_state_.PositionNode() || end_container_) { - const Node* node = CurrentContainer(); - if (node->IsCharacterDataNode()) - return node; - return Strategy::ChildAt(*node, StartOffsetInCurrentContainer()); - } - return nullptr; + const Node* node = CurrentContainer(); + if (node->IsCharacterDataNode()) + return node; + return Strategy::ChildAt(*node, StartOffsetInCurrentContainer()); } template <typename Strategy> @@ -858,7 +846,6 @@ text_state_.FlushPositionOffsets(); return text_state_.PositionStartOffset(); } - DCHECK(end_container_); return end_offset_; } @@ -868,7 +855,6 @@ text_state_.FlushPositionOffsets(); return text_state_.PositionEndOffset(); } - DCHECK(end_container_); return end_offset_; } @@ -877,7 +863,6 @@ if (text_state_.PositionNode()) { return text_state_.PositionNode(); } - DCHECK(end_container_); return end_container_; }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.h b/third_party/blink/renderer/core/editing/iterators/text_iterator.h index fb296dc5..76031a378 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.h +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.h
@@ -74,7 +74,7 @@ EphemeralRangeTemplate<Strategy> Range() const; const Node* GetNode() const; - Document* OwnerDocument() const; + const Document& OwnerDocument() const; const Node* CurrentContainer() const; int StartOffsetInCurrentContainer() const; int EndOffsetInCurrentContainer() const;
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc index f3d9a1df..09e14ca 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -359,6 +359,7 @@ } if (!n->GetLayoutObject() && + (!n->IsElementNode() || !ToElement(n)->HasDisplayContentsStyle()) && !EnclosingElementWithTag(FirstPositionInOrBeforeNode(*n), selectTag)) { next = Strategy::NextSkippingChildren(*n);
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc index 1208a0f..25c3c35 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer_test.cc
@@ -292,4 +292,15 @@ EXPECT_EQ("", SerializePart<EditingInFlatTreeStrategy>(start_ict, end_ict)); } +TEST_F(StyledMarkupSerializerTest, DisplayContentsStyle) { + const char* body_content = "1<span style='display: contents'>2</span>3"; + const char* expected_result = + "<span style=\"display: inline !important; float: none;\">1</span><span " + "style=\"display: contents;\">2</span><span style=\"display: inline " + "!important; float: none;\">3</span>"; + SetBodyContent(body_content); + EXPECT_EQ(expected_result, Serialize<EditingStrategy>()); + EXPECT_EQ(expected_result, Serialize<EditingInFlatTreeStrategy>()); +} + } // namespace blink
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 5d8701b3..6db494b 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -248,7 +248,6 @@ } static void ConfigureCompositingWebView(WebSettings* settings) { - settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); }
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 4ddb6f5..fb5ee37 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3659,19 +3659,21 @@ void WebViewImpl::InitializeLayerTreeView() { if (client_) { layer_tree_view_ = client_->InitializeLayerTreeView(); - if (layer_tree_view_ && layer_tree_view_->CompositorAnimationHost()) { - animation_host_ = std::make_unique<CompositorAnimationHost>( - layer_tree_view_->CompositorAnimationHost()); - } - } + // TODO(dcheng): All WebViewImpls should have an associated LayerTreeView, + // but for various reasons, that's not the case... + page_->GetSettings().SetAcceleratedCompositingEnabled(layer_tree_view_); + if (layer_tree_view_) { + if (layer_tree_view_->CompositorAnimationHost()) { + animation_host_ = std::make_unique<CompositorAnimationHost>( + layer_tree_view_->CompositorAnimationHost()); + } - page_->GetSettings().SetAcceleratedCompositingEnabled(layer_tree_view_); - if (layer_tree_view_) { - page_->LayerTreeViewInitialized(*layer_tree_view_, nullptr); - // We don't yet have a page loaded at this point of the initialization of - // WebViewImpl, so don't allow cc to commit any frames Blink might - // try to create in the meantime. - layer_tree_view_->SetDeferCommits(true); + page_->LayerTreeViewInitialized(*layer_tree_view_, nullptr); + // We don't yet have a page loaded at this point of the initialization of + // WebViewImpl, so don't allow cc to commit any frames Blink might + // try to create in the meantime. + layer_tree_view_->SetDeferCommits(true); + } } // FIXME: only unittests, click to play, Android printing, and printing (for
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 839a9b5..3d91c0e5 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -3217,7 +3217,6 @@ } static void ConfigueCompositingWebView(WebSettings* settings) { - settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); }
diff --git a/third_party/blink/renderer/core/frame/browser_controls_test.cc b/third_party/blink/renderer/core/frame/browser_controls_test.cc index 1ad655d..356b4899 100644 --- a/third_party/blink/renderer/core/frame/browser_controls_test.cc +++ b/third_party/blink/renderer/core/frame/browser_controls_test.cc
@@ -83,7 +83,6 @@ static void ConfigureSettings(WebSettings* settings) { settings->SetJavaScriptEnabled(true); - settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); // Android settings settings->SetViewportEnabled(true);
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h index deb42b37..738b19e 100644 --- a/third_party/blink/renderer/core/frame/frame.h +++ b/third_party/blink/renderer/core/frame/frame.h
@@ -100,6 +100,12 @@ Page* GetPage() const; // Null when the frame is detached. virtual FrameView* View() const = 0; + // Before using this, make sure you really want the top-level frame in the + // entire page, as opposed to a top-level local frame in a sub-tree, e.g. + // one representing a cross-process iframe in a renderer separate from the + // main frame's renderer. For layout and compositing code, often + // LocalFrame::IsLocalRoot() is more appropriate. If you are unsure, please + // reach out to site-isolation-dev@chromium.org. bool IsMainFrame() const; FrameOwner* Owner() const;
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index 57f5f4b0..a10a48d 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -240,7 +240,7 @@ { name: "immersiveModeEnabled", initial: false, - invalidate: "MediaQuery", + invalidate: "MediaControls", }, {
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 4826719..771a66bf 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -1020,29 +1020,22 @@ DCHECK(Client()); DCHECK(!mutator_); layer_tree_view_ = Client()->InitializeLayerTreeView(); - if (layer_tree_view_ && layer_tree_view_->CompositorAnimationHost()) { + DCHECK(layer_tree_view_); + if (layer_tree_view_->CompositorAnimationHost()) { animation_host_ = std::make_unique<CompositorAnimationHost>( layer_tree_view_->CompositorAnimationHost()); } - GetPage()->GetSettings().SetAcceleratedCompositingEnabled(layer_tree_view_); - if (layer_tree_view_) { - GetPage()->LayerTreeViewInitialized(*layer_tree_view_, - LocalRootImpl()->GetFrame()->View()); + GetPage()->LayerTreeViewInitialized(*layer_tree_view_, + LocalRootImpl()->GetFrame()->View()); - // TODO(kenrb): Currently GPU rasterization is always enabled for OOPIFs. - // This is okay because it is only necessarily to set the trigger to false - // for certain cases that affect the top-level frame, but it would be better - // to be consistent with the top-level frame. Ideally the logic should - // be moved from WebViewImpl into WebFrameWidget and used for all local - // frame roots. https://crbug.com/712794 - layer_tree_view_->HeuristicsForGpuRasterizationUpdated(true); - } - - // FIXME: only unittests, click to play, Android priting, and printing (for - // headers and footers) make this assert necessary. We should make them not - // hit this code and then delete allowsBrokenNullLayerTreeView. - DCHECK(layer_tree_view_ || Client()->AllowsBrokenNullLayerTreeView()); + // TODO(kenrb): Currently GPU rasterization is always enabled for OOPIFs. + // This is okay because it is only necessarily to set the trigger to false + // for certain cases that affect the top-level frame, but it would be better + // to be consistent with the top-level frame. Ideally the logic should + // be moved from WebViewImpl into WebFrameWidget and used for all local + // frame roots. https://crbug.com/712794 + layer_tree_view_->HeuristicsForGpuRasterizationUpdated(true); } void WebFrameWidgetImpl::SetIsAcceleratedCompositingActive(bool active) {
diff --git a/third_party/blink/renderer/core/layout/layout_geometry_map.cc b/third_party/blink/renderer/core/layout/layout_geometry_map.cc index 176f44d4..d13ed7a 100644 --- a/third_party/blink/renderer/core/layout/layout_geometry_map.cc +++ b/third_party/blink/renderer/core/layout/layout_geometry_map.cc
@@ -398,7 +398,7 @@ if (!(map_coordinates_flags_ & kTraverseDocumentBoundaries)) return true; - return layout_object->GetFrame()->IsMainFrame(); + return layout_object->GetFrame()->IsLocalRoot(); } #endif
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc index b8862df..93f9f56 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -86,7 +86,6 @@ static void ConfigureSettings(WebSettings* settings) { settings->SetJavaScriptEnabled(true); - settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); // Android settings. settings->SetViewportEnabled(true);
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc index 32c210b..604acc1 100644 --- a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
@@ -170,7 +170,6 @@ </div> )HTML"); - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); GetDocument().View()->SetParentVisible(true); GetDocument().View()->SetSelfVisible(true); GetDocument().View()->UpdateAllLifecyclePhases(); @@ -246,7 +245,6 @@ </div> )HTML"); - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); GetDocument().View()->SetParentVisible(true); GetDocument().View()->SetSelfVisible(true); GetDocument().View()->UpdateAllLifecyclePhases();
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index af58bc6c..ee68453e 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -127,7 +127,6 @@ private: static void ConfigureSettings(WebSettings* settings) { - settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); }
diff --git a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc index 81ffbe14..62ed498 100644 --- a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc +++ b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
@@ -53,7 +53,6 @@ FrameSettingOverrideFunction SettingOverrider() const override { return [](Settings& settings) { - settings.SetAcceleratedCompositingEnabled(true); // LayoutHTMLCanvas doesn't exist if script is disabled. settings.SetScriptEnabled(true); };
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 0d935c9..a46cd86 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -77,6 +77,7 @@ #include "third_party/blink/renderer/core/paint/filter_effect_builder.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_info.h" +#include "third_party/blink/renderer/core/paint/paint_layer_painter.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" @@ -3085,13 +3086,25 @@ SetNeedsCompositingInputsUpdate(); GetLayoutObject().SetNeedsPaintPropertyUpdate(); - // We don't need to invalidate paint of objects on SPv175 when paint order - // changes. However, we do need to repaint the containing stacking context, - // in order to generate new paint chunks in the correct order. Raster - // invalidation will be issued if needed during paint. - if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() && - diff.ZIndexChanged()) - SetNeedsRepaint(); + if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() && !NeedsRepaint()) { + if (diff.ZIndexChanged()) { + // We don't need to invalidate paint of objects on SPv175 when paint order + // changes. However, we do need to repaint the containing stacking + // context, in order to generate new paint chunks in the correct order. + // Raster invalidation will be issued if needed during paint. + SetNeedsRepaint(); + } else if (old_style) { + // Change of PaintedOutputInvisible() will affect existence of paint + // chunks, so needs repaint. + PaintLayerPainter painter(*this); + // It's fine for PaintedOutputInvisible() to access the current + // compositing state. + DisableCompositingQueryAsserts disable; + if (painter.PaintedOutputInvisible(*old_style) != + painter.PaintedOutputInvisible(GetLayoutObject().StyleRef())) + SetNeedsRepaint(); + } + } } LayoutPoint PaintLayer::LocationInternal() const {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 3adafae0..f4866f3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -67,23 +67,25 @@ } bool PaintLayerPainter::PaintedOutputInvisible( - const PaintLayerPaintingInfo& painting_info) { - const LayoutObject& layout_object = paint_layer_.GetLayoutObject(); - if (layout_object.HasBackdropFilter()) + const ComputedStyle& style, + GlobalPaintFlags global_paint_flags) const { + if (style.HasBackdropFilter()) return false; // Always paint when 'will-change: opacity' is present. Reduces jank for // common animation implementation approaches, for example, an element that // starts with opacity zero and later begins to animate. - if (layout_object.StyleRef().HasWillChangeOpacityHint()) + if (style.HasWillChangeOpacityHint()) return false; if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { - if (layout_object.StyleRef().Opacity()) + if (style.Opacity()) return false; - const EffectPaintPropertyNode* effect = - layout_object.FirstFragment().PaintProperties()->Effect(); + const auto* effect = paint_layer_.GetLayoutObject() + .FirstFragment() + .PaintProperties() + ->Effect(); if (effect && effect->RequiresCompositingForAnimation()) { return false; } @@ -94,9 +96,8 @@ // less leads to a color output of less than 0.5 in all channels, hence // not visible. static const float kMinimumVisibleOpacity = 0.0004f; - if (paint_layer_.PaintsWithTransparency( - painting_info.GetGlobalPaintFlags())) { - if (layout_object.StyleRef().Opacity() < kMinimumVisibleOpacity) { + if (paint_layer_.PaintsWithTransparency(global_paint_flags)) { + if (style.Opacity() < kMinimumVisibleOpacity) { return true; } } @@ -138,7 +139,8 @@ // but skipping the painted content during layerization in // PaintArtifactCompositor. if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && - PaintedOutputInvisible(painting_info)) { + PaintedOutputInvisible(paint_layer_.GetLayoutObject().StyleRef(), + painting_info.GetGlobalPaintFlags())) { return kFullyPainted; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.h b/third_party/blink/renderer/core/paint/paint_layer_painter.h index 79ccbc94..346f363f 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.h +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.h
@@ -14,6 +14,7 @@ namespace blink { class ClipRect; +class ComputedStyle; class DisplayItemClient; class PaintLayer; class GraphicsContext; @@ -54,6 +55,11 @@ const LayoutRect& damage_rect, const GlobalPaintFlags); + // Returns true if the painted output of this PaintLayer and its children is + // invisible and therefore can't impact painted output. + bool PaintedOutputInvisible(const ComputedStyle&, + GlobalPaintFlags = kGlobalPaintNormalPhase) const; + private: friend class PaintLayerPainterTest; @@ -147,10 +153,6 @@ const PaintLayerFlags&, const LayoutBoxModelObject&); - // Returns true if the painted output of this PaintLayer and its children is - // invisible and therefore can't impact painted output. - bool PaintedOutputInvisible(const PaintLayerPaintingInfo&); - void AdjustForPaintProperties(PaintLayerPaintingInfo&, PaintLayerFlags&); PaintLayer& paint_layer_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc index e4d6b84b..100cbbfe 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -28,7 +28,9 @@ PaintLayerPaintingInfo painting_info(nullptr, LayoutRect(), kGlobalPaintNormalPhase, LayoutSize()); bool invisible = - PaintLayerPainter(*target_layer).PaintedOutputInvisible(painting_info); + PaintLayerPainter(*target_layer) + .PaintedOutputInvisible(target_layer->GetLayoutObject().StyleRef(), + painting_info.GetGlobalPaintFlags()); EXPECT_EQ(expected_value, invisible) << "Failed painted output visibility [spv175_enabled=" << RuntimeEnabledFeatures::SlimmingPaintV175Enabled()
diff --git a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc index 3e3cc45..c862d924 100644 --- a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc +++ b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -529,7 +529,6 @@ TEST_P(FrameThrottlingTest, ThrottledFrameWithFocus) { WebView().GetSettings()->SetJavaScriptEnabled(true); - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); ScopedCompositedSelectionUpdateForTest composited_selection_update(true); // Create a hidden frame which is throttled and has a text selection. @@ -571,8 +570,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); - // Create a hidden frame which is throttled. SimRequest main_resource("https://example.com/", "text/html"); SimRequest frame_resource("https://example.com/iframe.html", "text/html"); @@ -637,7 +634,6 @@ TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledLayer) { WebView().GetSettings()->SetJavaScriptEnabled(true); - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); // Create a hidden frame which is throttled and has a touch handler inside a @@ -684,7 +680,6 @@ TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipCompositedThrottledFrame) { - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); // Create a hidden frame which is throttled. @@ -736,8 +731,6 @@ } TEST_P(FrameThrottlingTest, UnthrottleByTransformingWithoutLayout) { - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); - // Create a hidden frame which is throttled. SimRequest main_resource("https://example.com/", "text/html"); SimRequest frame_resource("https://example.com/iframe.html", "text/html"); @@ -768,7 +761,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetJavaScriptEnabled(true); EXPECT_EQ(0u, TouchHandlerRegionSize()); @@ -809,7 +801,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetJavaScriptEnabled(true); EXPECT_EQ(0u, TouchHandlerRegionSize()); @@ -878,7 +869,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); // Create a hidden frame which is throttled. @@ -915,7 +905,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); // Create a hidden frame which is throttled. @@ -1061,7 +1050,6 @@ } TEST_P(FrameThrottlingTest, SkipPaintingLayersInThrottledFrames) { - WebView().GetSettings()->SetAcceleratedCompositingEnabled(true); WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true); SimRequest main_resource("https://example.com/", "text/html");
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h index f771467..0cb7504 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.h +++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -157,7 +157,7 @@ // Only callable on the main thread. void AppendDebuggerTask(CrossThreadClosure); - // Only callable on the main thread. + // Callable on both the main thread and the worker thread. const base::UnguessableToken& GetDevToolsWorkerToken() const { return devtools_worker_token_; } @@ -310,7 +310,7 @@ TimeDelta forcible_termination_delay_; scoped_refptr<InspectorTaskRunner> inspector_task_runner_; - base::UnguessableToken devtools_worker_token_; + const base::UnguessableToken devtools_worker_token_; // Created on the main thread, passed to the worker thread but should kept // being accessed only on the main thread.
diff --git a/third_party/blink/renderer/devtools/front_end/formatter/FormatterWorkerPool.js b/third_party/blink/renderer/devtools/front_end/formatter/FormatterWorkerPool.js index c63d32f..6890f50 100644 --- a/third_party/blink/renderer/devtools/front_end/formatter/FormatterWorkerPool.js +++ b/third_party/blink/renderer/devtools/front_end/formatter/FormatterWorkerPool.js
@@ -230,6 +230,15 @@ rule => ({line: rule.lineNumber, column: rule.columnNumber, title: rule.selectorText || rule.atRule}))); } } + + /** + * @param {string} content + * @return {!Promise<?{baseExpression: string, possibleSideEffects:boolean}>} + */ + findLastExpression(content) { + return /** @type {!Promise<?{baseExpression: string, possibleSideEffects:boolean}>} */ ( + this._runTask('findLastExpression', {content})); + } }; Formatter.FormatterWorkerPool.MaxWorkers = 2;
diff --git a/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js b/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js index 8463752..e4528c0d 100644 --- a/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js +++ b/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js
@@ -84,6 +84,9 @@ case 'preprocessTopLevelAwaitExpressions': FormatterWorker.preprocessTopLevelAwaitExpressions(params.content); break; + case 'findLastExpression': + postMessage(FormatterWorker.findLastExpression(params.content)); + break; default: console.error('Unsupport method name: ' + method); } @@ -318,6 +321,72 @@ }; /** + * @param {string} content + * @return {?{baseExpression: string, possibleSideEffects:boolean}} + */ +FormatterWorker.findLastExpression = function(content) { + if (content.length > 10000) + return null; + try { + const tokenizer = acorn.tokenizer(content, {ecmaVersion: 9}); + while (tokenizer.getToken().type !== acorn.tokTypes.eof) { + } + } catch (e) { + return null; + } + + /** @type {!ESTree.Node} */ + let ast; + const suffix = '.DEVTOOLS'; + try { + acorn.parse(content + suffix, {ecmaVersion: 9}); + } catch (parseError) { + // If this is an invalid location for a '.', don't attempt to give autocomplete + if (parseError.message.startsWith('Unexpected token') && parseError.pos === content.length) + return null; + } + let parsedContent = ''; + for (let i = 0; i < content.length; i++) { + try { + // Wrap content in paren to successfully parse object literals + parsedContent = content[i] === '{' ? `(${content.substring(i)})${suffix}` : `${content.substring(i)}${suffix}`; + ast = acorn.parse(parsedContent, {ecmaVersion: 9}); + break; + } catch (e) { + } + } + if (!ast) + return null; + const types = new Set(['MemberExpression', 'Identifier']); + let baseNode = null; + const walker = new FormatterWorker.ESTreeWalker(node => { + if (baseNode || node.end < ast.end) + return FormatterWorker.ESTreeWalker.SkipSubtree; + if (types.has(node.type)) + baseNode = node; + }); + walker.walk(ast); + if (!baseNode) + return null; + let baseExpression = parsedContent.substring(baseNode.start, parsedContent.length - suffix.length); + if (baseExpression.startsWith('{')) + baseExpression = `(${baseExpression})`; + const sideEffectFreeTypes = new Set([ + 'MemberExpression', 'Identifier', 'BinaryExpression', 'Literal', 'TemplateLiteral', 'TemplateElement', + 'ObjectExpression', 'ArrayExpression', 'Property' + ]); + let possibleSideEffects = false; + const sideEffectwalker = new FormatterWorker.ESTreeWalker(node => { + if (!possibleSideEffects && !sideEffectFreeTypes.has(node.type)) + possibleSideEffects = true; + if (possibleSideEffects) + return FormatterWorker.ESTreeWalker.SkipSubtree; + }); + sideEffectwalker.walk(/** @type {!ESTree.Node} */ (baseNode)); + return {baseExpression, possibleSideEffects}; +}; + +/** * @interface */ FormatterWorker.FormatterWorkerContentParser = function() {};
diff --git a/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js b/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js index 4a2850d..33de221 100644 --- a/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js +++ b/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js
@@ -18,52 +18,17 @@ } /** - * @param {string} text + * @param {string} fullText * @param {string} query * @param {boolean=} force * @return {!Promise<!UI.SuggestBox.Suggestions>} */ - completionsForTextInCurrentContext(text, query, force) { - const clippedExpression = this._clipExpression(text, true); - const mapCompletionsPromise = this._mapCompletions(text, query); - return this._completionsForExpression(clippedExpression, query, force) - .then(completions => mapCompletionsPromise.then(mapCompletions => mapCompletions.concat(completions))); - } + async completionsForTextInCurrentContext(fullText, query, force) { + const trimmedText = fullText.trim(); - /** - * @param {string} text - * @param {boolean=} allowEndingBracket - * @return {string} - */ - _clipExpression(text, allowEndingBracket) { - let index; - const stopChars = new Set('=:({;,!+-*/&|^<>`'.split('')); - const whiteSpaceChars = new Set(' \r\n\t'.split('')); - const continueChars = new Set('[. \r\n\t'.split('')); - - for (index = text.length - 1; index >= 0; index--) { - if (stopChars.has(text.charAt(index))) - break; - if (whiteSpaceChars.has(text.charAt(index)) && !continueChars.has(text.charAt(index - 1))) - break; - } - const clippedExpression = text.substring(index + 1).trim(); - let bracketCount = 0; - - index = clippedExpression.length - 1; - while (index >= 0) { - const character = clippedExpression.charAt(index); - if (character === ']') - bracketCount++; - // Allow an open bracket at the end for property completion. - if (character === '[' && (index < clippedExpression.length - 1 || !allowEndingBracket)) { - bracketCount--; - if (bracketCount < 0) - break; - } - index--; - } - return clippedExpression.substring(index + 1).trim(); + const [mapCompletions, expressionCompletions] = await Promise.all( + [this._mapCompletions(trimmedText, query), this._completionsForExpression(trimmedText, query, force)]); + return mapCompletions.concat(expressionCompletions); } /** @@ -77,15 +42,20 @@ if (!executionContext || !mapMatch) return []; - const clippedExpression = this._clipExpression(text.substring(0, mapMatch.index)); + const expression = await Formatter.formatterWorkerPool().findLastExpression(text.substring(0, mapMatch.index)); + if (!expression) + return []; + const result = await executionContext.evaluate( { - expression: clippedExpression, - objectGroup: 'completion', + expression: expression.baseExpression, + objectGroup: 'mapCompletion', includeCommandLineAPI: true, silent: true, returnByValue: false, - generatePreview: false + generatePreview: false, + throwOnSideEffect: expression.possibleSideEffects, + timeout: expression.possibleSideEffects ? 500 : undefined }, /* userGesture */ false, /* awaitPromise */ false); if (result.error || !!result.exceptionDetails || result.object.subtype !== 'map') @@ -96,6 +66,7 @@ if (!entriesProperty) return []; const keysObj = await entriesProperty.value.callFunctionJSONPromise(getEntries); + executionContext.runtimeModel.releaseObjectGroup('mapCompletion'); return gotKeys(Object.keys(keysObj)); /** @@ -158,25 +129,29 @@ } /** - * @param {string} expressionString + * @param {string} fullText * @param {string} query * @param {boolean=} force * @return {!Promise<!UI.SuggestBox.Suggestions>} */ - async _completionsForExpression(expressionString, query, force) { + async _completionsForExpression(fullText, query, force) { const executionContext = UI.context.flavor(SDK.ExecutionContext); if (!executionContext) return []; + let expression; + if (fullText.endsWith('.') || fullText.endsWith('[')) + expression = await Formatter.formatterWorkerPool().findLastExpression(fullText.substring(0, fullText.length - 1)); + if (!expression) { + if (fullText.endsWith('.')) + return []; + expression = {baseExpression: '', possibleSideEffects: false}; + } + const needsNoSideEffects = expression.possibleSideEffects; + const expressionString = expression.baseExpression; - const lastIndex = expressionString.length - 1; - const dotNotation = (expressionString[lastIndex] === '.'); - const bracketNotation = (expressionString.length > 1 && expressionString[lastIndex] === '['); - - if (dotNotation || bracketNotation) - expressionString = expressionString.substr(0, lastIndex); - else - expressionString = ''; + const dotNotation = fullText.endsWith('.'); + const bracketNotation = !!expressionString && fullText.endsWith('['); // User is entering float value, do not suggest anything. if ((expressionString && !isNaN(expressionString)) || (!expressionString && query && !isNaN(query))) @@ -203,7 +178,9 @@ includeCommandLineAPI: true, silent: true, returnByValue: false, - generatePreview: false + generatePreview: false, + throwOnSideEffect: needsNoSideEffects, + timeout: needsNoSideEffects ? 500 : undefined }, /* userGesture */ false, /* awaitPromise */ false); cache = {date: Date.now(), value: resultPromise.then(result => completionsOnGlobal.call(this, result))};
diff --git a/third_party/blink/renderer/devtools/front_end/object_ui/module.json b/third_party/blink/renderer/devtools/front_end/object_ui/module.json index 216588d..3cfab83 100644 --- a/third_party/blink/renderer/devtools/front_end/object_ui/module.json +++ b/third_party/blink/renderer/devtools/front_end/object_ui/module.json
@@ -11,7 +11,8 @@ "dependencies": [ "ui", "sdk", - "components" + "components", + "formatter" ], "scripts": [ "CustomPreviewComponent.js",
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index 632beee..b2d5554 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -127,6 +127,7 @@ const char kActAsAudioControlsCSSClass[] = "audio-only"; const char kScrubbingMessageCSSClass[] = "scrubbing-message"; const char kTestModeCSSClass[] = "test-mode"; +const char kImmersiveModeCSSClass[] = "immersive-mode"; bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) { // Unconditionally allow the user to exit fullscreen if we are in it @@ -688,6 +689,12 @@ builder.Append(kActAsAudioControlsCSSClass); } + if (ShouldShowVideoControls() && GetDocument().GetSettings() && + GetDocument().GetSettings()->GetImmersiveModeEnabled()) { + builder.Append(" "); + builder.Append(kImmersiveModeCSSClass); + } + if (is_test_mode_) { builder.Append(" "); builder.Append(kTestModeCSSClass);
diff --git a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css index 6357354..3c9a6fe 100644 --- a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -821,80 +821,80 @@ /** * VR styling. */ -@media (immersive) { - video::-webkit-media-controls-timeline, - video::-internal-media-controls-button-panel { - padding-left: 32px; - padding-right: 32px; - } - /* Timeline sizing does not include padding in max width. */ - video::-webkit-media-controls-timeline { - max-width: 471px; - height: 5px; - margin-bottom: 20px; - padding-top: 19px; - padding-bottom: 19px; - } - /* Button panel sizing does include padding in max width. */ - video::-internal-media-controls-button-panel { - max-width: 535px; /* 471px + 64px padding. */ - } - - video::-webkit-media-controls-panel { - /* Centering the button panel and timeline within the controls. */ - text-align: -webkit-center; - - /* Taller scrim. */ - background: - -webkit-image-set(url('default_100_percent/modern/vr_gradient_bg.png') 1x) - repeat-x bottom left; - } - - input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before, - input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after, - input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background, - input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-buffering { - height: 5px; - } - - input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb { - width: 16px; - height: 16px; - border-radius: 8px; - margin-top: -5px; - } - - input[pseudo="-webkit-media-controls-overlay-play-button" i]::-internal-media-controls-overlay-play-button-internal { - width: 64px; - height: 64px; - border-radius: 32px; - background-size: 36px; - } - - video::-webkit-media-controls-mute-button, - video::-webkit-media-controls-fullscreen-button, - video::-internal-media-controls-overflow-button { - width: 43px; - height: 43px; - min-width: 43px; - margin-left: 5px; - } - - video::-internal-media-controls-button-panel { - height: 43px; - } - - /* Hover highlighting. */ - video::-webkit-media-controls-mute-button:hover, - video::-webkit-media-controls-fullscreen-button:hover, - video::-internal-media-controls-overflow-button:hover { - background-color: rgba(255, 255, 255, 0.2); - border-radius: 4px; - } +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i], +.immersive-mode div[pseudo="-internal-media-controls-button-panel" i] { + padding-left: 32px; + padding-right: 32px; } -@media (immersive) and (-webkit-min-device-pixel-ratio: 2) { - video::-webkit-media-controls-panel { +/* Timeline sizing does not include padding in max width. */ +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i] { + max-width: 471px; + height: 5px; + margin-bottom: 20px; + padding-top: 19px; + padding-bottom: 19px; +} + +/* Button panel sizing does include padding in max width. */ +.immersive-mode div[pseudo="-internal-media-controls-button-panel" i] { + max-width: 535px; /* 471px + 64px padding. */ +} + +.immersive-mode div[pseudo="-webkit-media-controls-panel" i] { + /* Centering the button panel and timeline within the controls. */ + text-align: -webkit-center; + + /* Taller scrim. */ + background: + -webkit-image-set(url('default_100_percent/modern/vr_gradient_bg.png') 1x) + repeat-x bottom left; +} + +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before, +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after, +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background, +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-buffering { + height: 5px; +} + +.immersive-mode input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb { + width: 16px; + height: 16px; + border-radius: 8px; + margin-top: -5px; +} + +.immersive-mode input[pseudo="-webkit-media-controls-overlay-play-button" i]::-internal-media-controls-overlay-play-button-internal { + width: 64px; + height: 64px; + border-radius: 32px; + background-size: 36px; +} + +.immersive-mode input[pseudo="-webkit-media-controls-mute-button" i], +.immersive-mode input[pseudo="-webkit-media-controls-fullscreen-button" i], +.immersive-mode input[pseudo="-internal-media-controls-overflow-button" i] { + width: 43px; + height: 43px; + min-width: 43px; + margin-left: 5px; +} + +.immersive-mode div[pseudo="-internal-media-controls-button-panel" i] { + height: 43px; +} + +/* Hover highlighting. */ +.immersive-mode input[pseudo="-webkit-media-controls-mute-button" i]:hover, +.immersive-mode input[pseudo="-webkit-media-controls-fullscreen-button" i]:hover, +.immersive-mode input[pseudo="-internal-media-controls-overflow-button" i]:hover { + background-color: rgba(255, 255, 255, 0.2); + border-radius: 4px; +} + +@media (-webkit-min-device-pixel-ratio: 2) { + .immersive-mode div[pseudo="-webkit-media-controls-panel" i] { background: -webkit-image-set(url('default_200_percent/modern/vr_gradient_bg.png') 1x) repeat-x bottom left auto 198px;
diff --git a/third_party/blink/renderer/modules/websockets/inspector_web_socket_events.cc b/third_party/blink/renderer/modules/websockets/inspector_web_socket_events.cc index 46c84728..a19f16c 100644 --- a/third_party/blink/renderer/modules/websockets/inspector_web_socket_events.cc +++ b/third_party/blink/renderer/modules/websockets/inspector_web_socket_events.cc
@@ -9,6 +9,8 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/identifiers_factory.h" +#include "third_party/blink/renderer/core/workers/worker_global_scope.h" +#include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" namespace blink { @@ -18,15 +20,21 @@ unsigned long identifier, const KURL& url, const String& protocol) { + DCHECK(execution_context->IsContextThread()); std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetInteger("identifier", identifier); value->SetString("url", url.GetString()); if (execution_context->IsDocument()) { value->SetString("frame", IdentifiersFactory::FrameId( ToDocument(execution_context)->GetFrame())); + } else if (execution_context->IsWorkerGlobalScope()) { + value->SetString("workerId", IdentifiersFactory::IdFromToken( + ToWorkerGlobalScope(execution_context) + ->GetThread() + ->GetDevToolsWorkerToken())); } else { - // TODO(nhiroki): Support WorkerGlobalScope (https://crbug.com/825740). - NOTREACHED(); + NOTREACHED() + << "WebSocket is available only in Document and WorkerGlobalScope"; } if (!protocol.IsNull()) value->SetString("webSocketProtocol", protocol); @@ -37,14 +45,20 @@ std::unique_ptr<TracedValue> InspectorWebSocketEvent::Data( ExecutionContext* execution_context, unsigned long identifier) { + DCHECK(execution_context->IsContextThread()); std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetInteger("identifier", identifier); if (execution_context->IsDocument()) { value->SetString("frame", IdentifiersFactory::FrameId( ToDocument(execution_context)->GetFrame())); + } else if (execution_context->IsWorkerGlobalScope()) { + value->SetString("workerId", IdentifiersFactory::IdFromToken( + ToWorkerGlobalScope(execution_context) + ->GetThread() + ->GetDevToolsWorkerToken())); } else { - // TODO(nhiroki): Support WorkerGlobalScope (https://crbug.com/825740). - NOTREACHED(); + NOTREACHED() + << "WebSocket is available only in Document and WorkerGlobalScope"; } SetCallStack(value.get()); return value;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 454b035..43ed87e5 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -347,6 +347,12 @@ name: "CustomElementsBuiltin", status: "stable", }, + // Introduced this flag as stable so web developers can test their sites + // without native Custom Elements v0 support. + { + name: "CustomElementsV0", + status: "stable", + }, { name: "CustomUserTiming", }, @@ -930,7 +936,7 @@ }, { name: "PictureInPictureAPI", - status: "test", + status: "experimental", }, { name: "PreciseMemoryInfo",
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp index bd2f692..011818d 100644 --- a/third_party/closure_compiler/compiled_resources2.gyp +++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -23,7 +23,6 @@ '<(DEPTH)/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/extensions/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/media_router/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/ntp4/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/pdf/compiled_resources2.gyp:*',
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index 7f7c9832..1cf0050 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -278,6 +278,7 @@ NODE_CHANGED: 'nodeChanged', TEXT_CHANGED: 'textChanged', NODE_REMOVED: 'nodeRemoved', + SUBTREE_UPDATE_END: 'subtreeUpdateEnd', }; /**
diff --git a/third_party/fuchsia-sdk/BUILD.gn b/third_party/fuchsia-sdk/BUILD.gn index ec5c942b..b25fb8c 100644 --- a/third_party/fuchsia-sdk/BUILD.gn +++ b/third_party/fuchsia-sdk/BUILD.gn
@@ -19,7 +19,7 @@ # async-default keep a per-thread dispatcher for async. fuchsia_sdk_pkg("async_default") { name = "async-default" - libs = [ "async.default" ] + libs = [ "async-default" ] } fuchsia_sdk_pkg("zx") {
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json index 0f1e6e42..4374166 100644 --- a/third_party/polymer/v1_0/bower.json +++ b/third_party/polymer/v1_0/bower.json
@@ -26,7 +26,7 @@ "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#2.3.2", "iron-pages": "PolymerElements/iron-pages#2.0.1", "iron-range-behavior": "PolymerElements/iron-range-behavior#2.0.0", - "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#1.0.5", + "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#2.1.0", "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#1.1.0", "iron-scroll-threshold": "PolymerElements/iron-scroll-threshold#2.0.0", "iron-selector": "PolymerElements/iron-selector#2.0.1",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/bower.json index 77d1968..845aeb9 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/bower.json +++ b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/bower.json
@@ -1,6 +1,6 @@ { "name": "iron-resizable-behavior", - "version": "1.0.5", + "version": "2.0.1", "license": "http://polymer.github.io/LICENSE.txt", "description": "Coordinates the flow of resizeable elements", "private": true, @@ -19,13 +19,30 @@ "url": "git://github.com/PolymerElements/iron-resizable-behavior.git" }, "dependencies": { - "polymer": "Polymer/polymer#^1.1.0" + "polymer": "Polymer/polymer#1.9 - 2" }, "devDependencies": { - "iron-component-page": "polymerelements/iron-component-page#^1.0.0", - "test-fixture": "polymerelements/test-fixture#^1.0.0", - "web-component-tester": "^4.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + "iron-component-page": "PolymerElements/iron-component-page#1 - 2", + "web-component-tester": "^6.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" }, - "ignore": [] + "variants": { + "1.x": { + "dependencies": { + "polymer": "Polymer/polymer#^1.9" + }, + "devDependencies": { + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", + "web-component-tester": "^4.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + }, + "resolutions": { + "webcomponentsjs": "^0.7" + } + } + }, + "ignore": [], + "resolutions": { + "webcomponentsjs": "^1.0.0" + } }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js index d882cae..527fda5 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js +++ b/third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js
@@ -27,7 +27,7 @@ }, /** - * True if this element is currently notifying its descedant elements of + * True if this element is currently notifying its descendant elements of * resize. */ _notifyingDescendant: { @@ -48,16 +48,7 @@ }, attached: function() { - this.fire('iron-request-resize-notifications', null, { - node: this, - bubbles: true, - cancelable: true - }); - - if (!this._parentResizable) { - window.addEventListener('resize', this._boundNotifyResize); - this.notifyResize(); - } + this._requestResizeNotifications(); }, detached: function() { @@ -126,7 +117,7 @@ return; } - // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the + // NOTE(cdata): In ShadowDOM, event retargeting makes echoing of the // otherwise non-bubbling event "just work." We do it manually here for // the case where Polymer is not using shadow roots for whatever reason: if (!Polymer.Settings.useShadow) { @@ -142,8 +133,7 @@ }, _onIronRequestResizeNotifications: function(event) { - var target = event.path ? event.path[0] : event.target; - + var target = /** @type {!EventTarget} */ (Polymer.dom(event).rootTarget); if (target === this) { return; } @@ -176,5 +166,35 @@ this._notifyingDescendant = true; descendant.notifyResize(); this._notifyingDescendant = false; + }, + + _requestResizeNotifications: function() { + if (!this.isAttached) + return; + + // NOTE(valdrin) In CustomElements v1 with native HTMLImports, the order + // of imports affects the order of `attached` callbacks (see webcomponents/custom-elements#15). + // This might cause a child to notify parents too early (as the parent + // still has to be upgraded), resulting in a parent not able to keep track + // of the `_interestedResizables`. To solve this, we wait for the document + // to be done loading before firing the event. + if (document.readyState === 'loading') { + var _requestResizeNotifications = this._requestResizeNotifications.bind(this); + document.addEventListener('readystatechange', function readystatechanged() { + document.removeEventListener('readystatechange', readystatechanged); + _requestResizeNotifications(); + }); + } else { + this.fire('iron-request-resize-notifications', null, { + node: this, + bubbles: true, + cancelable: true + }); + + if (!this._parentResizable) { + window.addEventListener('resize', this._boundNotifyResize); + this.notifyResize(); + } + } } }; \ No newline at end of file
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt index 554ef1d1..b1f4935 100644 --- a/third_party/polymer/v1_0/components_summary.txt +++ b/third_party/polymer/v1_0/components_summary.txt
@@ -144,9 +144,9 @@ Name: iron-resizable-behavior Repository: https://github.com/PolymerElements/iron-resizable-behavior.git -Tree: v1.0.5 -Revision: 354f287922e497b79797348b31596eebaccb9761 -Tree link: https://github.com/PolymerElements/iron-resizable-behavior/tree/v1.0.5 +Tree: v2.1.0 +Revision: 806e0807bd4253f446f8be624acf853069e36919 +Tree link: https://github.com/PolymerElements/iron-resizable-behavior/tree/v2.1.0 Name: iron-scroll-target-behavior Repository: https://github.com/PolymerElements/iron-scroll-target-behavior.git
diff --git a/third_party/typ/LICENSE b/third_party/typ/LICENSE deleted file mode 100644 index ad410e11..0000000 --- a/third_party/typ/LICENSE +++ /dev/null
@@ -1,201 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file
diff --git a/third_party/typ/OWNERS b/third_party/typ/OWNERS deleted file mode 100644 index ac3cc58b0..0000000 --- a/third_party/typ/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -dpranke@chromium.org -dtu@chromium.org -eseidel@chromium.org -ojan@chromium.org
diff --git a/third_party/typ/README.chromium b/third_party/typ/README.chromium deleted file mode 100644 index 0b3264e..0000000 --- a/third_party/typ/README.chromium +++ /dev/null
@@ -1,32 +0,0 @@ -Name: typ -URL: https://github.com/dpranke/typ.git -Version: 0.10.0 -Revision: 1e254b3ef4d14dee6109d8c3a58ab64d1500e3c2 -Security Critical: no -License: Apache 2.0 -License File: NOT_SHIPPED - -Description: - -typ is a simple wrapper around Python's unittest library that provides a -somewhat nicer command-line interface, parallel test execution, -code coverage support, and support for Chromium's JSON Results format. - -This code is not considered security critical since it is only to be linked -into test binaries! This should never be linked into chrome or any production -code. - -To update this copy of typ from the source repo (assuming you are in -src/third_party/typ): - - # can just do "sed -n '/^ /p' README.chromium | bash -e" - cd .. - git clone https://github.com/dpranke/typ.git typ_new - revision=$(cd typ_new && git log -1 | head -1 | awk '{ print $2 }') - version=$(cd typ_new && python -m typ --version) - cp typ/OWNERS typ_new - cat typ/README.chromium | sed -e "s/^Version: .*/Version: $version/" \ - -e "s/^Revision: .*/Revision: $revision/" \ - > typ_new/README.chromium - rm -fr typ_new/.git typ_new/.gitignore typ/ - mv typ_new typ
diff --git a/third_party/typ/README.rst b/third_party/typ/README.rst deleted file mode 100644 index dc03841..0000000 --- a/third_party/typ/README.rst +++ /dev/null
@@ -1,68 +0,0 @@ -typ (Test Your Program) -======================= -typ is a simple program for testing command line executables and Python code. - -When testing Python code, it is basically a wrapper around the standard -unittest module, but it provides the following bits of additional -functionality: - -* Parallel test execution. -* Clean output in the style of the Ninja build tool. -* A more flexible mechanism for discovering tests from the - command line and controlling how they are run: - - * Support for importing tests by directory, filename, or module. - * Support for specifying tests to skip, tests to run in parallel, - and tests that need to be run by themselves - -* Support for producing traces of test times compatible with Chrome's - tracing infrastructure (trace_viewer). -* Integrated test coverage reporting (including parallel coverage). -* Integrated support for debugging tests. -* Support for uploading test results automatically to a server - (useful for continuous integration monitoring of test results). -* An abstraction of operating system functionality called the - Host class. This can be used by other python code to write more - portable and easily testable code by wrapping the multiprocessing, - os, subprocess, and time modules. -* Simple libraries for integrating Ninja-style statistics and line - printing into your own code (the Stats and Printer classes). -* Support for processing arbitrary arguments from calling code to - test cases. -* Support for once-per-process setup and teardown hooks. - -(These last two bullet points allow one to write tests that do not require -Python globals). - -History -------- - -typ originated out of work on the Blink and Chromium projects, as a way to -provide a friendlier interface to the Python unittest modules. - -Work remaining --------------- - -typ is still a work in progress, but it's getting close to being done. -Things remaining for 1.0, roughly in priority order: - -- Implement a non-python file format for testing command line interfaces -- Write documentation - -Possible future work --------------------- - -- MainTestCase.check() improvements: - - - check all arguments and show all errors at once? - - make multi-line regexp matches easier to follow? - -- --debugger improvements: - - - make it skip the initial breakpoint? - -- Support testing javascript, java, c++/gtest-style binaries? -- Support for test sharding in addition to parallel execution (so that - run-webkit-tests can re-use as much of the code as possible)? -- Support for non-unittest runtest invocation (for run-webkit-tests, - other harnesses?)
diff --git a/third_party/typ/codereview.settings b/third_party/typ/codereview.settings deleted file mode 100644 index 8fbef92..0000000 --- a/third_party/typ/codereview.settings +++ /dev/null
@@ -1,3 +0,0 @@ -# This file is used by gcl to get repository specific information. -CODE_REVIEW_SERVER: codereview.chromium.org -PROJECT: typ
diff --git a/third_party/typ/pylintrc b/third_party/typ/pylintrc deleted file mode 100644 index 9ccea6f..0000000 --- a/third_party/typ/pylintrc +++ /dev/null
@@ -1,272 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Profiled execution. -profile=no - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - -[MESSAGES CONTROL] - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). -# CHANGED: -# C0111: Missing docstring -# I0011: Locally disabling WNNNN -# R0201: Method could be a function -# R0801: Similar lines -# W0141: Used builtin function 'map' -# W0142: Used * or ** magic -# W0511: TODO -# W0703: Catch "Exception" -disable=C0111,I0011,R0201,R0801,W0141,W0142,W0511,W0703 - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -# CHANGED: -reports=no - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (RP0004). -comment=no - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the beginning of the name of dummy variables -# (i.e. not used). -dummy-variables-rgx=_|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). -ignored-classes= - -# When zope mode is activated, add a predefined set of Zope acquired attributes -# to generated-members. -zope=no - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E0201 when accessed. Python regular -# expressions are accepted. -generated-members= - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - - -[FORMAT] - -# Maximum number of characters on a single line. -# max-line-length=200 -max-line-length=80 - -# Maximum number of lines in a module -# max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -# CHANGED: -indent-string=' ' - - -[BASIC] - -# Required attributes for module, separated by a comma -required-attributes= - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=(([a-zA-Z_][a-zA-Z0-9_]*)|(__.*__))$ - -# Regular expression which should only match correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression which should only match correct function names -function-rgx=[a-z_][a-z0-9_]{0,40}$ - -# Regular expression which should only match correct method names -method-rgx=[a-z_][a-z0-9_]{0,48}$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=[a-z_][a-z0-9_]{0,30}$ - -# Regular expression which should only match correct argument names -argument-rgx=[a-z_][a-z0-9_]{0,30}$ - -# Regular expression which should only match correct variable names -variable-rgx=[a-zA-Z0-9_]{0,30}$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Regular expression which should only match functions or classes name which do -# not require a docstring -no-docstring-rgx=__.*__ - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=8 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=32 - -# Maximum number of return / yield for function / method body -max-returns=32 - -# Maximum number of branch for function / method body -max-branches=32 - -# Maximum number of statements in function / method body -max-statements=65 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=16 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=0 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=100 - - -[CLASSES] - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,string,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception
diff --git a/third_party/typ/run b/third_party/typ/run deleted file mode 100755 index 401296bd..0000000 --- a/third_party/typ/run +++ /dev/null
@@ -1,98 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function - -import argparse -import os -import subprocess -import sys - -from tools import cov - - -class Runner(object): - - def __init__(self): - self._verbose = False - self._repo_dir = os.path.abspath(os.path.dirname(__file__)) - self._path_to_cov = os.path.join(self._repo_dir, 'tools', 'cov.py') - self._path_to_runner = os.path.join(self._repo_dir, 'typ', 'runner.py') - self._python = sys.executable - - def main(self, argv): - parser = argparse.ArgumentParser(prog='run') - parser.add_argument('-v', '--verbose', action='store_true') - subps = parser.add_subparsers() - - subp = subps.add_parser('clean', help='Remove any local files.') - subp.set_defaults(func=self.run_clean) - - subp = subps.add_parser('coverage', - help='Run the tests and report code coverage.') - subp.set_defaults(func=self.run_coverage) - cov.add_arguments(subp) - - subp = subps.add_parser('help', - help='Get help on a subcommand.') - subp.add_argument(nargs='?', action='store', dest='subcommand', - help='The command to get help for.') - subp.set_defaults(func=self.run_help) - - subp = subps.add_parser('lint', - help='run lint over the source') - subp.set_defaults(func=self.run_lint) - - subp = subps.add_parser('tests', - help='run the tests') - subp.set_defaults(func=self.run_tests) - - args = parser.parse_args(argv) - - self._verbose = args.verbose - args.func(args) - - def call(self, *args, **kwargs): - if self._verbose: - print(' '.join(args[0])) - ret = subprocess.call(*args, **kwargs) - if ret != 0: - sys.exit(ret) - - def run_clean(self, _args): - self.call(['git', 'clean', '-fxd']) - - def run_coverage(self, args): - if not args.path: - args.path = [self._repo_dir] - if not args.source: - args.source = [os.path.join(self._repo_dir, 'typ')] - argv = cov.argv_from_args(args) - cov_args = [self._path_to_runner, '-j', '1'] - self.call([self._python, self._path_to_cov] + argv + cov_args) - - def run_help(self, args): - if args.subcommand: - self.main([args.subcommand, '--help']) - self.main(['--help']) - - def run_lint(self, _args): - self.call('pylint --rcfile=pylintrc */*.py */*/*.py', shell=True) - - def run_tests(self, _args): - # Test running the typ module directly if it is in sys.path. - self.call([ - self._python, '-m', 'typ', - 'typ.tests.main_test.TestMain.test_basic', - ]) - - # Testing running the runner directly if nothing is in sys.path. - home_dir = os.environ['HOME'] - self.call([self._python, self._path_to_runner, - 'typ.tests.main_test.TestMain.test_basic'], cwd=home_dir) - - # Run the remaining tests. - self.call([self._python, self._path_to_runner]) - - -if __name__ == '__main__': - sys.exit(Runner().main(sys.argv[1:]))
diff --git a/third_party/typ/setup.cfg b/third_party/typ/setup.cfg deleted file mode 100644 index 3c6e79c..0000000 --- a/third_party/typ/setup.cfg +++ /dev/null
@@ -1,2 +0,0 @@ -[bdist_wheel] -universal=1
diff --git a/third_party/typ/setup.py b/third_party/typ/setup.py deleted file mode 100644 index f03f444..0000000 --- a/third_party/typ/setup.py +++ /dev/null
@@ -1,59 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -if here not in sys.path: - sys.path.insert(0, here) - -from typ.version import VERSION - -with open(os.path.join(here, 'README.rst')) as fp: - readme = fp.read().strip() - -readme_lines = readme.splitlines() - -setup( - name='typ', - packages=find_packages(), - package_data={'': ['../README.rst']}, - entry_points={ - 'console_scripts': [ - 'typ=typ.runner:main', - ] - }, - install_requires=[ - ], - version=VERSION, - author='Dirk Pranke', - author_email='dpranke@chromium.org', - description=readme_lines[3], - long_description=('\n' + '\n'.join(readme_lines)), - url='https://github.com/dpranke/typ', - license='Apache', - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Topic :: Software Development :: Testing', - ], -)
diff --git a/third_party/typ/tools/__init__.py b/third_party/typ/tools/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/third_party/typ/tools/__init__.py +++ /dev/null
diff --git a/third_party/typ/tools/cov.py b/third_party/typ/tools/cov.py deleted file mode 100755 index ff97728..0000000 --- a/third_party/typ/tools/cov.py +++ /dev/null
@@ -1,142 +0,0 @@ -#!/usr/bin/python -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import print_function - -import argparse -import sys -import textwrap - -is_python3 = bool(sys.version_info.major == 3) - - -ALL_PRAGMAS = ['no cover', 'no win32', 'python2', 'python3', 'untested', - 'win32'] -DEFAULT_PRAGMAS = ALL_PRAGMAS[:] - -if is_python3: - DEFAULT_PRAGMAS.remove('python3') -else: - DEFAULT_PRAGMAS.remove('python2') - -if sys.platform == 'win32': - DEFAULT_PRAGMAS.remove('win32') -else: - DEFAULT_PRAGMAS.remove('no win32') - - -def add_arguments(parser): - parser.add_argument('--no-pragmas', action='store_true', default=False, - help='Show all uncovered lines (no pragmas).') - parser.add_argument('--path', action='append', default=[], - help='Prepend given directories to sys.path.') - parser.add_argument('--pragma', action='append', default=[], - help=('The coverage pragmas to honor ' - '(defaults to %s).' % DEFAULT_PRAGMAS)) - parser.add_argument('--show', action='append', default=[], - help='Show code protected by the specified pragmas ' - '(uses all pragmas *except* for the ones ' - 'specified).') - parser.add_argument('--show-missing', action='store_true', - default=False, help='Show missing lines.') - parser.add_argument('--source', action='append', default=[], - help='Limit coverage data to the given directories.') - - parser.formatter_class = argparse.RawTextHelpFormatter - parser.epilog = textwrap.dedent(""" - Valid pragma values are: - 'no cover': The default coverage pragma, this now means we - truly cannot cover it. - 'no win32': Code that only executes when not on Windows. - 'python2': Code that only executes under Python2. - 'python3': Code that only executes under Python3. - 'untested': Code that does not yet have tests. - 'win32': Code that only executes on Windows. - - In typ, we aim for 'no cover' to only apply to code that executes only - when coverage is not available (and hence can never be counted). Most - code, if annotated at all, should be 'untested', and we should strive - for 'untested' to not be used, either. - """) - - -def argv_from_args(args): - argv = [] - if args.no_pragmas: - argv.append('--no-pragmas') - for arg in args.path: - argv.extend(['--path', arg]) - for arg in args.show: - argv.extend(['--show', arg]) - if args.show_missing: - argv.append('--show-missing') - for arg in args.source: - argv.extend(['--source', arg]) - for arg in args.pragma: - argv.extend(['--pragma', arg]) - return argv - - -def main(argv=None): - parser = argparse.ArgumentParser() - add_arguments(parser) - args, remaining_args = parser.parse_known_args(argv) - - for path in args.path: - if path not in sys.path: - sys.path.append(path) - - try: - import coverage - from coverage.execfile import run_python_module, run_python_file - except ImportError: - print("Error: coverage is not available.") - sys.exit(1) - - cov = coverage.coverage(source=args.source) - cov.erase() - cov.clear_exclude() - - if args.no_pragmas: - args.pragma = [] - - args.pragma = args.pragma or DEFAULT_PRAGMAS - - if args.show: - args.show_missing = True - for pragma in args.show: - if pragma in args.pragma: - args.pragma.remove(pragma) - - for pragma in args.pragma: - cov.exclude('pragma: %s' % pragma) - - ret = 0 - cov.start() - try: - if remaining_args[0] == '-m': - run_python_module(remaining_args[1], remaining_args[1:]) - else: - run_python_file(remaining_args[0], remaining_args) - except SystemExit as e: - ret = e.code - cov.stop() - cov.save() - cov.report(show_missing=args.show_missing) - return ret - - -if __name__ == '__main__': - sys.exit(main())
diff --git a/third_party/typ/typ/__init__.py b/third_party/typ/typ/__init__.py deleted file mode 100644 index ab04414..0000000 --- a/third_party/typ/typ/__init__.py +++ /dev/null
@@ -1,93 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Test Your Project - -typ is a simple program for testing command line executables and Python code. - -When testing Python code, it is basically a wrapper around the standard -unittest module, but it provides the following bits of additional -functionality: - - * Parallel test execution. - - * Clean output in the style of the Ninja build tool. - - * A more flexible mechanism for discovering tests from the - command line and controlling how they are run: - * Support for importing tests by directory, filename, or module. - * Support for specifying tests to skip, tests to run in parallel, - and tests that need to be run by themselves - - * Support for producing traces of test times compatible with Chrome's - tracing infrastructure (trace_viewer). - - * Integrated test coverage reporting. - - * Integrated support for debugging tests. - - * Support for uploading test results automatically to a server - (useful for continuous integration monitoring of test results). - - * An abstraction of operating system functionality called the - Host class. This can be used by other python code to write more - portable and easily testable code by wrapping the multiprocessing, - os, subprocess, and time modules. - - * Simple libraries for integrating Ninja-style statistics and line - printing into your own code (the Stats and Printer classes). - - * Support for processing arbitrary arguments from calling code to - test cases. - - * Support for once-per-process setup and teardown hooks. - (These last two bullet points allow one to write tests that do not - require Python globals). -""" - -from typ.arg_parser import ArgumentParser -from typ.fakes.host_fake import FakeHost -from typ.host import Host -from typ.json_results import exit_code_from_full_results -from typ.json_results import make_full_results, make_upload_request -from typ.json_results import Result, ResultSet, ResultType -from typ.runner import Runner, TestInput, TestSet, WinMultiprocessing, main -from typ.stats import Stats -from typ.printer import Printer -from typ.test_case import convert_newlines, TestCase, MainTestCase -from typ.version import VERSION - - -__all__ = [ - 'ArgumentParser', - 'FakeHost', - 'Host', - 'MainTestCase', - 'Printer', - 'Result', - 'ResultSet', - 'ResultType', - 'Runner', - 'Stats', - 'TestCase', - 'TestInput', - 'TestSet', - 'VERSION', - 'WinMultiprocessing', - 'convert_newlines', - 'exit_code_from_full_results', - 'main', - 'make_full_results', - 'make_upload_request', -]
diff --git a/third_party/typ/typ/__main__.py b/third_party/typ/typ/__main__.py deleted file mode 100644 index 0e026e8..0000000 --- a/third_party/typ/typ/__main__.py +++ /dev/null
@@ -1,21 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys # pragma: no cover - -from typ import main # pragma: no cover - - -if __name__ == '__main__': # pragma: no cover - sys.exit(main())
diff --git a/third_party/typ/typ/arg_parser.py b/third_party/typ/typ/arg_parser.py deleted file mode 100644 index 707adab0..0000000 --- a/third_party/typ/typ/arg_parser.py +++ /dev/null
@@ -1,342 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import argparse -import optparse - -from typ.host import Host - - -class _Bailout(Exception): - pass - - -DEFAULT_COVERAGE_OMIT = ['*/typ/*', '*/site-packages/*'] -DEFAULT_STATUS_FORMAT = '[%f/%t] ' -DEFAULT_SUFFIXES = ['*_test.py', '*_unittest.py'] - - -class ArgumentParser(argparse.ArgumentParser): - - @staticmethod - def add_option_group(parser, title, discovery=False, - running=False, reporting=False, skip=None): - # TODO: Get rid of this when telemetry upgrades to argparse. - ap = ArgumentParser(add_help=False, version=False, discovery=discovery, - running=running, reporting=reporting) - optlist = ap.optparse_options(skip=skip) - group = optparse.OptionGroup(parser, title) - group.add_options(optlist) - parser.add_option_group(group) - - def __init__(self, host=None, add_help=True, version=True, discovery=True, - reporting=True, running=True): - super(ArgumentParser, self).__init__(prog='typ', add_help=add_help) - - self._host = host or Host() - self.exit_status = None - - self.usage = '%(prog)s [options] [tests...]' - - if version: - self.add_argument('-V', '--version', action='store_true', - help='Print the typ version and exit.') - - if discovery: - self.add_argument('-f', '--file-list', metavar='FILENAME', - action='store', - help=('Takes the list of tests from the file ' - '(use "-" for stdin).')) - self.add_argument('--all', action='store_true', - help=('Run all the tests, including the ones ' - 'normally skipped.')) - self.add_argument('--isolate', metavar='glob', default=[], - action='append', - help=('Globs of tests to run in isolation ' - '(serially).')) - self.add_argument('--skip', metavar='glob', default=[], - action='append', - help=('Globs of test names to skip (' - 'defaults to %(default)s).')) - self.add_argument('--suffixes', metavar='glob', default=[], - action='append', - help=('Globs of test filenames to look for (' - 'can specify multiple times; defaults ' - 'to %s).' % DEFAULT_SUFFIXES)) - - if reporting: - self.add_argument('--builder-name', - help=('Builder name to include in the ' - 'uploaded data.')) - self.add_argument('-c', '--coverage', action='store_true', - help='Reports coverage information.') - self.add_argument('--coverage-source', action='append', - default=[], - help=('Directories to include when running and ' - 'reporting coverage (defaults to ' - '--top-level-dirs plus --path)')) - self.add_argument('--coverage-omit', action='append', - default=[], - help=('Globs to omit when reporting coverage ' - '(defaults to %s).' % - DEFAULT_COVERAGE_OMIT)) - self.add_argument('--coverage-annotate', action='store_true', - help=('Produce an annotate source report.')) - self.add_argument('--coverage-show-missing', action='store_true', - help=('Show missing line ranges in coverage ' - 'report.')) - self.add_argument('--master-name', - help=('Buildbot master name to include in the ' - 'uploaded data.')) - self.add_argument('--metadata', action='append', default=[], - help=('Optional key=value metadata that will ' - 'be included in the results.')) - self.add_argument('--test-results-server', - help=('If specified, uploads the full results ' - 'to this server.')) - self.add_argument('--test-type', - help=('Name of test type to include in the ' - 'uploaded data (e.g., ' - '"telemetry_unittests").')) - self.add_argument('--write-full-results-to', metavar='FILENAME', - action='store', - help=('If specified, writes the full results to ' - 'that path.')) - self.add_argument('--write-trace-to', metavar='FILENAME', - action='store', - help=('If specified, writes the trace to ' - 'that path.')) - self.add_argument('tests', nargs='*', default=[], - help=argparse.SUPPRESS) - - if running: - self.add_argument('-d', '--debugger', action='store_true', - help='Runs the tests under the debugger.') - self.add_argument('-j', '--jobs', metavar='N', type=int, - default=self._host.cpu_count(), - help=('Runs N jobs in parallel ' - '(defaults to %(default)s).')) - self.add_argument('-l', '--list-only', action='store_true', - help='Lists all the test names found and exits.') - self.add_argument('-n', '--dry-run', action='store_true', - help=argparse.SUPPRESS) - self.add_argument('-q', '--quiet', action='store_true', - default=False, - help=('Runs as quietly as possible ' - '(only prints errors).')) - self.add_argument('-s', '--status-format', - default=self._host.getenv('NINJA_STATUS', - DEFAULT_STATUS_FORMAT), - help=argparse.SUPPRESS) - self.add_argument('-t', '--timing', action='store_true', - help='Prints timing info.') - self.add_argument('-v', '--verbose', action='count', default=0, - help=('Prints more stuff (can specify multiple ' - 'times for more output).')) - self.add_argument('--passthrough', action='store_true', - default=False, - help='Prints all output while running.') - self.add_argument('--total-shards', default=1, type=int, - help=('Total number of shards being used for ' - 'this test run. (The user of ' - 'this script is responsible for spawning ' - 'all of the shards.)')) - self.add_argument('--shard-index', default=0, type=int, - help=('Shard index (0..total_shards-1) of this ' - 'test run.')) - self.add_argument('--retry-limit', type=int, default=0, - help='Retries each failure up to N times.') - self.add_argument('--terminal-width', type=int, - default=self._host.terminal_width(), - help=argparse.SUPPRESS) - self.add_argument('--overwrite', action='store_true', - default=None, - help=argparse.SUPPRESS) - self.add_argument('--no-overwrite', action='store_false', - dest='overwrite', default=None, - help=argparse.SUPPRESS) - - if discovery or running: - self.add_argument('-P', '--path', action='append', default=[], - help=('Adds dir to sys.path (can specify ' - 'multiple times).')) - self.add_argument('--top-level-dir', action='store', default=None, - help=argparse.SUPPRESS) - self.add_argument('--top-level-dirs', action='append', default=[], - help=('Sets the top directory of project ' - '(used when running subdirs).')) - - def parse_args(self, args=None, namespace=None): - try: - rargs = super(ArgumentParser, self).parse_args(args=args, - namespace=namespace) - except _Bailout: - return None - - for val in rargs.metadata: - if '=' not in val: - self._print_message('Error: malformed --metadata "%s"' % val) - self.exit_status = 2 - - if rargs.test_results_server: - if not rargs.builder_name: - self._print_message('Error: --builder-name must be specified ' - 'along with --test-result-server') - self.exit_status = 2 - if not rargs.master_name: - self._print_message('Error: --master-name must be specified ' - 'along with --test-result-server') - self.exit_status = 2 - if not rargs.test_type: - self._print_message('Error: --test-type must be specified ' - 'along with --test-result-server') - self.exit_status = 2 - - if rargs.total_shards < 1: - self._print_message('Error: --total-shards must be at least 1') - self.exit_status = 2 - - if rargs.shard_index < 0: - self._print_message('Error: --shard-index must be at least 0') - self.exit_status = 2 - - if rargs.shard_index >= rargs.total_shards: - self._print_message('Error: --shard-index must be no more than ' - 'the number of shards (%i) minus 1' % - rargs.total_shards) - self.exit_status = 2 - - if not rargs.suffixes: - rargs.suffixes = DEFAULT_SUFFIXES - - if not rargs.coverage_omit: - rargs.coverage_omit = DEFAULT_COVERAGE_OMIT - - if rargs.debugger: # pragma: no cover - rargs.jobs = 1 - rargs.passthrough = True - - if rargs.overwrite is None: - rargs.overwrite = self._host.stdout.isatty() and not rargs.verbose - - return rargs - - # Redefining built-in 'file' pylint: disable=W0622 - - def _print_message(self, msg, file=None): - self._host.print_(msg=msg, stream=file, end='\n') - - def print_help(self, file=None): - self._print_message(msg=self.format_help(), file=file) - - def error(self, message, bailout=True): # pylint: disable=W0221 - self.exit(2, '%s: error: %s\n' % (self.prog, message), bailout=bailout) - - def exit(self, status=0, message=None, # pylint: disable=W0221 - bailout=True): - self.exit_status = status - if message: - self._print_message(message, file=self._host.stderr) - if bailout: - raise _Bailout() - - def optparse_options(self, skip=None): - skip = skip or [] - options = [] - for action in self._actions: - args = [flag for flag in action.option_strings if flag not in skip] - if not args or action.help == '==SUPPRESS==': - # must either be a positional argument like 'tests' - # or an option we want to skip altogether. - continue - - kwargs = { - 'default': action.default, - 'dest': action.dest, - 'help': action.help, - 'metavar': action.metavar, - 'type': action.type, - 'action': _action_str(action) - } - options.append(optparse.make_option(*args, **kwargs)) - return options - - def argv_from_args(self, args): - default_parser = ArgumentParser(host=self._host) - default_args = default_parser.parse_args([]) - argv = [] - tests = [] - d = vars(args) - for k in sorted(d.keys()): - v = d[k] - argname = _argname_from_key(k) - action = self._action_for_key(k) - if not action: - continue - action_str = _action_str(action) - if k == 'tests': - tests = v - continue - if getattr(default_args, k) == v: - # this arg has the default value, so skip it. - continue - - assert action_str in ['append', 'count', 'store', 'store_true'] - if action_str == 'append': - for el in v: - argv.append(argname) - argv.append(el) - elif action_str == 'count': - for _ in range(v): - argv.append(argname) - elif action_str == 'store': - argv.append(argname) - argv.append(str(v)) - else: - # action_str == 'store_true' - argv.append(argname) - - return argv + tests - - def _action_for_key(self, key): - for action in self._actions: - if action.dest == key: - return action - - # Assume foreign argument: something used by the embedder of typ, for - # example. - return None - - -def _action_str(action): - # Access to a protected member pylint: disable=W0212 - assert action.__class__ in ( - argparse._AppendAction, - argparse._CountAction, - argparse._StoreAction, - argparse._StoreTrueAction - ) - - if isinstance(action, argparse._AppendAction): - return 'append' - if isinstance(action, argparse._CountAction): - return 'count' - if isinstance(action, argparse._StoreAction): - return 'store' - if isinstance(action, argparse._StoreTrueAction): - return 'store_true' - - -def _argname_from_key(key): - return '--' + key.replace('_', '-')
diff --git a/third_party/typ/typ/fakes/__init__.py b/third_party/typ/typ/fakes/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/third_party/typ/typ/fakes/__init__.py +++ /dev/null
diff --git a/third_party/typ/typ/fakes/host_fake.py b/third_party/typ/typ/fakes/host_fake.py deleted file mode 100644 index 89c0075..0000000 --- a/third_party/typ/typ/fakes/host_fake.py +++ /dev/null
@@ -1,292 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import copy -import io -import logging -import sys - -from typ.host import _TeedStream - - -is_python3 = bool(sys.version_info.major == 3) - -if is_python3: # pragma: python3 - # pylint: disable=redefined-builtin,invalid-name - unicode = str - - -class FakeHost(object): - # "too many instance attributes" pylint: disable=R0902 - # "redefining built-in" pylint: disable=W0622 - # "unused arg" pylint: disable=W0613 - - python_interpreter = 'python' - is_python3 = bool(sys.version_info.major == 3) - - def __init__(self): - self.logger = logging.getLogger() - self.stdin = io.StringIO() - self.stdout = io.StringIO() - self.stderr = io.StringIO() - self.platform = 'linux2' - self.env = {} - self.sep = '/' - self.dirs = set([]) - self.files = {} - self.fetches = [] - self.fetch_responses = {} - self.written_files = {} - self.last_tmpdir = None - self.current_tmpno = 0 - self.mtimes = {} - self.cmds = [] - self.cwd = '/tmp' - self._orig_logging_handlers = [] - - def __getstate__(self): - d = copy.copy(self.__dict__) - del d['stderr'] - del d['stdout'] - del d['stdin'] - del d['logger'] - del d['_orig_logging_handlers'] - return d - - def __setstate__(self, d): - for k, v in d.items(): - setattr(self, k, v) - self.logger = logging.getLogger() - self.stdin = io.StringIO() - self.stdout = io.StringIO() - self.stderr = io.StringIO() - - def abspath(self, *comps): - relpath = self.join(*comps) - if relpath.startswith('/'): - return relpath - return self.join(self.cwd, relpath) - - def add_to_path(self, *comps): - absolute_path = self.abspath(*comps) - if absolute_path not in sys.path: - sys.path.append(absolute_path) - - def basename(self, path): - return path.split(self.sep)[-1] - - def call(self, argv, stdin=None, env=None): - self.cmds.append(argv) - return 0, '', '' - - def call_inline(self, argv): - return self.call(argv)[0] - - def chdir(self, *comps): - path = self.join(*comps) - if not path.startswith('/'): - path = self.join(self.cwd, path) - self.cwd = path - - def cpu_count(self): - return 1 - - def dirname(self, path): - return '/'.join(path.split('/')[:-1]) - - def exists(self, *comps): - path = self.abspath(*comps) - return ((path in self.files and self.files[path] is not None) or - path in self.dirs) - - def files_under(self, top): - files = [] - top = self.abspath(top) - for f in self.files: - if self.files[f] is not None and f.startswith(top): - files.append(self.relpath(f, top)) - return files - - def for_mp(self): - return self - - def getcwd(self): - return self.cwd - - def getenv(self, key, default=None): - return self.env.get(key, default) - - def getpid(self): - return 1 - - def isdir(self, *comps): - path = self.abspath(*comps) - return path in self.dirs - - def isfile(self, *comps): - path = self.abspath(*comps) - return path in self.files and self.files[path] is not None - - def join(self, *comps): - p = '' - for c in comps: - if c in ('', '.'): - continue - elif c.startswith('/'): - p = c - elif p: - p += '/' + c - else: - p = c - - # Handle ./ - p = p.replace('/./', '/') - - # Handle ../ - while '/..' in p: - comps = p.split('/') - idx = comps.index('..') - comps = comps[:idx-1] + comps[idx+1:] - p = '/'.join(comps) - return p - - def maybe_mkdir(self, *comps): - path = self.abspath(self.join(*comps)) - if path not in self.dirs: - self.dirs.add(path) - - def mktempfile(self, delete=True): - curno = self.current_tmpno - self.current_tmpno += 1 - f = io.StringIO() - f.name = '__im_tmp/tmpfile_%u' % curno - return f - - def mkdtemp(self, suffix='', prefix='tmp', dir=None, **_kwargs): - if dir is None: - dir = self.sep + '__im_tmp' - curno = self.current_tmpno - self.current_tmpno += 1 - self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix)) - self.dirs.add(self.last_tmpdir) - return self.last_tmpdir - - def mtime(self, *comps): - return self.mtimes.get(self.join(*comps), 0) - - def print_(self, msg='', end='\n', stream=None): - stream = stream or self.stdout - stream.write(msg + end) - stream.flush() - - def read_binary_file(self, *comps): - return self._read(comps) - - def read_text_file(self, *comps): - return self._read(comps) - - def _read(self, comps): - return self.files[self.abspath(*comps)] - - def realpath(self, *comps): - return self.abspath(*comps) - - def relpath(self, path, start): - return path.replace(start + '/', '') - - def remove(self, *comps): - path = self.abspath(*comps) - self.files[path] = None - self.written_files[path] = None - - def rmtree(self, *comps): - path = self.abspath(*comps) - for f in self.files: - if f.startswith(path): - self.files[f] = None - self.written_files[f] = None - self.dirs.remove(path) - - def terminal_width(self): - return 80 - - def splitext(self, path): - idx = path.rfind('.') - if idx == -1: - return (path, '') - return (path[:idx], path[idx:]) - - def time(self): - return 0 - - def write_binary_file(self, path, contents): - self._write(path, contents) - - def write_text_file(self, path, contents): - self._write(path, contents) - - def _write(self, path, contents): - full_path = self.abspath(path) - self.maybe_mkdir(self.dirname(full_path)) - self.files[full_path] = contents - self.written_files[full_path] = contents - - def fetch(self, url, data=None, headers=None): - resp = self.fetch_responses.get(url, FakeResponse(unicode(''), url)) - self.fetches.append((url, data, headers, resp)) - return resp - - def _tap_output(self): - self.stdout = _TeedStream(self.stdout) - self.stderr = _TeedStream(self.stderr) - if True: - sys.stdout = self.stdout - sys.stderr = self.stderr - - def _untap_output(self): - assert isinstance(self.stdout, _TeedStream) - self.stdout = self.stdout.stream - self.stderr = self.stderr.stream - if True: - sys.stdout = self.stdout - sys.stderr = self.stderr - - def capture_output(self, divert=True): - self._tap_output() - self._orig_logging_handlers = self.logger.handlers - if self._orig_logging_handlers: - self.logger.handlers = [logging.StreamHandler(self.stderr)] - self.stdout.capture(divert=divert) - self.stderr.capture(divert=divert) - - def restore_output(self): - assert isinstance(self.stdout, _TeedStream) - out, err = (self.stdout.restore(), self.stderr.restore()) - self.logger.handlers = self._orig_logging_handlers - self._untap_output() - return out, err - - -class FakeResponse(io.StringIO): - - def __init__(self, response, url, code=200): - io.StringIO.__init__(self, response) - self._url = url - self.code = code - - def geturl(self): - return self._url - - def getcode(self): - return self.code
diff --git a/third_party/typ/typ/fakes/test_result_server_fake.py b/third_party/typ/typ/fakes/test_result_server_fake.py deleted file mode 100644 index 2cc876c..0000000 --- a/third_party/typ/typ/fakes/test_result_server_fake.py +++ /dev/null
@@ -1,79 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""A fake implementation of test-results.appspot.com.""" - -import io -import sys -import threading - - -if sys.version_info.major == 2: # pragma: python2 - from SimpleHTTPServer import SimpleHTTPRequestHandler as HTTPRequestHandler - from SocketServer import TCPServer -else: # pragma: python3 - assert sys.version_info.major == 3 - # pylint: disable=invalid-name, redefined-builtin - unicode = str - from http.server import BaseHTTPRequestHandler # pylint: disable=F0401 - HTTPRequestHandler = BaseHTTPRequestHandler - from socketserver import TCPServer # pylint: disable=F0401 - - -def start(code=200): - server = _Server(code=code) - thread = threading.Thread(target=_run, args=(server,)) - server.main_thread = thread - thread.daemon = True - thread.start() - return server - - -def _run(server): - server.serve_forever(0.05) - - -class _Server(TCPServer): - - def __init__(self, code): - self.allow_reuse_address = True - TCPServer.__init__(self, ('localhost', 0), _RequestHandler) - self.log = io.StringIO() - self.requests = [] - self.main_thread = None - self.code = code - - def stop(self): - self.shutdown() - self.main_thread.join() - return self.requests - - -class _RequestHandler(HTTPRequestHandler): - - def __init__(self, *args, **kwargs): - HTTPRequestHandler.__init__(self, *args, **kwargs) - - # 'Invalid Name' pylint: disable=C0103 - def do_POST(self): - path = self.path - length = int(self.headers['content-length']) - payload = self.rfile.read(length) - self.server.requests.append(('post', path, payload)) - self.send_response(self.server.code) - self.end_headers() - - # 'Redefining built-in' pylint: disable=W0622 - def log_message(self, format, *args): - self.server.log.write(unicode('%s\n' % (format % args)))
diff --git a/third_party/typ/typ/fakes/tests/__init__.py b/third_party/typ/typ/fakes/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/third_party/typ/typ/fakes/tests/__init__.py +++ /dev/null
diff --git a/third_party/typ/typ/fakes/tests/host_fake_test.py b/third_party/typ/typ/fakes/tests/host_fake_test.py deleted file mode 100644 index a16b7ba1..0000000 --- a/third_party/typ/typ/fakes/tests/host_fake_test.py +++ /dev/null
@@ -1,83 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys - -from typ.tests import host_test -from typ.fakes.host_fake import FakeHost, FakeResponse - -is_python3 = bool(sys.version_info.major == 3) - -if is_python3: # pragma: python3 - # redefining built-in 'unicode' pylint: disable=W0622 - unicode = str - -class TestFakeHost(host_test.TestHost): - - def host(self): - return FakeHost() - - def test_add_to_path(self): - # TODO: FakeHost uses the real sys.path, and then gets - # confused becayse host.abspath() doesn't work right for - # windows-style paths. - if sys.platform != 'win32': - super(TestFakeHost, self).test_add_to_path() - - def test_call(self): - h = self.host() - ret, out, err = h.call(['echo', 'hello, world']) - self.assertEqual(ret, 0) - self.assertEqual(out, '') - self.assertEqual(err, '') - self.assertEqual(h.cmds, [['echo', 'hello, world']]) - - def test_call_inline(self): - h = self.host() - ret = h.call_inline(['echo', 'hello, world']) - self.assertEqual(ret, 0) - - def test_capture_output(self): - h = self.host() - self.host = lambda: h - super(TestFakeHost, self).test_capture_output() - - # This tests that the super-method only tested the - # divert=True case, and things were diverted properly. - self.assertEqual(h.stdout.getvalue(), '') - self.assertEqual(h.stderr.getvalue(), '') - - h.capture_output(divert=False) - h.print_('on stdout') - h.print_('on stderr', stream=h.stderr) - out, err = h.restore_output() - self.assertEqual(out, 'on stdout\n') - self.assertEqual(err, 'on stderr\n') - self.assertEqual(h.stdout.getvalue(), 'on stdout\n') - self.assertEqual(h.stderr.getvalue(), 'on stderr\n') - - def test_for_mp(self): - h = self.host() - self.assertNotEqual(h.for_mp(), None) - - def test_fetch(self): - h = self.host() - url = 'http://localhost/test' - resp = FakeResponse(unicode('foo'), url) - h.fetch_responses[url] = resp - actual_resp = h.fetch(url) - self.assertEqual(actual_resp.geturl(), url) - self.assertEqual(actual_resp.getcode(), 200) - self.assertEqual(resp, actual_resp) - self.assertEqual(h.fetches, [(url, None, None, actual_resp)])
diff --git a/third_party/typ/typ/fakes/tests/test_result_server_fake_test.py b/third_party/typ/typ/fakes/tests/test_result_server_fake_test.py deleted file mode 100644 index 87316c87..0000000 --- a/third_party/typ/typ/fakes/tests/test_result_server_fake_test.py +++ /dev/null
@@ -1,36 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -from typ.fakes import test_result_server_fake -from typ import Host - - -class TestResultServerFakeTest(unittest.TestCase): - def test_basic_upload(self): - host = Host() - server = None - posts = [] - try: - server = test_result_server_fake.start() - url = 'http://%s:%d/testfile/upload' % server.server_address - if server: - resp = host.fetch(url, 'foo=bar') - finally: - if server: - posts = server.stop() - self.assertEqual(posts, [('post', '/testfile/upload', - 'foo=bar'.encode('utf8'))]) - self.assertNotEqual(server.log.getvalue(), '')
diff --git a/third_party/typ/typ/host.py b/third_party/typ/typ/host.py deleted file mode 100644 index 42890db5..0000000 --- a/third_party/typ/typ/host.py +++ /dev/null
@@ -1,286 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import io -import logging -import multiprocessing -import os -import shutil -import subprocess -import sys -import tempfile -import time - - -if sys.version_info.major == 2: # pragma: python2 - from urllib2 import urlopen, Request -else: # pragma: python3 - # pylint: disable=E0611 - assert sys.version_info.major == 3 - from urllib.request import urlopen, Request # pylint: disable=F0401,E0611 - - -class Host(object): - python_interpreter = sys.executable - is_python3 = bool(sys.version_info.major == 3) - - pathsep = os.pathsep - sep = os.sep - env = os.environ - - _orig_stdout = sys.stdout - _orig_stderr = sys.stderr - - def __init__(self): - self.logger = logging.getLogger() - self._orig_logging_handlers = None - self.stdout = sys.stdout - self.stderr = sys.stderr - self.stdin = sys.stdin - self.env = os.environ - self.platform = sys.platform - - def abspath(self, *comps): - return os.path.abspath(self.join(*comps)) - - def add_to_path(self, *comps): - absolute_path = self.abspath(*comps) - if absolute_path not in sys.path: - sys.path.insert(0, absolute_path) - - def basename(self, path): - return os.path.basename(path) - - def call(self, argv, stdin=None, env=None): - if stdin: - stdin_pipe = subprocess.PIPE - else: - stdin_pipe = None - proc = subprocess.Popen(argv, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, stdin=stdin_pipe, - env=env) - if stdin_pipe: - proc.stdin.write(stdin.encode('utf-8')) - stdout, stderr = proc.communicate() - - # pylint type checking bug - pylint: disable=E1103 - return proc.returncode, stdout.decode('utf-8'), stderr.decode('utf-8') - - def call_inline(self, argv, env=None): - if isinstance(self.stdout, _TeedStream): # pragma: no cover - ret, out, err = self.call(argv, env) - self.print_(out, end='') - self.print_(err, end='', stream=self.stderr) - return ret - return subprocess.call(argv, stdin=self.stdin, stdout=self.stdout, - stderr=self.stderr, env=env) - - def chdir(self, *comps): - return os.chdir(self.join(*comps)) - - def cpu_count(self): - return multiprocessing.cpu_count() - - def dirname(self, *comps): - return os.path.dirname(self.join(*comps)) - - def exists(self, *comps): - return os.path.exists(self.join(*comps)) - - def files_under(self, top): - all_files = [] - for root, _, files in os.walk(top): - for f in files: - relpath = self.relpath(os.path.join(root, f), top) - all_files.append(relpath) - return all_files - - def getcwd(self): - return os.getcwd() - - def getenv(self, key, default=None): - return self.env.get(key, default) - - def getpid(self): - return os.getpid() - - def for_mp(self): - return None - - def isdir(self, *comps): - return os.path.isdir(os.path.join(*comps)) - - def isfile(self, *comps): - return os.path.isfile(os.path.join(*comps)) - - def join(self, *comps): - return os.path.join(*comps) - - def maybe_mkdir(self, *comps): - path = self.abspath(self.join(*comps)) - if not self.exists(path): - os.makedirs(path) - - def mktempfile(self, delete=True): - return tempfile.NamedTemporaryFile(delete=delete) - - def mkdtemp(self, **kwargs): - return tempfile.mkdtemp(**kwargs) - - def mtime(self, *comps): - return os.stat(self.join(*comps)).st_mtime - - def print_(self, msg='', end='\n', stream=None): - stream = stream or self.stdout - stream.write(str(msg) + end) - stream.flush() - - def read_text_file(self, *comps): - return self._read(comps, 'r') - - def read_binary_file(self, *comps): - return self._read(comps, 'rb') - - def _read(self, comps, mode): - path = self.join(*comps) - with open(path, mode) as f: - return f.read() - - def realpath(self, *comps): - return os.path.realpath(os.path.join(*comps)) - - def relpath(self, path, start): - return os.path.relpath(path, start) - - def remove(self, *comps): - os.remove(self.join(*comps)) - - def rmtree(self, path): - shutil.rmtree(path, ignore_errors=True) - - def splitext(self, path): - return os.path.splitext(path) - - def time(self): - return time.time() - - def write_text_file(self, path, contents): - return self._write(path, contents, mode='w') - - def write_binary_file(self, path, contents): - return self._write(path, contents, mode='wb') - - def _write(self, path, contents, mode): - with open(path, mode) as f: - f.write(contents) - - def fetch(self, url, data=None, headers=None): - headers = headers or {} - return urlopen(Request(url, data.encode('utf8'), headers)) - - def terminal_width(self): - """Returns 0 if the width cannot be determined.""" - try: - if sys.platform == 'win32': # pragma: win32 - # From http://code.activestate.com/recipes/ \ - # 440694-determine-size-of-console-window-on-windows/ - from ctypes import windll, create_string_buffer - - STDERR_HANDLE = -12 - handle = windll.kernel32.GetStdHandle(STDERR_HANDLE) - - SCREEN_BUFFER_INFO_SZ = 22 - buf = create_string_buffer(SCREEN_BUFFER_INFO_SZ) - - if windll.kernel32.GetConsoleScreenBufferInfo(handle, buf): - import struct - fields = struct.unpack("hhhhHhhhhhh", buf.raw) - left = fields[5] - right = fields[7] - - # Note that we return 1 less than the width since writing - # into the rightmost column automatically performs a - # line feed. - return right - left - return 0 - else: # pragma: no win32 - import fcntl - import struct - import termios - packed = fcntl.ioctl(self.stderr.fileno(), - termios.TIOCGWINSZ, '\0' * 8) - _, columns, _, _ = struct.unpack('HHHH', packed) - return columns - except Exception: - return 0 - - def _tap_output(self): - self.stdout = sys.stdout = _TeedStream(self.stdout) - self.stderr = sys.stderr = _TeedStream(self.stderr) - - def _untap_output(self): - assert isinstance(self.stdout, _TeedStream) - self.stdout = sys.stdout = self.stdout.stream - self.stderr = sys.stderr = self.stderr.stream - - def capture_output(self, divert=True): - self._tap_output() - self._orig_logging_handlers = self.logger.handlers - if self._orig_logging_handlers: - self.logger.handlers = [logging.StreamHandler(self.stderr)] - self.stdout.capture(divert) - self.stderr.capture(divert) - - def restore_output(self): - assert isinstance(self.stdout, _TeedStream) - out, err = (self.stdout.restore(), self.stderr.restore()) - self.logger.handlers = self._orig_logging_handlers - self._untap_output() - return out, err - - -class _TeedStream(io.StringIO): - - def __init__(self, stream): - super(_TeedStream, self).__init__() - self.stream = stream - self.capturing = False - self.diverting = False - - def write(self, msg, *args, **kwargs): - if self.capturing: - if (sys.version_info.major == 2 and - isinstance(msg, str)): # pragma: python2 - msg = unicode(msg) - super(_TeedStream, self).write(msg, *args, **kwargs) - if not self.diverting: - self.stream.write(msg, *args, **kwargs) - - def flush(self): - if self.capturing: - super(_TeedStream, self).flush() - if not self.diverting: - self.stream.flush() - - def capture(self, divert=True): - self.truncate(0) - self.capturing = True - self.diverting = divert - - def restore(self): - msg = self.getvalue() - self.truncate(0) - self.capturing = False - self.diverting = False - return msg
diff --git a/third_party/typ/typ/json_results.py b/third_party/typ/typ/json_results.py deleted file mode 100644 index f048d05..0000000 --- a/third_party/typ/typ/json_results.py +++ /dev/null
@@ -1,212 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections import OrderedDict - -import json - - -class ResultType(object): - Pass = 'Pass' - Failure = 'Failure' - ImageOnlyFailure = 'ImageOnlyFailure' - Timeout = 'Timeout' - Crash = 'Crash' - Skip = 'Skip' - - values = (Pass, Failure, ImageOnlyFailure, Timeout, Crash, Skip) - - -class Result(object): - # too many instance attributes pylint: disable=R0902 - # too many arguments pylint: disable=R0913 - - def __init__(self, name, actual, started, took, worker, - expected=None, unexpected=False, - flaky=False, code=0, out='', err='', pid=0): - self.name = name - self.actual = actual - self.started = started - self.took = took - self.worker = worker - self.expected = expected or [ResultType.Pass] - self.unexpected = unexpected - self.flaky = flaky - self.code = code - self.out = out - self.err = err - self.pid = pid - - -class ResultSet(object): - - def __init__(self): - self.results = [] - - def add(self, result): - self.results.append(result) - - -TEST_SEPARATOR = '.' - - -def make_full_results(metadata, seconds_since_epoch, all_test_names, results): - """Convert the typ results to the Chromium JSON test result format. - - See http://www.chromium.org/developers/the-json-test-results-format - """ - - # We use OrderedDicts here so that the output is stable. - full_results = OrderedDict() - full_results['version'] = 3 - full_results['interrupted'] = False - full_results['path_delimiter'] = TEST_SEPARATOR - full_results['seconds_since_epoch'] = seconds_since_epoch - - for md in metadata: - key, val = md.split('=', 1) - full_results[key] = val - - passing_tests = _passing_test_names(results) - failed_tests = failed_test_names(results) - skipped_tests = set(all_test_names) - passing_tests - failed_tests - - full_results['num_failures_by_type'] = OrderedDict() - full_results['num_failures_by_type']['FAIL'] = len(failed_tests) - full_results['num_failures_by_type']['PASS'] = len(passing_tests) - full_results['num_failures_by_type']['SKIP'] = len(skipped_tests) - - full_results['tests'] = OrderedDict() - - for test_name in all_test_names: - value = _results_for_test(test_name, results) - if test_name in skipped_tests: - value['expected'] = 'SKIP' - else: - value['expected'] = 'PASS' - if value['actual'].endswith('FAIL'): - value['is_unexpected'] = True - _add_path_to_trie(full_results['tests'], test_name, value) - - return full_results - - -def make_upload_request(test_results_server, builder, master, testtype, - full_results): - if test_results_server.startswith('http'): - url = '%s/testfile/upload' % test_results_server - else: - url = 'https://%s/testfile/upload' % test_results_server - attrs = [('builder', builder), - ('master', master), - ('testtype', testtype)] - content_type, data = _encode_multipart_form_data(attrs, full_results) - return url, content_type, data - - -def exit_code_from_full_results(full_results): - return 1 if num_failures(full_results) else 0 - - -def num_failures(full_results): - return full_results['num_failures_by_type']['FAIL'] - - -def num_passes(full_results): - return full_results['num_failures_by_type']['PASS'] - - -def num_skips(full_results): - return full_results['num_failures_by_type']['SKIP'] - - -def failed_test_names(results): - names = set() - for r in results.results: - if r.actual == ResultType.Failure: - names.add(r.name) - elif ((r.actual == ResultType.Pass or r.actual == ResultType.Skip) - and r.name in names): - # This check indicates that a test failed, and then either passed - # or was skipped on a retry. It is somewhat counterintuitive - # that a test that failed and then skipped wouldn't be considered - # failed, but that's at least consistent with a test that is - # skipped every time. - names.remove(r.name) - return names - - -def _passing_test_names(results): - return set(r.name for r in results.results if r.actual == ResultType.Pass) - - -def _results_for_test(test_name, results): - value = OrderedDict() - actuals = [] - times = [] - for r in results.results: - if r.name == test_name: - if r.actual == ResultType.Failure: - actuals.append('FAIL') - elif r.actual == ResultType.Pass: - actuals.append('PASS') - elif r.actual == ResultType.Skip: - actuals.append('SKIP') - - # The time a test takes is a floating point number of seconds; - # if we were to encode this unmodified, then when we converted it - # to JSON it might make the file significantly larger. Instead - # we truncate the file to ten-thousandths of a second, which is - # probably more than good enough for most tests. - times.append(round(r.took, 4)) - if not actuals: # pragma: untested - actuals.append('SKIP') - value['actual'] = ' '.join(actuals) - value['times'] = times - return value - -def _add_path_to_trie(trie, path, value): - if TEST_SEPARATOR not in path: - trie[path] = value - return - directory, rest = path.split(TEST_SEPARATOR, 1) - if directory not in trie: - trie[directory] = {} - _add_path_to_trie(trie[directory], rest, value) - - -def _encode_multipart_form_data(attrs, test_results): - # Cloned from webkitpy/common/net/file_uploader.py - BOUNDARY = '-J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - - for key, value in attrs: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - lines.append(value) - - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="file"; ' - 'filename="full_results.json"') - lines.append('Content-Type: application/json') - lines.append('') - lines.append(json.dumps(test_results)) - - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body
diff --git a/third_party/typ/typ/pool.py b/third_party/typ/typ/pool.py deleted file mode 100644 index 6200a8a..0000000 --- a/third_party/typ/typ/pool.py +++ /dev/null
@@ -1,204 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import copy -import multiprocessing -import pickle -import traceback - -from typ.host import Host - - -def make_pool(host, jobs, callback, context, pre_fn, post_fn): - _validate_args(context, pre_fn, post_fn) - if jobs > 1: - return _ProcessPool(host, jobs, callback, context, pre_fn, post_fn) - else: - return _AsyncPool(host, jobs, callback, context, pre_fn, post_fn) - - -class _MessageType(object): - Request = 'Request' - Response = 'Response' - Close = 'Close' - Done = 'Done' - Error = 'Error' - Interrupt = 'Interrupt' - - values = [Request, Response, Close, Done, Error, Interrupt] - - -def _validate_args(context, pre_fn, post_fn): - try: - _ = pickle.dumps(context) - except Exception as e: - raise ValueError('context passed to make_pool is not picklable: %s' - % str(e)) - try: - _ = pickle.dumps(pre_fn) - except pickle.PickleError: - raise ValueError('pre_fn passed to make_pool is not picklable') - try: - _ = pickle.dumps(post_fn) - except pickle.PickleError: - raise ValueError('post_fn passed to make_pool is not picklable') - - -class _ProcessPool(object): - - def __init__(self, host, jobs, callback, context, pre_fn, post_fn): - self.host = host - self.jobs = jobs - self.requests = multiprocessing.Queue() - self.responses = multiprocessing.Queue() - self.workers = [] - self.discarded_responses = [] - self.closed = False - self.erred = False - for worker_num in range(1, jobs + 1): - w = multiprocessing.Process(target=_loop, - args=(self.requests, self.responses, - host.for_mp(), worker_num, - callback, context, - pre_fn, post_fn)) - w.start() - self.workers.append(w) - - def send(self, msg): - self.requests.put((_MessageType.Request, msg)) - - def get(self): - msg_type, resp = self.responses.get() - if msg_type == _MessageType.Error: - self._handle_error(resp) - elif msg_type == _MessageType.Interrupt: - raise KeyboardInterrupt - assert msg_type == _MessageType.Response - return resp - - def close(self): - for _ in self.workers: - self.requests.put((_MessageType.Close, None)) - self.closed = True - - def join(self): - # TODO: one would think that we could close self.requests in close(), - # above, and close self.responses below, but if we do, we get - # weird tracebacks in the daemon threads multiprocessing starts up. - # Instead, we have to hack the innards of multiprocessing. It - # seems likely that there's a bug somewhere, either in this module or - # in multiprocessing. - # pylint: disable=protected-access - if self.host.is_python3: # pragma: python3 - multiprocessing.queues.is_exiting = lambda: True - else: # pragma: python2 - multiprocessing.util._exiting = True - - if not self.closed: - # We must be aborting; terminate the workers rather than - # shutting down cleanly. - for w in self.workers: - w.terminate() - w.join() - return [] - - final_responses = [] - error = None - interrupted = None - for w in self.workers: - while True: - msg_type, resp = self.responses.get() - if msg_type == _MessageType.Error: - error = resp - break - if msg_type == _MessageType.Interrupt: - interrupted = True - break - if msg_type == _MessageType.Done: - final_responses.append(resp[1]) - break - self.discarded_responses.append(resp) - - for w in self.workers: - w.join() - - # TODO: See comment above at the beginning of the function for - # why this is commented out. - # self.responses.close() - - if error: - self._handle_error(error) - if interrupted: - raise KeyboardInterrupt - return final_responses - - def _handle_error(self, msg): - worker_num, tb = msg - self.erred = True - raise Exception("Error from worker %d (traceback follows):\n%s" % - (worker_num, tb)) - - -# 'Too many arguments' pylint: disable=R0913 - -def _loop(requests, responses, host, worker_num, - callback, context, pre_fn, post_fn, should_loop=True): - host = host or Host() - try: - context_after_pre = pre_fn(host, worker_num, context) - keep_looping = True - while keep_looping: - message_type, args = requests.get(block=True) - if message_type == _MessageType.Close: - responses.put((_MessageType.Done, - (worker_num, post_fn(context_after_pre)))) - break - assert message_type == _MessageType.Request - resp = callback(context_after_pre, args) - responses.put((_MessageType.Response, resp)) - keep_looping = should_loop - except KeyboardInterrupt as e: - responses.put((_MessageType.Interrupt, (worker_num, str(e)))) - except Exception as e: - responses.put((_MessageType.Error, - (worker_num, traceback.format_exc(e)))) - - -class _AsyncPool(object): - - def __init__(self, host, jobs, callback, context, pre_fn, post_fn): - self.host = host or Host() - self.jobs = jobs - self.callback = callback - self.context = copy.deepcopy(context) - self.msgs = [] - self.closed = False - self.post_fn = post_fn - self.context_after_pre = pre_fn(self.host, 1, self.context) - self.final_context = None - - def send(self, msg): - self.msgs.append(msg) - - def get(self): - return self.callback(self.context_after_pre, self.msgs.pop(0)) - - def close(self): - self.closed = True - self.final_context = self.post_fn(self.context_after_pre) - - def join(self): - if not self.closed: - self.close() - return [self.final_context]
diff --git a/third_party/typ/typ/printer.py b/third_party/typ/typ/printer.py deleted file mode 100644 index 473537b..0000000 --- a/third_party/typ/typ/printer.py +++ /dev/null
@@ -1,40 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -class Printer(object): - - def __init__(self, print_, should_overwrite, cols): - self.print_ = print_ - self.should_overwrite = should_overwrite - self.cols = cols - self.last_line = '' - - def flush(self): - if self.last_line: - self.print_('') - self.last_line = '' - - def update(self, msg, elide=True): - msg_len = len(msg) - if elide and self.cols and msg_len > self.cols - 5: - new_len = int((self.cols - 5) / 2) - msg = msg[:new_len] + '...' + msg[-new_len:] - if self.should_overwrite and self.last_line: - self.print_('\r' + ' ' * len(self.last_line) + '\r', end='') - elif self.last_line: - self.print_('') - self.print_(msg, end='') - last_nl = msg.rfind('\n') - self.last_line = msg[last_nl + 1:]
diff --git a/third_party/typ/typ/runner.py b/third_party/typ/typ/runner.py deleted file mode 100644 index 62d92c7f..0000000 --- a/third_party/typ/typ/runner.py +++ /dev/null
@@ -1,993 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import fnmatch -import importlib -import inspect -import json -import os -import pdb -import sys -import unittest -import traceback - -from collections import OrderedDict - -# This ensures that absolute imports of typ modules will work when -# running typ/runner.py as a script even if typ is not installed. -# We need this entry in addition to the one in __main__.py to ensure -# that typ/runner.py works when invoked via subprocess on windows in -# _spawn_main(). -path_to_file = os.path.realpath(__file__) -if path_to_file.endswith('.pyc'): # pragma: no cover - path_to_file = path_to_file[:-1] -dir_above_typ = os.path.dirname(os.path.dirname(path_to_file)) -if dir_above_typ not in sys.path: # pragma: no cover - sys.path.append(dir_above_typ) - - -from typ import json_results -from typ.arg_parser import ArgumentParser -from typ.host import Host -from typ.pool import make_pool -from typ.stats import Stats -from typ.printer import Printer -from typ.test_case import TestCase as TypTestCase -from typ.version import VERSION - - -Result = json_results.Result -ResultSet = json_results.ResultSet -ResultType = json_results.ResultType - - -def main(argv=None, host=None, win_multiprocessing=None, **defaults): - host = host or Host() - runner = Runner(host=host) - if win_multiprocessing is not None: - runner.win_multiprocessing = win_multiprocessing - return runner.main(argv, **defaults) - - -class TestInput(object): - - def __init__(self, name, msg='', timeout=None, expected=None): - self.name = name - self.msg = msg - self.timeout = timeout - self.expected = expected - - -class TestSet(object): - - def __init__(self, parallel_tests=None, isolated_tests=None, - tests_to_skip=None): - - def promote(tests): - tests = tests or [] - return [test if isinstance(test, TestInput) else TestInput(test) - for test in tests] - - self.parallel_tests = promote(parallel_tests) - self.isolated_tests = promote(isolated_tests) - self.tests_to_skip = promote(tests_to_skip) - - -class WinMultiprocessing(object): - ignore = 'ignore' - importable = 'importable' - spawn = 'spawn' - - values = [ignore, importable, spawn] - - -class _AddTestsError(Exception): - pass - - -class Runner(object): - - def __init__(self, host=None): - self.args = None - self.classifier = None - self.cov = None - self.context = None - self.coverage_source = None - self.host = host or Host() - self.loader = unittest.loader.TestLoader() - self.printer = None - self.setup_fn = None - self.stats = None - self.teardown_fn = None - self.top_level_dir = None - self.top_level_dirs = [] - self.win_multiprocessing = WinMultiprocessing.spawn - self.final_responses = [] - - # initialize self.args to the defaults. - parser = ArgumentParser(self.host) - self.parse_args(parser, []) - - def main(self, argv=None, **defaults): - parser = ArgumentParser(self.host) - self.parse_args(parser, argv, **defaults) - if parser.exit_status is not None: - return parser.exit_status - - try: - ret, _, _ = self.run() - return ret - except KeyboardInterrupt: - self.print_("interrupted, exiting", stream=self.host.stderr) - return 130 - - def parse_args(self, parser, argv, **defaults): - for attrname in defaults: - if not hasattr(self.args, attrname): - parser.error("Unknown default argument name '%s'" % attrname, - bailout=False) - return - parser.set_defaults(**defaults) - self.args = parser.parse_args(args=argv) - if parser.exit_status is not None: - return - - def print_(self, msg='', end='\n', stream=None): - self.host.print_(msg, end, stream=stream) - - def run(self, test_set=None): - - ret = 0 - h = self.host - - if self.args.version: - self.print_(VERSION) - return ret, None, None - - should_spawn = self._check_win_multiprocessing() - if should_spawn: - return self._spawn(test_set) - - ret = self._set_up_runner() - if ret: - return ret, None, None - - find_start = h.time() - if self.cov: # pragma: no cover - self.cov.erase() - self.cov.start() - - full_results = None - result_set = ResultSet() - - if not test_set: - ret, test_set = self.find_tests(self.args) - find_end = h.time() - - if not ret: - ret, full_results = self._run_tests(result_set, test_set) - - if self.cov: # pragma: no cover - self.cov.stop() - self.cov.save() - test_end = h.time() - - trace = self._trace_from_results(result_set) - if full_results: - self._summarize(full_results) - self._write(self.args.write_full_results_to, full_results) - upload_ret = self._upload(full_results) - if not ret: - ret = upload_ret - reporting_end = h.time() - self._add_trace_event(trace, 'run', find_start, reporting_end) - self._add_trace_event(trace, 'discovery', find_start, find_end) - self._add_trace_event(trace, 'testing', find_end, test_end) - self._add_trace_event(trace, 'reporting', test_end, reporting_end) - self._write(self.args.write_trace_to, trace) - self.report_coverage() - else: - upload_ret = 0 - - return ret, full_results, trace - - def _check_win_multiprocessing(self): - wmp = self.win_multiprocessing - - ignore, importable, spawn = WinMultiprocessing.values - - if wmp not in WinMultiprocessing.values: - raise ValueError('illegal value %s for win_multiprocessing' % - wmp) - - h = self.host - if wmp == ignore and h.platform == 'win32': # pragma: win32 - raise ValueError('Cannot use WinMultiprocessing.ignore for ' - 'win_multiprocessing when actually running ' - 'on Windows.') - - if wmp == ignore or self.args.jobs == 1: - return False - - if wmp == importable: - if self._main_is_importable(): - return False - raise ValueError('The __main__ module (%s) ' # pragma: no cover - 'may not be importable' % - sys.modules['__main__'].__file__) - - assert wmp == spawn - return True - - def _main_is_importable(self): # pragma: untested - path = sys.modules['__main__'].__file__ - if not path: - return False - if path.endswith('.pyc'): - path = path[:-1] - if not path.endswith('.py'): - return False - if path.endswith('__main__.py'): - # main modules are not directly importable. - return False - - path = self.host.realpath(path) - for d in sys.path: - if path.startswith(self.host.realpath(d)): - return True - return False # pragma: no cover - - def _spawn(self, test_set): - # TODO: Handle picklable hooks, rather than requiring them to be None. - assert self.classifier is None - assert self.context is None - assert self.setup_fn is None - assert self.teardown_fn is None - assert test_set is None - h = self.host - - if self.args.write_trace_to: # pragma: untested - should_delete_trace = False - else: - should_delete_trace = True - fp = h.mktempfile(delete=False) - fp.close() - self.args.write_trace_to = fp.name - - if self.args.write_full_results_to: # pragma: untested - should_delete_results = False - else: - should_delete_results = True - fp = h.mktempfile(delete=False) - fp.close() - self.args.write_full_results_to = fp.name - - argv = ArgumentParser(h).argv_from_args(self.args) - ret = h.call_inline([h.python_interpreter, path_to_file] + argv) - - trace = self._read_and_delete(self.args.write_trace_to, - should_delete_trace) - full_results = self._read_and_delete(self.args.write_full_results_to, - should_delete_results) - return ret, full_results, trace - - def _set_up_runner(self): - h = self.host - args = self.args - - self.stats = Stats(args.status_format, h.time, args.jobs) - self.printer = Printer( - self.print_, args.overwrite, args.terminal_width) - - if self.args.top_level_dirs and self.args.top_level_dir: - self.print_( - 'Cannot specify both --top-level-dir and --top-level-dirs', - stream=h.stderr) - return 1 - - self.top_level_dirs = args.top_level_dirs - if not self.top_level_dirs and args.top_level_dir: - self.top_level_dirs = [args.top_level_dir] - - if not self.top_level_dirs: - for test in [t for t in args.tests if h.exists(t)]: - if h.isdir(test): - top_dir = test - else: - top_dir = h.dirname(test) - while h.exists(top_dir, '__init__.py'): - top_dir = h.dirname(top_dir) - top_dir = h.realpath(top_dir) - if not top_dir in self.top_level_dirs: - self.top_level_dirs.append(top_dir) - if not self.top_level_dirs: - top_dir = h.getcwd() - while h.exists(top_dir, '__init__.py'): - top_dir = h.dirname(top_dir) - top_dir = h.realpath(top_dir) - self.top_level_dirs.append(top_dir) - - if not self.top_level_dir and self.top_level_dirs: - self.top_level_dir = self.top_level_dirs[0] - - for path in self.top_level_dirs: - h.add_to_path(path) - - for path in args.path: - h.add_to_path(path) - - if args.coverage: # pragma: no cover - try: - import coverage - except ImportError: - return 1 - - source = self.args.coverage_source - if not source: - source = self.top_level_dirs + self.args.path - self.coverage_source = source - self.cov = coverage.coverage(source=self.coverage_source, - data_suffix=True) - self.cov.erase() - return 0 - - def find_tests(self, args): - test_set = TestSet() - - orig_skip = unittest.skip - orig_skip_if = unittest.skipIf - if args.all: - unittest.skip = lambda reason: lambda x: x - unittest.skipIf = lambda condition, reason: lambda x: x - - try: - names = self._name_list_from_args(args) - classifier = self.classifier or _default_classifier(args) - - for name in names: - try: - self._add_tests_to_set(test_set, args.suffixes, - self.top_level_dirs, classifier, - name) - except (AttributeError, ImportError, SyntaxError) as e: - ex_str = traceback.format_exc() - self.print_('Failed to load "%s" in find_tests: %s' % - (name, e)) - self.print_(' %s' % - '\n '.join(ex_str.splitlines())) - self.print_(ex_str) - return 1, None - except _AddTestsError as e: - self.print_(str(e)) - return 1, None - - # TODO: Add support for discovering setupProcess/teardownProcess? - - shard_index = args.shard_index - total_shards = args.total_shards - assert total_shards >= 1 - assert shard_index >= 0 and shard_index < total_shards, ( - 'shard_index (%d) must be >= 0 and < total_shards (%d)' % - (shard_index, total_shards)) - test_set.parallel_tests = _sort_inputs( - test_set.parallel_tests)[shard_index::total_shards] - test_set.isolated_tests = _sort_inputs( - test_set.isolated_tests)[shard_index::total_shards] - test_set.tests_to_skip = _sort_inputs( - test_set.tests_to_skip)[shard_index::total_shards] - return 0, test_set - finally: - unittest.skip = orig_skip - unittest.skipIf = orig_skip_if - - def _name_list_from_args(self, args): - if args.tests: - names = args.tests - elif args.file_list: - if args.file_list == '-': - s = self.host.stdin.read() - else: - s = self.host.read_text_file(args.file_list) - names = [line.strip() for line in s.splitlines()] - else: - names = self.top_level_dirs - return names - - def _add_tests_to_set(self, test_set, suffixes, top_level_dirs, classifier, - name): - h = self.host - loader = self.loader - add_tests = _test_adder(test_set, classifier) - - found = set() - for d in top_level_dirs: - if h.isfile(name): - rpath = h.relpath(name, d) - if rpath.startswith('..'): - continue - if rpath.endswith('.py'): - rpath = rpath[:-3] - module = rpath.replace(h.sep, '.') - if module not in found: - found.add(module) - add_tests(loader.loadTestsFromName(module)) - elif h.isdir(name): - rpath = h.relpath(name, d) - if rpath.startswith('..'): - continue - for suffix in suffixes: - if not name in found: - found.add(name + '/' + suffix) - add_tests(loader.discover(name, suffix, d)) - else: - possible_dir = name.replace('.', h.sep) - if h.isdir(d, possible_dir): - for suffix in suffixes: - path = h.join(d, possible_dir) - if not path in found: - found.add(path + '/' + suffix) - suite = loader.discover(path, suffix, d) - add_tests(suite) - elif not name in found: - found.add(name) - add_tests(loader.loadTestsFromName(name)) - - # pylint: disable=no-member - if hasattr(loader, 'errors') and loader.errors: # pragma: python3 - # In Python3's version of unittest, loader failures get converted - # into failed test cases, rather than raising exceptions. However, - # the errors also get recorded so you can err out immediately. - raise ImportError(loader.errors) - - def _run_tests(self, result_set, test_set): - h = self.host - - all_tests = [ti.name for ti in - _sort_inputs(test_set.parallel_tests + - test_set.isolated_tests + - test_set.tests_to_skip)] - - if self.args.list_only: - self.print_('\n'.join(all_tests)) - return 0, None - - self._run_one_set(self.stats, result_set, test_set) - - failed_tests = sorted(json_results.failed_test_names(result_set)) - retry_limit = self.args.retry_limit - - while retry_limit and failed_tests: - if retry_limit == self.args.retry_limit: - self.flush() - self.args.overwrite = False - self.printer.should_overwrite = False - self.args.verbose = min(self.args.verbose, 1) - - self.print_('') - self.print_('Retrying failed tests (attempt #%d of %d)...' % - (self.args.retry_limit - retry_limit + 1, - self.args.retry_limit)) - self.print_('') - - stats = Stats(self.args.status_format, h.time, 1) - stats.total = len(failed_tests) - tests_to_retry = TestSet(isolated_tests=list(failed_tests)) - retry_set = ResultSet() - self._run_one_set(stats, retry_set, tests_to_retry) - result_set.results.extend(retry_set.results) - failed_tests = json_results.failed_test_names(retry_set) - retry_limit -= 1 - - if retry_limit != self.args.retry_limit: - self.print_('') - - full_results = json_results.make_full_results(self.args.metadata, - int(h.time()), - all_tests, result_set) - - return (json_results.exit_code_from_full_results(full_results), - full_results) - - def _run_one_set(self, stats, result_set, test_set): - stats.total = (len(test_set.parallel_tests) + - len(test_set.isolated_tests) + - len(test_set.tests_to_skip)) - self._skip_tests(stats, result_set, test_set.tests_to_skip) - self._run_list(stats, result_set, - test_set.parallel_tests, self.args.jobs) - self._run_list(stats, result_set, - test_set.isolated_tests, 1) - - def _skip_tests(self, stats, result_set, tests_to_skip): - for test_input in tests_to_skip: - last = self.host.time() - stats.started += 1 - self._print_test_started(stats, test_input) - now = self.host.time() - result = Result(test_input.name, actual=ResultType.Skip, - started=last, took=(now - last), worker=0, - expected=[ResultType.Skip], - out=test_input.msg) - result_set.add(result) - stats.finished += 1 - self._print_test_finished(stats, result) - - def _run_list(self, stats, result_set, test_inputs, jobs): - h = self.host - running_jobs = set() - - jobs = min(len(test_inputs), jobs) - if not jobs: - return - - child = _Child(self) - pool = make_pool(h, jobs, _run_one_test, child, - _setup_process, _teardown_process) - try: - while test_inputs or running_jobs: - while test_inputs and (len(running_jobs) < self.args.jobs): - test_input = test_inputs.pop(0) - stats.started += 1 - pool.send(test_input) - running_jobs.add(test_input.name) - self._print_test_started(stats, test_input) - - result = pool.get() - running_jobs.remove(result.name) - result_set.add(result) - stats.finished += 1 - self._print_test_finished(stats, result) - pool.close() - finally: - self.final_responses.extend(pool.join()) - - def _print_test_started(self, stats, test_input): - if self.args.quiet: - # Print nothing when --quiet was passed. - return - - # If -vvv was passed, print when the test is queued to be run. - # We don't actually know when the test picked up to run, because - # that is handled by the child process (where we can't easily - # print things). Otherwise, only print when the test is started - # if we know we can overwrite the line, so that we do not - # get multiple lines of output as noise (in -vvv, we actually want - # the noise). - test_start_msg = stats.format() + test_input.name - if self.args.verbose > 2: - self.update(test_start_msg + ' queued', elide=False) - if self.args.overwrite: - self.update(test_start_msg, elide=(not self.args.verbose)) - - def _print_test_finished(self, stats, result): - stats.add_time() - - assert result.actual in [ResultType.Failure, ResultType.Skip, - ResultType.Pass] - if result.actual == ResultType.Failure: - result_str = ' failed' - elif result.actual == ResultType.Skip: - result_str = ' was skipped' - elif result.actual == ResultType.Pass: - result_str = ' passed' - - if result.unexpected: - result_str += ' unexpectedly' - if self.args.timing: - timing_str = ' %.4fs' % result.took - else: - timing_str = '' - suffix = '%s%s' % (result_str, timing_str) - out = result.out - err = result.err - if result.code: - if out or err: - suffix += ':\n' - self.update(stats.format() + result.name + suffix, elide=False) - for l in out.splitlines(): - self.print_(' %s' % l) - for l in err.splitlines(): - self.print_(' %s' % l) - elif not self.args.quiet: - if self.args.verbose > 1 and (out or err): - suffix += ':\n' - self.update(stats.format() + result.name + suffix, - elide=(not self.args.verbose)) - if self.args.verbose > 1: - for l in out.splitlines(): - self.print_(' %s' % l) - for l in err.splitlines(): - self.print_(' %s' % l) - if self.args.verbose: - self.flush() - - def update(self, msg, elide): - self.printer.update(msg, elide) - - def flush(self): - self.printer.flush() - - def _summarize(self, full_results): - num_passes = json_results.num_passes(full_results) - num_failures = json_results.num_failures(full_results) - num_skips = json_results.num_skips(full_results) - - if self.args.quiet and num_failures == 0: - return - - if self.args.timing: - timing_clause = ' in %.1fs' % (self.host.time() - - self.stats.started_time) - else: - timing_clause = '' - self.update('%d test%s passed%s, %d skipped, %d failure%s.' % - (num_passes, - '' if num_passes == 1 else 's', - timing_clause, - num_skips, - num_failures, - '' if num_failures == 1 else 's'), elide=False) - self.print_() - - def _read_and_delete(self, path, delete): - h = self.host - obj = None - if h.exists(path): - contents = h.read_text_file(path) - if contents: - obj = json.loads(contents) - if delete: - h.remove(path) - return obj - - def _write(self, path, obj): - if path: - self.host.write_text_file(path, json.dumps(obj, indent=2) + '\n') - - def _upload(self, full_results): - h = self.host - if not self.args.test_results_server: - return 0 - - url, content_type, data = json_results.make_upload_request( - self.args.test_results_server, self.args.builder_name, - self.args.master_name, self.args.test_type, - full_results) - - try: - h.fetch(url, data, {'Content-Type': content_type}) - return 0 - except Exception as e: - h.print_('Uploading the JSON results raised "%s"' % str(e)) - return 1 - - def report_coverage(self): - if self.args.coverage: # pragma: no cover - self.host.print_() - import coverage - cov = coverage.coverage(data_suffix=True) - cov.combine() - cov.report(show_missing=self.args.coverage_show_missing, - omit=self.args.coverage_omit) - if self.args.coverage_annotate: - cov.annotate(omit=self.args.coverage_omit) - - def _add_trace_event(self, trace, name, start, end): - event = { - 'name': name, - 'ts': int((start - self.stats.started_time) * 1000000), - 'dur': int((end - start) * 1000000), - 'ph': 'X', - 'pid': self.host.getpid(), - 'tid': 0, - } - trace['traceEvents'].append(event) - - def _trace_from_results(self, result_set): - trace = OrderedDict() - trace['traceEvents'] = [] - trace['otherData'] = {} - for m in self.args.metadata: - k, v = m.split('=') - trace['otherData'][k] = v - - for result in result_set.results: - started = int((result.started - self.stats.started_time) * 1000000) - took = int(result.took * 1000000) - event = OrderedDict() - event['name'] = result.name - event['dur'] = took - event['ts'] = started - event['ph'] = 'X' # "Complete" events - event['pid'] = result.pid - event['tid'] = result.worker - - args = OrderedDict() - args['expected'] = sorted(str(r) for r in result.expected) - args['actual'] = str(result.actual) - args['out'] = result.out - args['err'] = result.err - args['code'] = result.code - args['unexpected'] = result.unexpected - args['flaky'] = result.flaky - event['args'] = args - - trace['traceEvents'].append(event) - return trace - - -def _matches(name, globs): - return any(fnmatch.fnmatch(name, glob) for glob in globs) - - -def _default_classifier(args): - def default_classifier(test_set, test): - name = test.id() - if not args.all and _matches(name, args.skip): - test_set.tests_to_skip.append(TestInput(name, - 'skipped by request')) - elif _matches(name, args.isolate): - test_set.isolated_tests.append(TestInput(name)) - else: - test_set.parallel_tests.append(TestInput(name)) - return default_classifier - - -def _test_adder(test_set, classifier): - def add_tests(obj): - if isinstance(obj, unittest.suite.TestSuite): - for el in obj: - add_tests(el) - elif (obj.id().startswith('unittest.loader.LoadTestsFailure') or - obj.id().startswith('unittest.loader.ModuleImportFailure')): - # Access to protected member pylint: disable=W0212 - module_name = obj._testMethodName - try: - method = getattr(obj, obj._testMethodName) - method() - except Exception as e: - if 'LoadTests' in obj.id(): - raise _AddTestsError('%s.load_tests() failed: %s' - % (module_name, str(e))) - else: - raise _AddTestsError(str(e)) - else: - assert isinstance(obj, unittest.TestCase) - classifier(test_set, obj) - return add_tests - - -class _Child(object): - - def __init__(self, parent): - self.host = None - self.worker_num = None - self.all = parent.args.all - self.debugger = parent.args.debugger - self.coverage = parent.args.coverage and parent.args.jobs > 1 - self.coverage_source = parent.coverage_source - self.dry_run = parent.args.dry_run - self.loader = parent.loader - self.passthrough = parent.args.passthrough - self.context = parent.context - self.setup_fn = parent.setup_fn - self.teardown_fn = parent.teardown_fn - self.context_after_setup = None - self.top_level_dir = parent.top_level_dir - self.top_level_dirs = parent.top_level_dirs - self.loaded_suites = {} - self.cov = None - - -def _setup_process(host, worker_num, child): - child.host = host - child.worker_num = worker_num - # pylint: disable=protected-access - - if child.coverage: # pragma: no cover - import coverage - child.cov = coverage.coverage(source=child.coverage_source, - data_suffix=True) - child.cov._warn_no_data = False - child.cov.start() - - if child.setup_fn: - child.context_after_setup = child.setup_fn(child, child.context) - else: - child.context_after_setup = child.context - return child - - -def _teardown_process(child): - res = None - e = None - if child.teardown_fn: - try: - res = child.teardown_fn(child, child.context_after_setup) - except Exception as e: - pass - - if child.cov: # pragma: no cover - child.cov.stop() - child.cov.save() - - return (child.worker_num, res, e) - - -def _run_one_test(child, test_input): - h = child.host - pid = h.getpid() - test_name = test_input.name - - start = h.time() - - # It is important to capture the output before loading the test - # to ensure that - # 1) the loader doesn't logs something we don't captured - # 2) neither the loader nor the test case grab a reference to the - # uncaptured stdout or stderr that later is used when the test is run. - # This comes up when using the FakeTestLoader and testing typ itself, - # but could come up when testing non-typ code as well. - h.capture_output(divert=not child.passthrough) - - ex_str = '' - try: - orig_skip = unittest.skip - orig_skip_if = unittest.skipIf - if child.all: - unittest.skip = lambda reason: lambda x: x - unittest.skipIf = lambda condition, reason: lambda x: x - - try: - suite = child.loader.loadTestsFromName(test_name) - except Exception as e: - ex_str = ('loadTestsFromName("%s") failed: %s\n%s\n' % - (test_name, e, traceback.format_exc())) - try: - suite = _load_via_load_tests(child, test_name) - ex_str += ('\nload_via_load_tests(\"%s\") returned %d tests\n' % - (test_name, len(list(suite)))) - except Exception as e: # pragma: untested - suite = [] - ex_str += ('\nload_via_load_tests("%s") failed: %s\n%s\n' % - (test_name, e, traceback.format_exc())) - finally: - unittest.skip = orig_skip - unittest.skipIf = orig_skip_if - - tests = list(suite) - if len(tests) != 1: - err = 'Failed to load "%s" in run_one_test' % test_name - if ex_str: # pragma: untested - err += '\n ' + '\n '.join(ex_str.splitlines()) - - h.restore_output() - return Result(test_name, ResultType.Failure, start, 0, - child.worker_num, unexpected=True, code=1, - err=err, pid=pid) - - test_case = tests[0] - if isinstance(test_case, TypTestCase): - test_case.child = child - test_case.context = child.context_after_setup - - test_result = unittest.TestResult() - out = '' - err = '' - try: - if child.dry_run: - pass - elif child.debugger: # pragma: no cover - _run_under_debugger(h, test_case, suite, test_result) - else: - suite.run(test_result) - finally: - out, err = h.restore_output() - - took = h.time() - start - return _result_from_test_result(test_result, test_name, start, took, out, - err, child.worker_num, pid) - - -def _run_under_debugger(host, test_case, suite, - test_result): # pragma: no cover - # Access to protected member pylint: disable=W0212 - test_func = getattr(test_case, test_case._testMethodName) - fname = inspect.getsourcefile(test_func) - lineno = inspect.getsourcelines(test_func)[1] + 1 - dbg = pdb.Pdb(stdout=host.stdout.stream) - dbg.set_break(fname, lineno) - dbg.runcall(suite.run, test_result) - - -def _result_from_test_result(test_result, test_name, start, took, out, err, - worker_num, pid): - flaky = False - if test_result.failures: - expected = [ResultType.Pass] - actual = ResultType.Failure - code = 1 - unexpected = True - err = err + test_result.failures[0][1] - elif test_result.errors: - expected = [ResultType.Pass] - actual = ResultType.Failure - code = 1 - unexpected = True - err = err + test_result.errors[0][1] - elif test_result.skipped: - expected = [ResultType.Skip] - actual = ResultType.Skip - err = err + test_result.skipped[0][1] - code = 0 - unexpected = False - elif test_result.expectedFailures: - expected = [ResultType.Failure] - actual = ResultType.Failure - code = 1 - err = err + test_result.expectedFailures[0][1] - unexpected = False - elif test_result.unexpectedSuccesses: - expected = [ResultType.Failure] - actual = ResultType.Pass - code = 0 - unexpected = True - else: - expected = [ResultType.Pass] - actual = ResultType.Pass - code = 0 - unexpected = False - - return Result(test_name, actual, start, took, worker_num, - expected, unexpected, flaky, code, out, err, pid) - - -def _load_via_load_tests(child, test_name): - # If we couldn't import a test directly, the test may be only loadable - # via unittest's load_tests protocol. See if we can find a load_tests - # entry point that will work for this test. - loader = child.loader - comps = test_name.split('.') - new_suite = unittest.TestSuite() - - while comps: - name = '.'.join(comps) - module = None - suite = None - if name not in child.loaded_suites: - try: - module = importlib.import_module(name) - except ImportError: - pass - if module: - suite = loader.loadTestsFromModule(module) - child.loaded_suites[name] = suite - suite = child.loaded_suites[name] - if suite: - for test_case in suite: - assert isinstance(test_case, unittest.TestCase) - if test_case.id() == test_name: # pragma: untested - new_suite.addTest(test_case) - break - comps.pop() - return new_suite - - -def _sort_inputs(inps): - return sorted(inps, key=lambda inp: inp.name) - - -if __name__ == '__main__': # pragma: no cover - sys.modules['__main__'].__file__ = path_to_file - sys.exit(main(win_multiprocessing=WinMultiprocessing.importable))
diff --git a/third_party/typ/typ/stats.py b/third_party/typ/typ/stats.py deleted file mode 100644 index 0cd408dc..0000000 --- a/third_party/typ/typ/stats.py +++ /dev/null
@@ -1,83 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -class Stats(object): - - def __init__(self, status_format, time_fn, size): - self.fmt = status_format - self.finished = 0 - self.started = 0 - self.total = 0 - self.started_time = time_fn() - self._times = [] - self._size = size - self._time = time_fn - self._times.append(self.started_time) - - def add_time(self): - if len(self._times) > self._size: - self._times.pop(0) - self._times.append(self._time()) - - def format(self): - # Too many statements pylint: disable=R0915 - out = '' - p = 0 - end = len(self.fmt) - while p < end: - c = self.fmt[p] - if c == '%' and p < end - 1: - cn = self.fmt[p + 1] - if cn == 'c': - elapsed = self._times[-1] - self._times[0] - if elapsed > 0: - out += '%5.1f' % ((len(self._times) - 1) / elapsed) - else: - out += '-' - elif cn == 'e': - now = self._time() - assert now >= self.started_time - out += '%-5.3f' % (now - self.started_time) - elif cn == 'f': - out += str(self.finished) - elif cn == 'o': - now = self._time() - if now > self.started_time: - out += '%5.1f' % (self.finished * 1.0 / - (now - self.started_time)) - else: - out += '-' - elif cn == 'p': - if self.total: - out += '%5.1f' % (self.started * 100.0 / self.total) - else: - out += '-' - elif cn == 'r': - out += str(self.started - self.finished) - elif cn == 's': - out += str(self.started) - elif cn == 't': - out += str(self.total) - elif cn == 'u': - out += str(self.total - self.finished) - elif cn == '%': - out += '%' - else: - out += c + cn - p += 2 - else: - out += c - p += 1 - return out
diff --git a/third_party/typ/typ/test_case.py b/third_party/typ/typ/test_case.py deleted file mode 100644 index d709a57..0000000 --- a/third_party/typ/typ/test_case.py +++ /dev/null
@@ -1,127 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import fnmatch -import shlex -import unittest - - -def convert_newlines(msg): - """A routine that mimics Python's universal_newlines conversion.""" - return msg.replace('\r\n', '\n').replace('\r', '\n') - - -class TestCase(unittest.TestCase): - child = None - context = None - maxDiff = 80 * 66 - - -class MainTestCase(TestCase): - prog = None - files_to_ignore = [] - - def _write_files(self, host, files): - for path, contents in list(files.items()): - dirname = host.dirname(path) - if dirname: - host.maybe_mkdir(dirname) - host.write_text_file(path, contents) - - def _read_files(self, host, tmpdir): - out_files = {} - for f in host.files_under(tmpdir): - if any(fnmatch.fnmatch(f, pat) for pat in self.files_to_ignore): - continue - key = f.replace(host.sep, '/') - out_files[key] = host.read_text_file(tmpdir, f) - return out_files - - def assert_files(self, expected_files, actual_files, files_to_ignore=None): - files_to_ignore = files_to_ignore or [] - for k, v in expected_files.items(): - self.assertMultiLineEqual(expected_files[k], v) - interesting_files = set(actual_files.keys()).difference( - files_to_ignore) - self.assertEqual(interesting_files, set(expected_files.keys())) - - def make_host(self): - # If we are ever called by unittest directly, and not through typ, - # this will probably fail. - assert self.child - return self.child.host - - def call(self, host, argv, stdin, env): - return host.call(argv, stdin=stdin, env=env) - - def check(self, cmd=None, stdin=None, env=None, aenv=None, files=None, - prog=None, cwd=None, host=None, - ret=None, out=None, rout=None, err=None, rerr=None, - exp_files=None, - files_to_ignore=None, universal_newlines=True): - # Too many arguments pylint: disable=R0913 - prog = prog or self.prog or [] - host = host or self.make_host() - argv = shlex.split(cmd) if isinstance(cmd, str) else cmd or [] - - tmpdir = None - orig_wd = host.getcwd() - try: - tmpdir = host.mkdtemp() - host.chdir(tmpdir) - if files: - self._write_files(host, files) - if cwd: - host.chdir(cwd) - if aenv: - env = host.env.copy() - env.update(aenv) - - if self.child.debugger: # pragma: no cover - host.print_('') - host.print_('cd %s' % tmpdir, stream=host.stdout.stream) - host.print_(' '.join(prog + argv), stream=host.stdout.stream) - host.print_('') - import pdb - dbg = pdb.Pdb(stdout=host.stdout.stream) - dbg.set_trace() - - result = self.call(host, prog + argv, stdin=stdin, env=env) - - actual_ret, actual_out, actual_err = result - actual_files = self._read_files(host, tmpdir) - finally: - host.chdir(orig_wd) - if tmpdir: - host.rmtree(tmpdir) - - if universal_newlines: - actual_out = convert_newlines(actual_out) - if universal_newlines: - actual_err = convert_newlines(actual_err) - - if ret is not None: - self.assertEqual(ret, actual_ret) - if out is not None: - self.assertMultiLineEqual(out, actual_out) - if rout is not None: - self.assertRegexpMatches(actual_out, rout) - if err is not None: - self.assertMultiLineEqual(err, actual_err) - if rerr is not None: - self.assertRegexpMatches(actual_err, rerr) - if exp_files: - self.assert_files(exp_files, actual_files, files_to_ignore) - - return actual_ret, actual_out, actual_err, actual_files
diff --git a/third_party/typ/typ/tests/__init__.py b/third_party/typ/typ/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/third_party/typ/typ/tests/__init__.py +++ /dev/null
diff --git a/third_party/typ/typ/tests/arg_parser_test.py b/third_party/typ/typ/tests/arg_parser_test.py deleted file mode 100644 index 3d443f6..0000000 --- a/third_party/typ/typ/tests/arg_parser_test.py +++ /dev/null
@@ -1,83 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import optparse -import unittest - -from typ import ArgumentParser - - -class ArgumentParserTest(unittest.TestCase): - - def test_optparse_options(self): - parser = optparse.OptionParser() - ArgumentParser.add_option_group(parser, 'foo', - discovery=True, - running=True, - reporting=True, - skip='[-d]') - options, _ = parser.parse_args(['-j', '1']) - self.assertEqual(options.jobs, 1) - - def test_argv_from_args(self): - - def check(argv, expected=None): - parser = ArgumentParser() - args = parser.parse_args(argv) - actual_argv = parser.argv_from_args(args) - expected = expected or argv - self.assertEqual(expected, actual_argv) - - check(['--version']) - check(['--coverage', '--coverage-omit', 'foo']) - check(['--jobs', '3']) - check(['-vv'], ['--verbose', '--verbose']) - - def test_argv_from_args_foreign_argument(self): - parser = ArgumentParser() - parser.add_argument('--some-foreign-argument', default=False, - action='store_true') - args = parser.parse_args(['--some-foreign-argument', '--verbose']) - self.assertEqual(['--verbose'], ArgumentParser().argv_from_args(args)) - - def test_valid_shard_options(self): - parser = ArgumentParser() - - parser.parse_args(['--total-shards', '1']) - self.assertEqual(parser.exit_status, None) - - parser.parse_args(['--total-shards', '5', '--shard-index', '4']) - self.assertEqual(parser.exit_status, None) - - parser.parse_args(['--total-shards', '5', '--shard-index', '0']) - self.assertEqual(parser.exit_status, None) - - - def test_invalid_shard_options(self): - parser = ArgumentParser() - - parser.parse_args(['--total-shards', '0']) - self.assertEqual(parser.exit_status, 2) - - parser.parse_args(['--total-shards', '-1']) - self.assertEqual(parser.exit_status, 2) - - parser.parse_args(['--total-shards', '5', '--shard-index', '-1']) - self.assertEqual(parser.exit_status, 2) - - parser.parse_args(['--total-shards', '5', '--shard-index', '5']) - self.assertEqual(parser.exit_status, 2) - - parser.parse_args(['--total-shards', '5', '--shard-index', '6']) - self.assertEqual(parser.exit_status, 2)
diff --git a/third_party/typ/typ/tests/host_test.py b/third_party/typ/typ/tests/host_test.py deleted file mode 100644 index 5100a2a2..0000000 --- a/third_party/typ/typ/tests/host_test.py +++ /dev/null
@@ -1,216 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import pickle -import sys -import unittest - -from typ.host import Host - - -class TestHost(unittest.TestCase): - - def host(self): - return Host() - - def test_capture_output(self): - try: - logging.basicConfig() - h = self.host() - h.capture_output() - h.print_('on stdout') - h.print_('on stderr', stream=h.stderr) - logging.critical('critical log failure') - out, err = h.restore_output() - self.assertEqual(out, 'on stdout\n') - self.assertEqual(err, 'on stderr\ncritical log failure\n') - finally: - h.logger.handlers = [] - - # TODO: Add tests for divert=False or eliminate the flag? - - def test_abspath_and_realpath(self): - h = self.host() - self.assertNotEqual(h.abspath(h.getcwd()), None) - self.assertNotEqual(h.realpath(h.getcwd()), None) - - def test_chdir(self): - h = self.host() - orig_cwd = h.getcwd() - h.chdir('.') - self.assertEqual(orig_cwd, h.getcwd()) - h.chdir('..') - self.assertNotEqual(orig_cwd, h.getcwd()) - - def test_files(self): - h = self.host() - orig_cwd = h.getcwd() - try: - now = h.time() - - # TODO: MacOS does goofy things with temp dirs by default, so - # we can't compare for equality. Figure out how to get the normpath - # from mkdtemp - dirpath = h.mkdtemp(suffix='host_test') - self.assertTrue(h.isdir(dirpath)) - h.chdir(dirpath) - self.assertIn(dirpath, h.getcwd()) - - h.maybe_mkdir('bar') - self.assertTrue(h.exists(dirpath, 'bar')) - self.assertTrue(h.isdir(dirpath, 'bar')) - self.assertFalse(h.isfile(dirpath, 'bar')) - - bar_path = h.join(dirpath, 'bar') - self.assertEqual(dirpath, h.dirname(bar_path)) - - h.write_text_file('bar/foo.txt', 'foo') - self.assertTrue(h.exists('bar', 'foo.txt')) - self.assertEqual(h.read_text_file('bar/foo.txt'), 'foo') - self.assertTrue(h.exists(dirpath, 'bar', 'foo.txt')) - self.assertTrue(h.isfile(dirpath, 'bar', 'foo.txt')) - self.assertFalse(h.isdir(dirpath, 'bar', 'foo.txt')) - - h.write_binary_file('binfile', b'bin contents') - self.assertEqual(h.read_binary_file('binfile'), - b'bin contents') - - self.assertEqual(sorted(h.files_under(dirpath)), - ['bar' + h.sep + 'foo.txt', 'binfile']) - - mtime = h.mtime(dirpath, 'bar', 'foo.txt') - self.assertGreaterEqual(now, mtime - 0.1) - h.remove(dirpath, 'bar', 'foo.txt') - self.assertFalse(h.exists(dirpath, 'bar', 'foo.txt')) - self.assertFalse(h.isfile(dirpath, 'bar', 'foo.txt')) - - h.chdir(orig_cwd) - h.rmtree(dirpath) - self.assertFalse(h.exists(dirpath)) - self.assertFalse(h.isdir(dirpath)) - finally: - h.chdir(orig_cwd) - - def test_terminal_width(self): - h = self.host() - self.assertGreaterEqual(h.terminal_width(), 0) - - def test_for_mp_and_pickling(self): - h = self.host() - mp_host = h.for_mp() - s = pickle.dumps(mp_host) - pickle.loads(s) - - def test_cpu_count(self): - h = self.host() - self.assertGreaterEqual(h.cpu_count(), 1) - - def test_getenv(self): - h = self.host() - self.assertNotEqual(h.getenv('PATH', ''), None) - - def test_getpid(self): - h = self.host() - self.assertNotEqual(h.getpid(), 0) - - def test_basename(self): - h = self.host() - self.assertEqual(h.basename('foo.txt'), 'foo.txt') - self.assertEqual(h.basename('foo/bar.txt'), 'bar.txt') - - def test_mktempfile(self, delete=False): # pylint: disable=unused-argument - h = self.host() - f = h.mktempfile() - f.close() - self.assertNotEqual(f.name, None) - - def test_splitext(self): - h = self.host() - self.assertEqual(h.splitext('foo'), ('foo', '')) - self.assertEqual(h.splitext('foo.txt'), ('foo', '.txt')) - self.assertEqual(h.splitext('foo/bar'), ('foo/bar', '')) - self.assertEqual(h.splitext('foo/bar.txt'), ('foo/bar', '.txt')) - - def test_print(self): - h = self.host() - - class FakeStream(object): - - def __init__(self): - self.contents = None - self.flush_called = False - - def write(self, m): - self.contents = m - - def flush(self): - self.flush_called = True - - s = FakeStream() - h.print_('hello', stream=s) - self.assertEqual(s.contents, 'hello\n') - self.assertTrue(s.flush_called) - - s = FakeStream() - h.stdout = s - h.print_('hello') - self.assertEqual(s.contents, 'hello\n') - - s = FakeStream() - h.stdout = s - h.print_('hello', '') - self.assertEqual(s.contents, 'hello') - - def test_call(self): - h = self.host() - ret, out, err = h.call( - [h.python_interpreter, - '-c', 'import sys; sys.stdout.write(sys.stdin.read())'], - stdin='foo', env={}) - self.assertEqual(ret, 0) - self.assertEqual(out, 'foo') - self.assertEqual(err, '') - - ret, out, err = h.call( - [h.python_interpreter, - '-c', 'import sys; sys.stderr.write("err\\n")']) - self.assertEqual(ret, 0) - self.assertEqual(out, '') - self.assertIn(err, ('err\n', 'err\r\n')) - - def test_call_inline(self): - h = self.host() - h.stdout = None - h.stderr = None - ret = h.call_inline([h.python_interpreter, - '-c', 'import sys; sys.exit(0)']) - self.assertEqual(ret, 0) - - def test_add_to_path(self): - orig_sys_path = sys.path[:] - try: - h = self.host() - h.add_to_path(sys.path[-1]) - self.assertEqual(sys.path, orig_sys_path) - - dirpath = h.mkdtemp() - h.add_to_path(dirpath) - self.assertNotEqual(sys.path, orig_sys_path) - finally: - sys.path = orig_sys_path - - def test_platform(self): - h = self.host() - self.assertNotEqual(h.platform, None)
diff --git a/third_party/typ/typ/tests/json_results_test.py b/third_party/typ/typ/tests/json_results_test.py deleted file mode 100644 index 76446f9..0000000 --- a/third_party/typ/typ/tests/json_results_test.py +++ /dev/null
@@ -1,113 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -from typ import json_results - - -class TestMakeUploadRequest(unittest.TestCase): - maxDiff = 4096 - - def test_basic_upload(self): - results = json_results.ResultSet() - full_results = json_results.make_full_results([], 0, [], results) - url, content_type, data = json_results.make_upload_request( - 'localhost', 'fake_builder_name', 'fake_master', 'fake_test_type', - full_results) - - self.assertEqual( - content_type, - 'multipart/form-data; ' - 'boundary=-J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-') - - self.assertEqual(url, 'https://localhost/testfile/upload') - self.assertMultiLineEqual( - data, - ('---J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-\r\n' - 'Content-Disposition: form-data; name="builder"\r\n' - '\r\n' - 'fake_builder_name\r\n' - '---J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-\r\n' - 'Content-Disposition: form-data; name="master"\r\n' - '\r\n' - 'fake_master\r\n' - '---J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-\r\n' - 'Content-Disposition: form-data; name="testtype"\r\n' - '\r\n' - 'fake_test_type\r\n' - '---J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y-\r\n' - 'Content-Disposition: form-data; name="file"; ' - 'filename="full_results.json"\r\n' - 'Content-Type: application/json\r\n' - '\r\n' - '{"version": 3, "interrupted": false, "path_delimiter": ".", ' - '"seconds_since_epoch": 0, ' - '"num_failures_by_type": {"FAIL": 0, "PASS": 0, "SKIP": 0}, ' - '"tests": {}}\r\n' - '---J-S-O-N-R-E-S-U-L-T-S---B-O-U-N-D-A-R-Y---\r\n')) - - -class TestMakeFullResults(unittest.TestCase): - maxDiff = 2048 - - def test_basic(self): - test_names = ['foo_test.FooTest.test_fail', - 'foo_test.FooTest.test_pass', - 'foo_test.FooTest.test_skip'] - - result_set = json_results.ResultSet() - result_set.add( - json_results.Result('foo_test.FooTest.test_fail', - json_results.ResultType.Failure, 0, 0.1, 0, - unexpected=True)) - result_set.add(json_results.Result('foo_test.FooTest.test_pass', - json_results.ResultType.Pass, - 0, 0.2, 0)) - result_set.add(json_results.Result('foo_test.FooTest.test_skip', - json_results.ResultType.Skip, - 0, 0.3, 0, unexpected=False)) - - full_results = json_results.make_full_results( - ['foo=bar'], 0, test_names, result_set) - expected_full_results = { - 'foo': 'bar', - 'interrupted': False, - 'num_failures_by_type': { - 'FAIL': 1, - 'PASS': 1, - 'SKIP': 1}, - 'path_delimiter': '.', - 'seconds_since_epoch': 0, - 'tests': { - 'foo_test': { - 'FooTest': { - 'test_fail': { - 'expected': 'PASS', - 'actual': 'FAIL', - 'times': [0.1], - 'is_unexpected': True, - }, - 'test_pass': { - 'expected': 'PASS', - 'actual': 'PASS', - 'times': [0.2], - }, - 'test_skip': { - 'expected': 'SKIP', - 'actual': 'SKIP', - 'times': [0.3], - }}}}, - 'version': 3} - self.assertEqual(full_results, expected_full_results)
diff --git a/third_party/typ/typ/tests/main_test.py b/third_party/typ/typ/tests/main_test.py deleted file mode 100644 index 2d90b16..0000000 --- a/third_party/typ/typ/tests/main_test.py +++ /dev/null
@@ -1,829 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import io -import json -import os -import sys -import textwrap - -from typ import main -from typ import test_case -from typ import Host -from typ import VERSION -from typ.fakes import test_result_server_fake - - -is_python3 = bool(sys.version_info.major == 3) - -if is_python3: # pragma: python3 - # pylint: disable=redefined-builtin,invalid-name - unicode = str - -d = textwrap.dedent - - -PASS_TEST_PY = """ -import unittest -class PassingTest(unittest.TestCase): - def test_pass(self): - pass -""" - - -PASS_TEST_FILES = {'pass_test.py': PASS_TEST_PY} - - -FAIL_TEST_PY = """ -import unittest -class FailingTest(unittest.TestCase): - def test_fail(self): - self.fail() -""" - - -FAIL_TEST_FILES = {'fail_test.py': FAIL_TEST_PY} - - -OUTPUT_TEST_PY = """ -import sys -import unittest - -class PassTest(unittest.TestCase): - def test_out(self): - sys.stdout.write("hello on stdout\\n") - sys.stdout.flush() - - def test_err(self): - sys.stderr.write("hello on stderr\\n") - -class FailTest(unittest.TestCase): - def test_out_err_fail(self): - sys.stdout.write("hello on stdout\\n") - sys.stdout.flush() - sys.stderr.write("hello on stderr\\n") - self.fail() -""" - - -OUTPUT_TEST_FILES = {'output_test.py': OUTPUT_TEST_PY} - - -SF_TEST_PY = """ -import sys -import unittest - -class SkipMethods(unittest.TestCase): - @unittest.skip('reason') - def test_reason(self): - self.fail() - - @unittest.skipIf(True, 'reason') - def test_skip_if_true(self): - self.fail() - - @unittest.skipIf(False, 'reason') - def test_skip_if_false(self): - self.fail() - - -class SkipSetup(unittest.TestCase): - def setUp(self): - self.skipTest('setup failed') - - def test_notrun(self): - self.fail() - - -@unittest.skip('skip class') -class SkipClass(unittest.TestCase): - def test_method(self): - self.fail() - -class SetupClass(unittest.TestCase): - @classmethod - def setUpClass(cls): - sys.stdout.write('in setupClass\\n') - sys.stdout.flush() - assert False, 'setupClass failed' - - def test_method1(self): - pass - - def test_method2(self): - pass - -class ExpectedFailures(unittest.TestCase): - @unittest.expectedFailure - def test_fail(self): - self.fail() - - @unittest.expectedFailure - def test_pass(self): - pass -""" - - -SF_TEST_FILES = {'sf_test.py': SF_TEST_PY} - - -LOAD_TEST_PY = """ -import unittest - - -class BaseTest(unittest.TestCase): - pass - - -def method_fail(self): - self.fail() - - -def method_pass(self): - pass - - -def load_tests(_, _2, _3): - setattr(BaseTest, "test_fail", method_fail) - setattr(BaseTest, "test_pass", method_pass) - suite = unittest.TestSuite() - suite.addTest(BaseTest("test_fail")) - suite.addTest(BaseTest("test_pass")) - return suite -""" - -LOAD_TEST_FILES = {'load_test.py': LOAD_TEST_PY} - - - -path_to_main = os.path.join( - os.path.dirname(os.path.dirname(os.path.abspath(__file__))), - 'runner.py') - - -class TestCli(test_case.MainTestCase): - prog = [sys.executable, path_to_main] - files_to_ignore = ['*.pyc'] - - def test_bad_arg(self): - self.check(['--bad-arg'], ret=2, out='', - rerr='.*: error: unrecognized arguments: --bad-arg\n') - self.check(['-help'], ret=2, out='', - rerr=(".*: error: argument -h/--help: " - "ignored explicit argument 'elp'\n")) - - def test_bad_metadata(self): - self.check(['--metadata', 'foo'], ret=2, err='', - out='Error: malformed --metadata "foo"\n') - - def test_basic(self): - self.check([], files=PASS_TEST_FILES, - ret=0, - out=('[1/1] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 0 skipped, 0 failures.\n'), err='') - - def test_coverage(self): - try: - import coverage # pylint: disable=W0612 - files = { - 'pass_test.py': PASS_TEST_PY, - 'fail_test.py': FAIL_TEST_PY, - } - self.check(['-c', 'pass_test'], files=files, ret=0, err='', - out=d("""\ - [1/1] pass_test.PassingTest.test_pass passed - 1 test passed, 0 skipped, 0 failures. - - Name Stmts Miss Cover - ---------------------------------- - fail_test.py 4 4 0% - pass_test.py 4 0 100% - ---------------------------------- - TOTAL 8 4 50% - """)) - except ImportError: # pragma: no cover - # We can never cover this line, since running coverage means - # that import will succeed. - self.check(['-c'], files=PASS_TEST_FILES, ret=1, - out='Error: coverage is not installed\n', err='') - - def test_debugger(self): - if sys.version_info.major == 3: # pragma: python3 - return - else: # pragma: python2 - _, out, _, _ = self.check(['-d'], stdin='quit()\n', - files=PASS_TEST_FILES, ret=0, err='') - self.assertIn('(Pdb) ', out) - - def test_dryrun(self): - self.check(['-n'], files=PASS_TEST_FILES, ret=0, err='', - out=d("""\ - [1/1] pass_test.PassingTest.test_pass passed - 1 test passed, 0 skipped, 0 failures. - """)) - - def test_error(self): - files = {'err_test.py': d("""\ - import unittest - class ErrTest(unittest.TestCase): - def test_err(self): - foo = bar - """)} - _, out, _, _ = self.check([''], files=files, ret=1, err='') - self.assertIn('[1/1] err_test.ErrTest.test_err failed unexpectedly', - out) - self.assertIn('0 tests passed, 0 skipped, 1 failure', out) - - def test_fail(self): - _, out, _, _ = self.check([], files=FAIL_TEST_FILES, ret=1, err='') - self.assertIn('fail_test.FailingTest.test_fail failed unexpectedly', - out) - - def test_fail_then_pass(self): - files = {'fail_then_pass_test.py': d("""\ - import unittest - count = 0 - class FPTest(unittest.TestCase): - def test_count(self): - global count - count += 1 - if count == 1: - self.fail() - """)} - _, out, _, files = self.check(['--retry-limit', '3', - '--write-full-results-to', - 'full_results.json'], - files=files, ret=0, err='') - self.assertIn('Retrying failed tests (attempt #1 of 3)', out) - self.assertNotIn('Retrying failed tests (attempt #2 of 3)', out) - self.assertIn('1 test passed, 0 skipped, 0 failures.\n', out) - results = json.loads(files['full_results.json']) - self.assertEqual( - results['tests'][ - 'fail_then_pass_test']['FPTest']['test_count']['actual'], - 'FAIL PASS') - - def test_fail_then_skip(self): - files = {'fail_then_skip_test.py': d("""\ - import unittest - count = 0 - class FPTest(unittest.TestCase): - def test_count(self): - global count - count += 1 - if count == 1: - self.fail() - elif count == 2: - self.skipTest('') - """)} - _, out, _, files = self.check(['--retry-limit', '3', - '--write-full-results-to', - 'full_results.json'], - files=files, ret=0, err='') - self.assertIn('Retrying failed tests (attempt #1 of 3)', out) - self.assertNotIn('Retrying failed tests (attempt #2 of 3)', out) - self.assertIn('0 tests passed, 1 skipped, 0 failures.\n', out) - results = json.loads(files['full_results.json']) - self.assertEqual( - results['tests'][ - 'fail_then_skip_test']['FPTest']['test_count']['actual'], - 'FAIL SKIP') - - def test_failures_are_not_elided(self): - _, out, _, _ = self.check(['--terminal-width=20'], - files=FAIL_TEST_FILES, ret=1, err='') - self.assertIn('[1/1] fail_test.FailingTest.test_fail failed ' - 'unexpectedly:\n', out) - - def test_file_list(self): - files = PASS_TEST_FILES - self.check(['-f', '-'], files=files, stdin='pass_test\n', ret=0) - self.check(['-f', '-'], files=files, stdin='pass_test.PassingTest\n', - ret=0) - self.check(['-f', '-'], files=files, - stdin='pass_test.PassingTest.test_pass\n', - ret=0) - files = {'pass_test.py': PASS_TEST_PY, - 'test_list.txt': 'pass_test.PassingTest.test_pass\n'} - self.check(['-f', 'test_list.txt'], files=files, ret=0) - - def test_find(self): - files = PASS_TEST_FILES - self.check(['-l'], files=files, ret=0, - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', 'pass_test'], files=files, ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', 'pass_test.py'], files=files, ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', './pass_test.py'], files=files, ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', '.'], files=files, ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', 'pass_test.PassingTest.test_pass'], files=files, - ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - self.check(['-l', '.'], files=files, ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - - def test_find_from_subdirs(self): - files = { - 'foo/__init__.py': '', - 'foo/pass_test.py': PASS_TEST_PY, - 'bar/__init__.py': '', - 'bar/tmp': '', - - } - self.check(['-l', '../foo/pass_test.py'], files=files, cwd='bar', - ret=0, err='', - out='foo.pass_test.PassingTest.test_pass\n') - self.check(['-l', 'foo'], files=files, cwd='bar', - ret=0, err='', - out='foo.pass_test.PassingTest.test_pass\n') - self.check(['-l', '--path', '../foo', 'pass_test'], - files=files, cwd='bar', ret=0, err='', - out='pass_test.PassingTest.test_pass\n') - - def test_multiple_top_level_dirs(self): - files = { - 'foo/bar/__init__.py': '', - 'foo/bar/pass_test.py': PASS_TEST_PY, - 'baz/quux/__init__.py': '', - 'baz/quux/second_test.py': PASS_TEST_PY, - } - self.check(['-l', 'foo/bar', 'baz/quux'], files=files, - ret=0, err='', - out=( - 'bar.pass_test.PassingTest.test_pass\n' - 'quux.second_test.PassingTest.test_pass\n' - )) - self.check(['-l', 'foo/bar/pass_test.py', 'baz/quux'], files=files, - ret=0, err='', - out=( - 'bar.pass_test.PassingTest.test_pass\n' - 'quux.second_test.PassingTest.test_pass\n' - )) - self.check(['-l', '--top-level-dirs', 'foo', '--top-level-dirs', 'baz'], - files=files, - ret=0, err='', - out=( - 'bar.pass_test.PassingTest.test_pass\n' - 'quux.second_test.PassingTest.test_pass\n' - )) - - def test_single_top_level_dir(self): - files = { - 'foo/bar/__init__.py': '', - 'foo/bar/pass_test.py': PASS_TEST_PY, - 'baz/quux/__init__.py': '', - 'baz/quux/second_test.py': PASS_TEST_PY, - } - self.check(['-l', '--top-level-dir', 'foo'], - files=files, - ret=0, err='', - out=( - 'bar.pass_test.PassingTest.test_pass\n' - )) - - def test_can_not_have_both_top_level_flags(self): - files = { - 'foo/bar/__init__.py': '', - 'foo/bar/pass_test.py': PASS_TEST_PY, - 'baz/quux/__init__.py': '', - 'baz/quux/second_test.py': PASS_TEST_PY, - } - self.check( - ['-l', '--top-level-dir', 'foo', '--top-level-dirs', 'bar'], - files=files, - ret=1, out='', - err='Cannot specify both --top-level-dir and --top-level-dirs\n') - - def test_help(self): - self.check(['--help'], ret=0, rout='.*', err='') - - def test_import_failure_missing_file(self): - _, out, _, _ = self.check(['-l', 'foo'], ret=1, err='') - self.assertIn('Failed to load "foo" in find_tests', out) - self.assertIn('No module named foo', out) - - def test_import_failure_missing_package(self): - files = {'foo.py': d("""\ - import unittest - import package_that_does_not_exist - - class ImportFailureTest(unittest.TestCase): - def test_case(self): - pass - """)} - _, out, _, _ = self.check(['-l', 'foo.py'], files=files, ret=1, err='') - self.assertIn('Failed to load "foo.py" in find_tests', out) - self.assertIn('No module named package_that_does_not_exist', out) - - def test_import_failure_no_tests(self): - files = {'foo.py': 'import unittest'} - self.check(['-l', 'foo'], files=files, ret=0, err='', - out='\n') - - def test_import_failure_syntax_error(self): - files = {'syn_test.py': d("""\ - import unittest - - class SyntaxErrorTest(unittest.TestCase): - def test_syntax_error_in_test(self): - syntax error - """)} - _, out, _, _ = self.check([], files=files, ret=1, err='') - self.assertIn('Failed to import test module: syn_test', out) - self.assertIn('SyntaxError: invalid syntax', out) - - def test_interrupt(self): - files = {'interrupt_test.py': d("""\ - import unittest - class Foo(unittest.TestCase): - def test_interrupt(self): - raise KeyboardInterrupt() - """)} - self.check(['-j', '1'], files=files, ret=130, out='', - err='interrupted, exiting\n') - - def test_isolate(self): - self.check(['--isolate', '*test_pass*'], files=PASS_TEST_FILES, ret=0, - out=('[1/1] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 0 skipped, 0 failures.\n'), err='') - - def test_load_tests_failure(self): - files = {'foo_test.py': d("""\ - import unittest - - def load_tests(_, _2, _3): - raise ValueError('this should fail') - """)} - _, out, _, _ = self.check([], files=files, ret=1, err='') - self.assertIn('this should fail', out) - - def test_load_tests_single_worker(self): - files = LOAD_TEST_FILES - _, out, _, _ = self.check(['-j', '1', '-v'], files=files, ret=1, - err='') - self.assertIn('[1/2] load_test.BaseTest.test_fail failed', out) - self.assertIn('[2/2] load_test.BaseTest.test_pass passed', out) - self.assertIn('1 test passed, 0 skipped, 1 failure.\n', out) - - def test_load_tests_multiple_workers(self): - _, out, _, _ = self.check([], files=LOAD_TEST_FILES, ret=1, err='') - - # The output for this test is nondeterministic since we may run - # two tests in parallel. So, we just test that some of the substrings - # we care about are present. - self.assertIn('test_pass passed', out) - self.assertIn('test_fail failed', out) - self.assertIn('1 test passed, 0 skipped, 1 failure.\n', out) - - def test_missing_builder_name(self): - self.check(['--test-results-server', 'localhost'], ret=2, - out=('Error: --builder-name must be specified ' - 'along with --test-result-server\n' - 'Error: --master-name must be specified ' - 'along with --test-result-server\n' - 'Error: --test-type must be specified ' - 'along with --test-result-server\n'), err='') - - def test_ninja_status_env(self): - self.check(['-v', 'output_test.PassTest.test_out'], - files=OUTPUT_TEST_FILES, aenv={'NINJA_STATUS': 'ns: '}, - out=d("""\ - ns: output_test.PassTest.test_out passed - 1 test passed, 0 skipped, 0 failures. - """), err='') - - def test_output_for_failures(self): - _, out, _, _ = self.check(['output_test.FailTest'], - files=OUTPUT_TEST_FILES, - ret=1, err='') - self.assertIn('[1/1] output_test.FailTest.test_out_err_fail ' - 'failed unexpectedly:\n' - ' hello on stdout\n' - ' hello on stderr\n', out) - - def test_quiet(self): - self.check(['-q'], files=PASS_TEST_FILES, ret=0, err='', out='') - - def test_retry_limit(self): - _, out, _, _ = self.check(['--retry-limit', '2'], - files=FAIL_TEST_FILES, ret=1, err='') - self.assertIn('Retrying failed tests', out) - lines = out.splitlines() - self.assertEqual(len([l for l in lines - if 'test_fail failed unexpectedly:' in l]), - 3) - - def test_skip(self): - _, out, _, _ = self.check(['--skip', '*test_fail*'], - files=FAIL_TEST_FILES, ret=0) - self.assertIn('0 tests passed, 1 skipped, 0 failures.', out) - - files = {'fail_test.py': FAIL_TEST_PY, - 'pass_test.py': PASS_TEST_PY} - self.check(['-j', '1', '--skip', '*test_fail*'], files=files, ret=0, - out=('[1/2] fail_test.FailingTest.test_fail was skipped\n' - '[2/2] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 1 skipped, 0 failures.\n'), err='') - - # This tests that we print test_started updates for skipped tests - # properly. It also tests how overwriting works. - _, out, _, _ = self.check(['-j', '1', '--overwrite', '--skip', - '*test_fail*'], files=files, ret=0, - err='', universal_newlines=False) - - # We test this string separately and call out.strip() to - # avoid the trailing \r\n we get on windows, while keeping - # the \r's elsewhere in the string. - self.assertMultiLineEqual( - out.strip(), - ('[0/2] fail_test.FailingTest.test_fail\r' - ' \r' - '[1/2] fail_test.FailingTest.test_fail was skipped\r' - ' \r' - '[1/2] pass_test.PassingTest.test_pass\r' - ' \r' - '[2/2] pass_test.PassingTest.test_pass passed\r' - ' \r' - '1 test passed, 1 skipped, 0 failures.')) - - def test_skips_and_failures(self): - _, out, _, _ = self.check(['-j', '1', '-v', '-v'], files=SF_TEST_FILES, - ret=1, err='') - - # We do a bunch of assertIn()'s to work around the non-portable - # tracebacks. - self.assertIn(('[1/9] sf_test.ExpectedFailures.test_fail failed:\n' - ' Traceback '), out) - self.assertIn(('[2/9] sf_test.ExpectedFailures.test_pass ' - 'passed unexpectedly'), out) - self.assertIn(('[3/9] sf_test.SetupClass.test_method1 ' - 'failed unexpectedly:\n' - ' in setupClass\n'), out) - self.assertIn(('[4/9] sf_test.SetupClass.test_method2 ' - 'failed unexpectedly:\n' - ' in setupClass\n'), out) - self.assertIn(('[5/9] sf_test.SkipClass.test_method was skipped:\n' - ' skip class\n'), out) - self.assertIn(('[6/9] sf_test.SkipMethods.test_reason was skipped:\n' - ' reason\n'), out) - self.assertIn(('[7/9] sf_test.SkipMethods.test_skip_if_false ' - 'failed unexpectedly:\n' - ' Traceback'), out) - self.assertIn(('[8/9] sf_test.SkipMethods.test_skip_if_true ' - 'was skipped:\n' - ' reason\n' - '[9/9] sf_test.SkipSetup.test_notrun was skipped:\n' - ' setup failed\n' - '1 test passed, 4 skipped, 4 failures.\n'), out) - - def test_skip_and_all(self): - # --all should override --skip - _, out, _, _ = self.check(['--skip', '*test_pass'], - files=PASS_TEST_FILES, ret=0, err='') - self.assertIn('0 tests passed, 1 skipped, 0 failures.', out) - - _, out, _, _ = self.check(['--all', '--skip', '*test_pass'], - files=PASS_TEST_FILES, ret=0, err='') - self.assertIn('1 test passed, 0 skipped, 0 failures.', out) - - def test_skip_decorators_and_all(self): - _, out, _, _ = self.check(['--all', '-j', '1', '-v', '-v'], - files=SF_TEST_FILES, ret=1, err='') - self.assertIn('sf_test.SkipClass.test_method failed', out) - self.assertIn('sf_test.SkipMethods.test_reason failed', out) - self.assertIn('sf_test.SkipMethods.test_skip_if_true failed', out) - self.assertIn('sf_test.SkipMethods.test_skip_if_false failed', out) - - # --all does not override explicit calls to skipTest(), only - # the decorators. - self.assertIn('sf_test.SkipSetup.test_notrun was skipped', out) - - def test_sharding(self): - - def run(shard_index, total_shards, tests): - files = {'shard_test.py': textwrap.dedent( - """\ - import unittest - class ShardTest(unittest.TestCase): - def test_01(self): - pass - - def test_02(self): - pass - - def test_03(self): - pass - - def test_04(self): - pass - - def test_05(self): - pass - """)} - _, out, _, _ = self.check( - ['--shard-index', str(shard_index), - '--total-shards', str(total_shards), - '--jobs', '1'], - files=files) - - exp_out = '' - total_tests = len(tests) - for i, test in enumerate(tests): - exp_out += ('[%d/%d] shard_test.ShardTest.test_%s passed\n' % - (i + 1, total_tests, test)) - exp_out += '%d test%s passed, 0 skipped, 0 failures.\n' % ( - total_tests, "" if total_tests == 1 else "s") - self.assertEqual(out, exp_out) - - run(0, 1, ['01', '02', '03', '04', '05']) - run(0, 2, ['01', '03', '05']) - run(1, 2, ['02', '04']) - run(0, 6, ['01']) - - def test_subdir(self): - files = { - 'foo/__init__.py': '', - 'foo/bar/__init__.py': '', - 'foo/bar/pass_test.py': PASS_TEST_PY - } - self.check(['foo/bar'], files=files, ret=0, err='', - out=d("""\ - [1/1] foo.bar.pass_test.PassingTest.test_pass passed - 1 test passed, 0 skipped, 0 failures. - """)) - - def test_timing(self): - self.check(['-t'], files=PASS_TEST_FILES, ret=0, err='', - rout=(r'\[1/1\] pass_test.PassingTest.test_pass passed ' - r'\d+.\d+s\n' - r'1 test passed in \d+.\d+s, 0 skipped, 0 failures.')) - - def test_test_results_server(self): - server = test_result_server_fake.start() - self.assertNotEqual(server, None, 'could not start fake server') - - try: - self.check(['--test-results-server', - 'http://%s:%d' % server.server_address, - '--master-name', 'fake_master', - '--builder-name', 'fake_builder', - '--test-type', 'typ_tests', - '--metadata', 'foo=bar'], - files=PASS_TEST_FILES, ret=0, err='', - out=('[1/1] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 0 skipped, 0 failures.\n')) - - finally: - posts = server.stop() - - self.assertEqual(len(posts), 1) - payload = posts[0][2].decode('utf8') - self.assertIn('"test_pass": {"actual": "PASS"', - payload) - self.assertTrue(payload.endswith('--\r\n')) - self.assertNotEqual(server.log.getvalue(), '') - - def test_test_results_server_error(self): - server = test_result_server_fake.start(code=500) - self.assertNotEqual(server, None, 'could not start fake server') - - try: - self.check(['--test-results-server', - 'http://%s:%d' % server.server_address, - '--master-name', 'fake_master', - '--builder-name', 'fake_builder', - '--test-type', 'typ_tests', - '--metadata', 'foo=bar'], - files=PASS_TEST_FILES, ret=1, err='', - out=('[1/1] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 0 skipped, 0 failures.\n' - 'Uploading the JSON results raised ' - '"HTTP Error 500: Internal Server Error"\n')) - - finally: - _ = server.stop() - - def test_test_results_server_not_running(self): - self.check(['--test-results-server', 'http://localhost:99999', - '--master-name', 'fake_master', - '--builder-name', 'fake_builder', - '--test-type', 'typ_tests', - '--metadata', 'foo=bar'], - files=PASS_TEST_FILES, ret=1, err='', - rout=(r'\[1/1\] pass_test.PassingTest.test_pass passed\n' - '1 test passed, 0 skipped, 0 failures.\n' - 'Uploading the JSON results raised .*\n')) - - def test_verbose_2(self): - self.check(['-vv', '-j', '1', 'output_test.PassTest'], - files=OUTPUT_TEST_FILES, ret=0, - out=d("""\ - [1/2] output_test.PassTest.test_err passed: - hello on stderr - [2/2] output_test.PassTest.test_out passed: - hello on stdout - 2 tests passed, 0 skipped, 0 failures. - """), err='') - - def test_verbose_3(self): - self.check(['-vvv', '-j', '1', 'output_test.PassTest'], - files=OUTPUT_TEST_FILES, ret=0, - out=d("""\ - [0/2] output_test.PassTest.test_err queued - [1/2] output_test.PassTest.test_err passed: - hello on stderr - [1/2] output_test.PassTest.test_out queued - [2/2] output_test.PassTest.test_out passed: - hello on stdout - 2 tests passed, 0 skipped, 0 failures. - """), err='') - - def test_version(self): - self.check('--version', ret=0, out=(VERSION + '\n')) - - def test_write_full_results_to(self): - _, _, _, files = self.check(['--write-full-results-to', - 'results.json'], files=PASS_TEST_FILES) - self.assertIn('results.json', files) - results = json.loads(files['results.json']) - self.assertEqual(results['interrupted'], False) - self.assertEqual(results['path_delimiter'], '.') - - # The time it takes to run the test varies, so we test that - # we got a single entry greater than zero, but then delete it from - # the result so we can do an exact match on the rest of the trie. - result = results['tests']['pass_test']['PassingTest']['test_pass'] - self.assertEqual(len(result['times']), 1) - self.assertGreater(result['times'][0], 0) - result.pop('times') - self.assertEqual(results['tests'], - {u'pass_test': { - u'PassingTest': { - u'test_pass': { - u'actual': u'PASS', - u'expected': u'PASS', - } - } - }}) - - def test_write_trace_to(self): - _, _, _, files = self.check(['--write-trace-to', 'trace.json'], - files=PASS_TEST_FILES) - self.assertIn('trace.json', files) - trace_obj = json.loads(files['trace.json']) - self.assertEqual(trace_obj['otherData'], {}) - self.assertEqual(len(trace_obj['traceEvents']), 5) - event = trace_obj['traceEvents'][0] - self.assertEqual(event['name'], 'pass_test.PassingTest.test_pass') - self.assertEqual(event['ph'], 'X') - self.assertEqual(event['tid'], 1) - self.assertEqual(event['args']['expected'], ['Pass']) - self.assertEqual(event['args']['actual'], 'Pass') - - -class TestMain(TestCli): - prog = [] - - def make_host(self): - return Host() - - def call(self, host, argv, stdin, env): - stdin = unicode(stdin) - host.stdin = io.StringIO(stdin) - if env: - host.getenv = env.get - host.capture_output() - orig_sys_path = sys.path[:] - orig_sys_modules = list(sys.modules.keys()) - - try: - ret = main(argv + ['-j', '1'], host) - finally: - out, err = host.restore_output() - modules_to_unload = [] - for k in sys.modules: - if k not in orig_sys_modules: - modules_to_unload.append(k) - for k in modules_to_unload: - del sys.modules[k] - sys.path = orig_sys_path - - return ret, out, err - - def test_debugger(self): - # TODO: this test seems to hang under coverage. - pass
diff --git a/third_party/typ/typ/tests/pool_test.py b/third_party/typ/typ/tests/pool_test.py deleted file mode 100644 index 319c3961..0000000 --- a/third_party/typ/typ/tests/pool_test.py +++ /dev/null
@@ -1,172 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys -import unittest - -from typ import test_case -from typ.host import Host -from typ.pool import make_pool, _MessageType, _ProcessPool, _loop - - -def _pre(host, worker_num, context): # pylint: disable=W0613 - context['pre'] = True - return context - - -def _post(context): - context['post'] = True - return context - - -def _echo(context, msg): - return '%s/%s/%s' % (context['pre'], context['post'], msg) - - -def _error(context, msg): # pylint: disable=W0613 - raise Exception('_error() raised Exception') - - -def _interrupt(context, msg): # pylint: disable=W0613 - raise KeyboardInterrupt() - - -def _stub(*args): # pylint: disable=W0613 - return None - - -class TestPool(test_case.TestCase): - - def run_basic_test(self, jobs): - host = Host() - context = {'pre': False, 'post': False} - pool = make_pool(host, jobs, _echo, context, _pre, _post) - pool.send('hello') - pool.send('world') - msg1 = pool.get() - msg2 = pool.get() - pool.close() - final_contexts = pool.join() - self.assertEqual(set([msg1, msg2]), - set(['True/False/hello', - 'True/False/world'])) - expected_context = {'pre': True, 'post': True} - expected_final_contexts = [expected_context for _ in range(jobs)] - self.assertEqual(final_contexts, expected_final_contexts) - - def run_through_loop(self, callback=None, pool=None): - callback = callback or _stub - if pool: - host = pool.host - else: - host = Host() - pool = _ProcessPool(host, 0, _stub, None, _stub, _stub) - pool.send('hello') - - worker_num = 1 - _loop(pool.requests, pool.responses, host, worker_num, callback, - None, _stub, _stub, should_loop=False) - return pool - - def test_async_close(self): - host = Host() - pool = make_pool(host, 1, _echo, None, _stub, _stub) - pool.join() - - def test_basic_one_job(self): - self.run_basic_test(1) - - def test_basic_two_jobs(self): - self.run_basic_test(2) - - def test_join_discards_messages(self): - host = Host() - context = {'pre': False, 'post': False} - pool = make_pool(host, 2, _echo, context, _pre, _post) - pool.send('hello') - pool.close() - pool.join() - self.assertEqual(len(pool.discarded_responses), 1) - - @unittest.skipIf(sys.version_info.major == 3, 'fails under python3') - def test_join_gets_an_error(self): - host = Host() - pool = make_pool(host, 2, _error, None, _stub, _stub) - pool.send('hello') - pool.close() - try: - pool.join() - except Exception as e: - self.assertIn('_error() raised Exception', str(e)) - - def test_join_gets_an_interrupt(self): - host = Host() - pool = make_pool(host, 2, _interrupt, None, _stub, _stub) - pool.send('hello') - pool.close() - self.assertRaises(KeyboardInterrupt, pool.join) - - def test_loop(self): - pool = self.run_through_loop() - resp = pool.get() - self.assertEqual(resp, None) - pool.requests.put((_MessageType.Close, None)) - pool.close() - self.run_through_loop(pool=pool) - pool.join() - - def test_loop_fails_to_respond(self): - # This tests what happens if _loop() tries to send a response - # on a closed queue; we can't simulate this directly through the - # api in a single thread. - pool = self.run_through_loop() - pool.requests.put((_MessageType.Request, None)) - pool.requests.put((_MessageType.Close, None)) - self.run_through_loop(pool=pool) - pool.join() - - @unittest.skipIf(sys.version_info.major == 3, 'fails under python3') - def test_loop_get_raises_error(self): - pool = self.run_through_loop(_error) - self.assertRaises(Exception, pool.get) - pool.requests.put((_MessageType.Close, None)) - pool.close() - pool.join() - - def test_loop_get_raises_interrupt(self): - pool = self.run_through_loop(_interrupt) - self.assertRaises(KeyboardInterrupt, pool.get) - pool.requests.put((_MessageType.Close, None)) - pool.close() - pool.join() - - def test_pickling_errors(self): - def unpicklable_fn(): # pragma: no cover - pass - - host = Host() - jobs = 2 - self.assertRaises(Exception, make_pool, - host, jobs, _stub, unpicklable_fn, None, None) - self.assertRaises(Exception, make_pool, - host, jobs, _stub, None, unpicklable_fn, None) - self.assertRaises(Exception, make_pool, - host, jobs, _stub, None, None, unpicklable_fn) - - def test_no_close(self): - host = Host() - context = {'pre': False, 'post': False} - pool = make_pool(host, 2, _echo, context, _pre, _post) - final_contexts = pool.join() - self.assertEqual(final_contexts, [])
diff --git a/third_party/typ/typ/tests/printer_test.py b/third_party/typ/typ/tests/printer_test.py deleted file mode 100644 index b2310bc0..0000000 --- a/third_party/typ/typ/tests/printer_test.py +++ /dev/null
@@ -1,61 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -from typ.printer import Printer - - -class TestPrinter(unittest.TestCase): - - def setUp(self): - # 'Invalid name' pylint: disable=C0103 - self.out = [] - - def print_(self, msg, end='\n'): - self.out.append(msg + end) - - def test_basic(self): - pr = Printer(self.print_, False, 80) - pr.update('foo') - pr.flush() - self.assertEqual(self.out, ['foo', '\n']) - - def test_elide(self): - pr = Printer(self.print_, False, 8) - pr.update('hello world') - pr.flush() - self.assertEqual(self.out, ['h...d', '\n']) - - def test_overwrite(self): - pr = Printer(self.print_, True, 80) - pr.update('hello world') - pr.update('goodbye world') - pr.flush() - self.assertEqual(self.out, - ['hello world', - '\r \r', - 'goodbye world', - '\n']) - - def test_last_line_flushed_when_not_overwriting(self): - pr = Printer(self.print_, False, 80) - pr.update('foo\nbar') - pr.update('baz') - pr.flush() - self.assertEqual(self.out, - ['foo\nbar', - '\n', - 'baz', - '\n'])
diff --git a/third_party/typ/typ/tests/runner_test.py b/third_party/typ/typ/tests/runner_test.py deleted file mode 100644 index a5013b2..0000000 --- a/third_party/typ/typ/tests/runner_test.py +++ /dev/null
@@ -1,224 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys -import tempfile -import unittest - -from textwrap import dedent as d - - -from typ import Host, Runner, TestCase, TestSet, TestInput -from typ import WinMultiprocessing - - -def _setup_process(child, context): # pylint: disable=W0613 - return context - - -def _teardown_process(child, context): # pylint: disable=W0613 - return context - -def _teardown_throws(child, context): # pylint: disable=W0613 - raise Exception("exception in teardown") - - -class RunnerTests(TestCase): - def test_context(self): - r = Runner() - r.args.tests = ['typ.tests.runner_test.ContextTests'] - r.context = {'foo': 'bar'} - r.setup_fn = _setup_process - r.teardown_fn = _teardown_process - r.win_multiprocessing = WinMultiprocessing.importable - ret, _, _ = r.run() - self.assertEqual(ret, 0) - - @unittest.skipIf(sys.version_info.major == 3, 'fails under python3') - def test_exception_in_teardown(self): - r = Runner() - r.args.tests = ['typ.tests.runner_test.ContextTests'] - r.context = {'foo': 'bar'} - r.setup_fn = _setup_process - r.teardown_fn = _teardown_throws - r.win_multiprocessing = WinMultiprocessing.importable - ret, _, _ = r.run() - self.assertEqual(ret, 0) - self.assertEqual(r.final_responses[0][2].message, - 'exception in teardown') - - def test_bad_default(self): - r = Runner() - ret = r.main([], foo='bar') - self.assertEqual(ret, 2) - - def test_good_default(self): - r = Runner() - ret = r.main([], tests=['typ.tests.runner_test.ContextTests']) - self.assertEqual(ret, 0) - - -class TestSetTests(TestCase): - # This class exists to test the failures that can come up if you - # create your own test sets and bypass find_tests(); failures that - # would normally be caught there can occur later during test execution. - - def test_missing_name(self): - test_set = TestSet() - test_set.parallel_tests = [TestInput('nonexistent test')] - r = Runner() - r.args.jobs = 1 - ret, _, _ = r.run(test_set) - self.assertEqual(ret, 1) - - def test_failing_load_test(self): - h = Host() - orig_wd = h.getcwd() - tmpdir = None - try: - tmpdir = h.mkdtemp() - h.chdir(tmpdir) - h.write_text_file('load_test.py', d("""\ - import unittest - def load_tests(_, _2, _3): - assert False - """)) - test_set = TestSet() - test_set.parallel_tests = [TestInput('load_test.BaseTest.test_x')] - r = Runner() - r.args.jobs = 1 - ret, _, trace = r.run(test_set) - self.assertEqual(ret, 1) - self.assertIn('Failed to load "load_test.BaseTest.test_x" in ' - 'run_one_test', - trace['traceEvents'][0]['args']['err']) - finally: - h.chdir(orig_wd) - if tmpdir: - h.rmtree(tmpdir) - - -class TestWinMultiprocessing(TestCase): - def make_host(self): - return Host() - - def call(self, argv, platform=None, win_multiprocessing=None, **kwargs): - h = self.make_host() - orig_wd = h.getcwd() - tmpdir = None - try: - tmpdir = h.mkdtemp() - h.chdir(tmpdir) - h.capture_output() - if platform is not None: - h.platform = platform - r = Runner(h) - if win_multiprocessing is not None: - r.win_multiprocessing = win_multiprocessing - ret = r.main(argv, **kwargs) - finally: - out, err = h.restore_output() - h.chdir(orig_wd) - if tmpdir: - h.rmtree(tmpdir) - - return ret, out, err - - def test_bad_value(self): - self.assertRaises(ValueError, self.call, [], win_multiprocessing='foo') - - def test_ignore(self): - h = self.make_host() - if h.platform == 'win32': # pragma: win32 - self.assertRaises(ValueError, self.call, [], - win_multiprocessing=WinMultiprocessing.ignore) - else: - result = self.call([], - win_multiprocessing=WinMultiprocessing.ignore) - ret, out, err = result - self.assertEqual(ret, 0) - self.assertEqual(out, '0 tests passed, 0 skipped, 0 failures.\n') - self.assertEqual(err, '') - - def test_real_unimportable_main(self): - h = self.make_host() - tmpdir = None - orig_wd = h.getcwd() - out = err = None - out_str = err_str = '' - try: - tmpdir = h.mkdtemp() - h.chdir(tmpdir) - out = tempfile.NamedTemporaryFile(delete=False) - err = tempfile.NamedTemporaryFile(delete=False) - path_above_typ = h.realpath(h.dirname(__file__), '..', '..') - env = h.env.copy() - if 'PYTHONPATH' in env: # pragma: untested - env['PYTHONPATH'] = '%s%s%s' % (env['PYTHONPATH'], - h.pathsep, - path_above_typ) - else: # pragma: untested. - env['PYTHONPATH'] = path_above_typ - - h.write_text_file('test', d(""" - import sys - import typ - importable = typ.WinMultiprocessing.importable - sys.exit(typ.main(win_multiprocessing=importable)) - """)) - h.stdout = out - h.stderr = err - ret = h.call_inline([h.python_interpreter, h.join(tmpdir, 'test')], - env=env) - finally: - h.chdir(orig_wd) - if tmpdir: - h.rmtree(tmpdir) - if out: - out.close() - out = open(out.name) - out_str = out.read() - out.close() - h.remove(out.name) - if err: - err.close() - err = open(err.name) - err_str = err.read() - err.close() - h.remove(err.name) - - self.assertEqual(ret, 1) - self.assertEqual(out_str, '') - self.assertIn('ValueError: The __main__ module ', - err_str) - - def test_single_job(self): - ret, out, err = self.call(['-j', '1'], platform='win32') - self.assertEqual(ret, 0) - self.assertEqual('0 tests passed, 0 skipped, 0 failures.\n', out ) - self.assertEqual(err, '') - - def test_spawn(self): - ret, out, err = self.call([]) - self.assertEqual(ret, 0) - self.assertEqual('0 tests passed, 0 skipped, 0 failures.\n', out) - self.assertEqual(err, '') - - -class ContextTests(TestCase): - def test_context(self): - # This test is mostly intended to be called by - # RunnerTests.test_context, above. It is not interesting on its own. - if self.context: - self.assertEquals(self.context['foo'], 'bar')
diff --git a/third_party/typ/typ/tests/stats_test.py b/third_party/typ/typ/tests/stats_test.py deleted file mode 100644 index 3154768f..0000000 --- a/third_party/typ/typ/tests/stats_test.py +++ /dev/null
@@ -1,74 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -from typ.stats import Stats - - -class TestStats(unittest.TestCase): - - def test_basic(self): - s = Stats('foo', lambda: 0, 32) - self.assertEqual(s.format(), 'foo') - - def test_edges(self): - s = Stats('[%s/%f/%t/%r/%p]', lambda: 0, 32) - self.assertEqual(s.format(), '[0/0/0/0/-]') - s.started = 3 - s.total = 5 - s.finished = 1 - self.assertEqual(s.format(), '[3/1/5/2/ 60.0]') - - s.started = 5 - s.finished = 5 - self.assertEqual(s.format(), '[5/5/5/0/100.0]') - - def test_elapsed_time(self): - times = [0.0, 0.4] - s = Stats('[%e]', lambda: times.pop(0), 32) - self.assertEqual(s.format(), '[0.400]') - - s = Stats('[%e]', lambda: 0, 32) - self.assertEqual(s.format(), '[0.000]') - - def test_current_rate(self): - times = [0.0, 0.1, 0.2] - s = Stats('[%c]', lambda: times.pop(0), 1) - self.assertEquals(s.format(), '[-]') - s.add_time() - s.add_time() - self.assertEquals(s.format(), '[ 10.0]') - - def test_overall_rate(self): - times = [0, 0, 5] - s = Stats('[%o]', lambda: times.pop(0), 32) - self.assertEqual(s.format(), '[-]') - s.started = 3 - s.finished = 1 - s.total = 5 - self.assertEqual(s.format(), '[ 0.2]') - - def test_escaped_percent(self): - s = Stats('%%', lambda: 0, 32) - self.assertEqual(s.format(), '%') - - def test_unrecognized_escape(self): - s = Stats('%x', lambda: 0, 32) - self.assertEqual(s.format(), '%x') - - def test_remaining(self): - s = Stats('%u', lambda: 0, 32) - s.total = 2 - self.assertEqual(s.format(), '2')
diff --git a/third_party/typ/typ/tests/test_case_test.py b/third_party/typ/typ/tests/test_case_test.py deleted file mode 100644 index 4d22bd9..0000000 --- a/third_party/typ/typ/tests/test_case_test.py +++ /dev/null
@@ -1,54 +0,0 @@ -# Copyright 2014 Dirk Pranke. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typ import test_case - - -class TestFuncs(test_case.MainTestCase): - - def test_convert_newlines(self): - cn = test_case.convert_newlines - self.assertEqual(cn('foo'), 'foo') - self.assertEqual(cn('foo\nbar\nbaz'), 'foo\nbar\nbaz') - self.assertEqual(cn('foo\rbar\nbaz\r'), 'foo\nbar\nbaz\n') - self.assertEqual(cn('foo\r\nbar\r\nbaz\r\nmeh\n'), - 'foo\nbar\nbaz\nmeh\n') - - -class TestMainTestCase(test_case.MainTestCase): - - def test_basic(self): - h = self.make_host() - files = { - 'test.py': """ -import os -import sys -sys.stdout.write("in: %s\\n" % sys.stdin.read()) -sys.stdout.write("out: %s\\n" % os.environ['TEST_VAR']) -sys.stderr.write("err\\n") -with open("../results", "w") as fp: - fp.write(open("../input", "r").read() + " written") -""", - 'input': 'results', - 'subdir/x': 'y', - } - exp_files = files.copy() - exp_files['results'] = 'results written' - self.check(prog=[h.python_interpreter, '../test.py'], - stdin='hello on stdin', - env={'TEST_VAR': 'foo'}, - cwd='subdir', - files=files, - ret=0, out='in: hello on stdin\nout: foo\n', - err='err\n', exp_files=exp_files)
diff --git a/third_party/typ/typ/version.py b/third_party/typ/typ/version.py deleted file mode 100644 index 437f236..0000000 --- a/third_party/typ/typ/version.py +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -VERSION = '0.10.0'
diff --git a/tools/metrics/BUILD.gn b/tools/metrics/BUILD.gn index 5900f4b1..84417f33 100644 --- a/tools/metrics/BUILD.gn +++ b/tools/metrics/BUILD.gn
@@ -71,7 +71,7 @@ "//testing/scripts/common.py", "//testing/xvfb.py", "//testing/test_env.py", - "//third_party/typ/", + "//third_party/catapult/third_party/typ/", # Scripts we depend on. Their unit tests are also included. "//tools/json_comment_eater/json_comment_eater.py",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8399310..3e2f74d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -22129,6 +22129,22 @@ <int value="3" label="active, was active"/> </enum> +<enum name="GpuTerminationStatus"> + <summary> + Return status re-encoded values from GetTerminationStatus as defined in + base/process/kill.h enum TerminationStatus. + </summary> + <int value="0" label="Normal">NORMAL_TERMINATION</int> + <int value="1" label="Abnormal">ABNORMAL_TERMINATION</int> + <int value="2" label="Killed">PROCESS_WAS_KILLED</int> + <int value="3" label="Crashed">PROCESS_CRASHED</int> + <int value="4" label="Still Running">STILL_RUNNING</int> + <int value="5" label="Killed by OOM">PROCESS_WAS_KILLED_BY_OOM</int> + <int value="6" label="OOM protected">OOM_PROTECTED</int> + <int value="7" label="Launch Failed">LAUNCH_FAILED</int> + <int value="8" label="OOM">OOM</int> +</enum> + <enum name="GpuTextureResultR16_L16"> <summary> Keeps track of how many users have R16_EXT or/and LUMINANCE_F16, and also @@ -26656,7 +26672,6 @@ <int value="-886912558" label="ChromeHomePromo:enabled"/> <int value="-885601782" label="enable-contextual-search"/> <int value="-884864731" label="WebPaymentsSingleAppUiSkip:enabled"/> - <int value="-881854123" label="enable-heap-profiling"/> <int value="-881447505" label="ash-disable-shelf-model-synchronization"/> <int value="-881054479" label="WebAssemblyStreaming:disabled"/> <int value="-879055117" label="ClipboardContentSetting:enabled"/> @@ -43908,6 +43923,9 @@ </enum> <enum name="TerminationStatus"> + <obsolete> + Deprecated April 2018. Replaced by GpuTerminationStatus. + </obsolete> <summary> Return status values from GetTerminationStatus as defined in base/process/kill.h enum TerminationStatus. The last couple enums are
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 8f0ded7..1e3c846 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -29558,6 +29558,16 @@ </histogram> <histogram name="GPU.GPUProcessTerminationStatus" enum="TerminationStatus"> + <obsolete> + Deprecated April 2018. Replaced by GPU.GPUProcessTerminationStatus2. + </obsolete> + <owner>vmiura@chromium.org</owner> + <summary> + Counts for each time the GPU Process Host detects the process dies. + </summary> +</histogram> + +<histogram name="GPU.GPUProcessTerminationStatus2" enum="GpuTerminationStatus"> <owner>vmiura@chromium.org</owner> <summary> Counts for each time the GPU Process Host detects the process dies. @@ -58436,9 +58446,40 @@ </summary> </histogram> +<histogram name="OfflinePages.ConsistencyCheck.Legacy.DeletedHeadlessFileCount" + units="files"> + <owner>romax@chromium.org</owner> + <summary> + Number of files which are deleted during legacy dir clearing since they have + no associated DB entry and live in private directory. + </summary> +</histogram> + +<histogram name="OfflinePages.ConsistencyCheck.Persistent.ExpiredEntryCount" + units="entries"> + <owner>romax@chromium.org</owner> + <summary> + Number of DB entries (in persistent namespaces) that have been missing their + files for longer than 365 days, and deleted during maintenance task. + </summary> +</histogram> + +<histogram name="OfflinePages.ConsistencyCheck.Persistent.MissingFileCount" + units="files"> + <owner>romax@chromium.org</owner> + <summary> + Number of files that are found missing during maintenance task, which is + also the number of DB entries that are updated with valid file missing time. + </summary> +</histogram> + <histogram name="OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount" units="pages"> + <obsolete> + Deprecated 04/2018, since saving public offline pages to external download + directory needs a different consistency check strategy. + </obsolete> <owner>romax@chromium.org</owner> <summary> Number of persistent offline pages without archive file when checking @@ -58449,6 +58490,10 @@ <histogram name="OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount" units="pages"> + <obsolete> + Deprecated 04/2018, since saving public offline pages to external download + directory needs a different consistency check strategy. + </obsolete> <owner>romax@chromium.org</owner> <summary> Number of archives without database entry when checking persistent page @@ -58456,6 +58501,15 @@ </summary> </histogram> +<histogram name="OfflinePages.ConsistencyCheck.Persistent.ReappearedFileCount" + units="files"> + <owner>romax@chromium.org</owner> + <summary> + Number of files that were marked as missing reappeared in the file system, + which is also the number of DB entries that removes file missing time. + </summary> +</histogram> + <histogram name="OfflinePages.ConsistencyCheck.Persistent.Result" enum="OfflinePagesSyncOperationResult"> <owner>romax@chromium.org</owner> @@ -109700,7 +109754,11 @@ <histogram_suffixes name="ExtensionWebUiPageType" separator="."> <suffix name="MD" label="The Material Design chrome://extensions page."/> - <suffix name="Uber" label="The Uber chrome://extensions page."/> + <suffix name="Uber" label="The Uber chrome://extensions page."> + <obsolete> + Deprecated and removed from code as of 04/2018. + </obsolete> + </suffix> <affected-histogram name="Extensions.WebUi.DocumentLoadedInMainFrameTime"/> <affected-histogram name="Extensions.WebUi.LoadCompletedInMainFrame"/> </histogram_suffixes>
diff --git a/tools/metrics/metrics_python_tests.py b/tools/metrics/metrics_python_tests.py index d619265..6acc509e 100755 --- a/tools/metrics/metrics_python_tests.py +++ b/tools/metrics/metrics_python_tests.py
@@ -8,7 +8,7 @@ THIS_DIR = os.path.abspath(os.path.dirname(__file__)) SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) -TYP_DIR = os.path.join(SRC_DIR, 'third_party', 'typ') +TYP_DIR = os.path.join(SRC_DIR, 'third_party', 'catapult', 'third_party', 'typ') if not TYP_DIR in sys.path: sys.path.insert(0, TYP_DIR)
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py index 5a1e2a84..7870c80 100644 --- a/tools/perf/benchmarks/memory.py +++ b/tools/perf/benchmarks/memory.py
@@ -89,14 +89,6 @@ return page_sets.TrivialSitesStorySet(wait_in_seconds=0, measure_memory=True) - def SetExtraBrowserOptions(self, options): - super(MemoryBenchmarkTrivialSitesDesktop, self).SetExtraBrowserOptions( - options) - # Heap profiling is disabled because of crbug.com/757847. - #options.AppendExtraBrowserArgs([ - # '--enable-heap-profiling=native', - #]) - @classmethod def Name(cls): return 'memory.desktop'
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py index 0b86d552c..4e672089 100644 --- a/tools/perf/benchmarks/system_health.py +++ b/tools/perf/benchmarks/system_health.py
@@ -127,14 +127,6 @@ def Name(cls): return 'system_health.memory_desktop' - def SetExtraBrowserOptions(self, options): - super(DesktopMemorySystemHealth, self).SetExtraBrowserOptions( - options) - # Heap profiling is disabled because of crbug.com/757847. - #options.AppendExtraBrowserArgs([ - # '--enable-heap-profiling=native', - #]) - @benchmark.Owner(emails=['perezju@chromium.org']) class MobileMemorySystemHealth(_MemorySystemHealthBenchmark):
diff --git a/tools/perf/contrib/heap_profiling/heap_profiling.py b/tools/perf/contrib/heap_profiling/heap_profiling.py index c60f4c5..8c95ac8b 100644 --- a/tools/perf/contrib/heap_profiling/heap_profiling.py +++ b/tools/perf/contrib/heap_profiling/heap_profiling.py
@@ -63,9 +63,12 @@ super(_HeapProfilingBenchmark, self).SetExtraBrowserOptions(options) args = [] if self.PROFILING_MODE == 'pseudo': - args += ['--enable-heap-profiling'] + args += [ + '--memlog=all', '--memlog-stack-mode=pseudo', '--memlog-sampling'] elif self.PROFILING_MODE == 'native': - args += ['--enable-heap-profiling=native'] + args += [ + '--memlog=all', '--memlog-stack-mode=native-with-thread-names', + '--memlog-sampling'] options.AppendExtraBrowserArgs(args)
diff --git a/tools/perf/contrib/memory_extras/memory_extras.py b/tools/perf/contrib/memory_extras/memory_extras.py index f46092f..42f44bf 100644 --- a/tools/perf/contrib/memory_extras/memory_extras.py +++ b/tools/perf/contrib/memory_extras/memory_extras.py
@@ -82,7 +82,9 @@ def SetExtraBrowserOptions(self, options): super(LongRunningMemoryBenchmarkSitesDesktop, self).SetExtraBrowserOptions( options) - options.AppendExtraBrowserArgs(['--enable-heap-profiling=native']) + options.AppendExtraBrowserArgs([ + '--memlog=all', '--memlog-sampling', + '--memlog-stack-mode=native-with-thread-names']) # Disable taking screenshot on failing pages. options.take_screenshot_for_failed_page = False
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc index a93b33bb..16076e2a 100644 --- a/ui/android/view_android.cc +++ b/ui/android/view_android.cc
@@ -87,14 +87,9 @@ ViewAndroid::ViewAndroid() : ViewAndroid(LayoutType::NORMAL) {} ViewAndroid::~ViewAndroid() { + RemoveAllChildren(); observer_list_.Clear(); RemoveFromParent(); - - for (std::list<ViewAndroid*>::iterator it = children_.begin(); - it != children_.end(); it++) { - DCHECK_EQ((*it)->parent_, this); - (*it)->parent_ = nullptr; - } } void ViewAndroid::SetDelegate(const JavaRef<jobject>& delegate) { @@ -256,6 +251,18 @@ return gfx::PointF(x + loc_x, y + loc_y); } +void ViewAndroid::RemoveAllChildren() { + bool has_window = GetWindowAndroid(); + auto it = children_.begin(); + while (it != children_.end()) { + if (has_window) + (*it)->OnDetachedFromWindow(); + (*it)->parent_ = nullptr; + // erase returns a new iterator for the element following the ereased one. + it = children_.erase(it); + } +} + void ViewAndroid::RemoveChild(ViewAndroid* child) { DCHECK(child); DCHECK_EQ(child->parent_, this);
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index 18c8ca7..92ecadc 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -197,6 +197,7 @@ bool OnGestureEvent(const GestureEventAndroid& event); void RemoveChild(ViewAndroid* child); + void RemoveAllChildren(); void OnAttachedToWindow(); void OnDetachedFromWindow();
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 2f74c3a9..14aa332 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -360,6 +360,7 @@ test("aura_unittests") { sources = [ "../compositor_extra/shadow_unittest.cc", + "//ui/aura_extra/window_occlusion_impl_unittest_win.cc", "gestures/gesture_recognizer_unittest.cc", "hit_test_data_provider_aura_unittest.cc", "mus/drag_drop_controller_mus_unittest.cc", @@ -392,6 +393,7 @@ "//services/ui/public/cpp", "//skia", "//testing/gtest", + "//ui/aura_extra", "//ui/base:test_support", "//ui/compositor:test_support", "//ui/compositor_extra",
diff --git a/ui/aura_extra/BUILD.gn b/ui/aura_extra/BUILD.gn index dae41d2..f66afd1 100644 --- a/ui/aura_extra/BUILD.gn +++ b/ui/aura_extra/BUILD.gn
@@ -9,6 +9,10 @@ "aura_extra_export.h", "image_window_delegate.cc", "image_window_delegate.h", + "window_occlusion_impl_win.cc", + "window_occlusion_impl_win.h", + "window_occlusion_win.cc", + "window_occlusion_win.h", ] defines = [ "AURA_EXTRA_IMPLEMENTATION" ]
diff --git a/ui/aura_extra/window_occlusion_impl_unittest_win.cc b/ui/aura_extra/window_occlusion_impl_unittest_win.cc new file mode 100644 index 0000000..44e8efeb --- /dev/null +++ b/ui/aura_extra/window_occlusion_impl_unittest_win.cc
@@ -0,0 +1,457 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/aura_extra/window_occlusion_impl_win.h" + +#include "base/win/scoped_gdi_object.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/test/aura_test_base.h" +#include "ui/aura/window_tree_host_platform.h" +#include "ui/gfx/geometry/rect.h" + +namespace aura_extra { + +// A single set of arguments that are passed to WindowEvaluator::Evaluate(). +// Used to mock calls to WindowEvaluator::Evaluate(). +struct EvaluatorArgs { + bool is_relevant; + gfx::Rect window_rect; + HWND hwnd; +}; + +// Iterates over a provided set of mock windows and their properties. +class MockNativeWindowIterator : public NativeWindowIterator { + public: + MockNativeWindowIterator( + const std::vector<EvaluatorArgs>& evaluator_args_list) + : args_list_(evaluator_args_list) {} + + void Iterate(WindowEvaluator* evaluator) override { + for (EvaluatorArgs args : args_list_) { + if (!evaluator->EvaluateWindow(args.is_relevant, args.window_rect, + args.hwnd)) + return; + } + } + + private: + std::vector<EvaluatorArgs> args_list_; + + DISALLOW_COPY_AND_ASSIGN(MockNativeWindowIterator); +}; + +// Test implementation of WindowBoundsDelegate using a flat_map of aura::Window +// to gfx::Rect. +class MockWindowBoundsDelegateImpl : public WindowBoundsDelegate { + public: + MockWindowBoundsDelegateImpl() = default; + + // WindowBoundsDelegate implementation: + gfx::Rect GetBoundsInPixels(aura::WindowTreeHost* window) override { + return root_window_bounds_[window]; + } + + void AddWindowWithBounds(aura::WindowTreeHost* window, + const gfx::Rect& window_bounds_in_pixels) { + root_window_bounds_[window] = window_bounds_in_pixels; + } + + private: + base::flat_map<aura::WindowTreeHost*, gfx::Rect> root_window_bounds_; + + DISALLOW_COPY_AND_ASSIGN(MockWindowBoundsDelegateImpl); +}; + +// The int argument here is an offset in pixels for tests that need to offset +// windows. This allows for variable offsets in the parameterized tests. +using OffsetAndBoundsPair = std::pair<int, gfx::Rect>; + +class WindowOcclusionWinTest + : public aura::test::AuraTestBase, + public ::testing::WithParamInterface<OffsetAndBoundsPair> { + public: + WindowOcclusionWinTest() {} + + void TearDown() override { + Clear(); + aura::test::AuraTestBase::TearDown(); + } + + aura::WindowTreeHost* AddRootAuraWindowWithBounds(const gfx::Rect& bounds) { + std::unique_ptr<aura::WindowTreeHost> window_tree_host( + aura::WindowTreeHost::Create(bounds)); + window_tree_host->window()->Show(); + + EvaluatorArgs args{true, bounds, window_tree_host->GetAcceleratedWidget()}; + evaluator_args_list_.push_back(args); + + mock_bounds_delegate_->AddWindowWithBounds(window_tree_host.get(), bounds); + + aura::WindowTreeHost* host = window_tree_host.get(); + window_tree_hosts_.push_back(std::move(window_tree_host)); + return host; + } + + void AddMockNativeWindowWithBounds(gfx::Rect bounds) { + EvaluatorArgs args{true, bounds, 0}; + evaluator_args_list_.push_back(args); + } + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> + ComputeOcclusion() { + std::unique_ptr<NativeWindowIterator> iterator = + std::make_unique<MockNativeWindowIterator>(evaluator_args_list_); + std::vector<aura::WindowTreeHost*> window_tree_hosts; + + for (auto& host : window_tree_hosts_) + window_tree_hosts.push_back(host.get()); + + return ComputeNativeWindowOcclusionStatusImpl( + window_tree_hosts, std::move(iterator), + std::unique_ptr<WindowBoundsDelegate>(mock_bounds_delegate_.release())); + } + + void Clear() { + evaluator_args_list_.clear(); + window_tree_hosts_.clear(); + } + + private: + std::vector<EvaluatorArgs> evaluator_args_list_; + + std::vector<std::unique_ptr<aura::WindowTreeHost>> window_tree_hosts_; + std::unique_ptr<MockWindowBoundsDelegateImpl> mock_bounds_delegate_ = + std::make_unique<MockWindowBoundsDelegateImpl>(); + + DISALLOW_COPY_AND_ASSIGN(WindowOcclusionWinTest); +}; + +// An aura window completely covered by a native window should be occluded. +TEST_P(WindowOcclusionWinTest, SimpleOccluded) { + OffsetAndBoundsPair param = GetParam(); + AddMockNativeWindowWithBounds(param.second); + aura::WindowTreeHost* window = AddRootAuraWindowWithBounds(param.second); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 1U); + ASSERT_TRUE(base::ContainsKey(result, window)); + EXPECT_EQ(result[window], aura::Window::OcclusionState::OCCLUDED); +} + +// An aura window not occluded at all by a native window should be visible. +TEST_P(WindowOcclusionWinTest, SimpleVisible) { + OffsetAndBoundsPair param = GetParam(); + aura::WindowTreeHost* window = AddRootAuraWindowWithBounds(param.second); + AddMockNativeWindowWithBounds(param.second); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 1U); + ASSERT_TRUE(base::ContainsKey(result, window)); + EXPECT_EQ(result[window], aura::Window::OcclusionState::VISIBLE); + Clear(); +} + +// An aura window occluded by an aura window should be occluded. +TEST_P(WindowOcclusionWinTest, OccludedByAuraWindow) { + OffsetAndBoundsPair param = GetParam(); + aura::WindowTreeHost* window1 = AddRootAuraWindowWithBounds(param.second); + aura::WindowTreeHost* window2 = AddRootAuraWindowWithBounds(param.second); + + std::vector<aura::WindowTreeHost*> windows({window1, window2}); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 2U); + + ASSERT_TRUE(base::ContainsKey(result, window1)); + EXPECT_EQ(result[window1], aura::Window::OcclusionState::VISIBLE); + + ASSERT_TRUE(base::ContainsKey(result, window2)); + EXPECT_EQ(result[window2], aura::Window::OcclusionState::OCCLUDED); +} + +// An aura window occluded by two native windows should be occluded. +TEST_P(WindowOcclusionWinTest, OccludedByMultipleWindows) { + OffsetAndBoundsPair param = GetParam(); + + gfx::Rect left_half = param.second; + left_half.Offset(-left_half.width() / 2, 0); + + gfx::Rect right_half = param.second; + right_half.Offset(right_half.width() / 2, 0); + + AddMockNativeWindowWithBounds(left_half); + AddMockNativeWindowWithBounds(right_half); + aura::WindowTreeHost* window = AddRootAuraWindowWithBounds(param.second); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 1U); + ASSERT_TRUE(base::ContainsKey(result, window)); + EXPECT_EQ(result[window], aura::Window::OcclusionState::OCCLUDED); +} + +// An aura window partially occluded by an aura window should be visible. +TEST_P(WindowOcclusionWinTest, PartiallyOverlappedAuraWindows) { + OffsetAndBoundsPair param = GetParam(); + aura::WindowTreeHost* window1 = AddRootAuraWindowWithBounds(param.second); + + gfx::Rect offset_bounds = param.second; + offset_bounds.Offset(param.first, param.first); + aura::WindowTreeHost* window2 = AddRootAuraWindowWithBounds(offset_bounds); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 2U); + + ASSERT_TRUE(base::ContainsKey(result, window1)); + EXPECT_EQ(result[window1], aura::Window::OcclusionState::VISIBLE); + + ASSERT_TRUE(base::ContainsKey(result, window2)); + EXPECT_EQ(result[window2], aura::Window::OcclusionState::VISIBLE); +} + +// An aura window partially occluded by a native window should be visible. +TEST_P(WindowOcclusionWinTest, PartiallyOverlappedWindows) { + OffsetAndBoundsPair param = GetParam(); + aura::WindowTreeHost* window = AddRootAuraWindowWithBounds(param.second); + + gfx::Rect offset_bounds = param.second; + offset_bounds.Offset(param.first, param.first); + AddMockNativeWindowWithBounds(offset_bounds); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 1U); + + ASSERT_TRUE(base::ContainsKey(result, window)); + EXPECT_EQ(result[window], aura::Window::OcclusionState::VISIBLE); +} + +// If for some reason the bounds of an aura::Window are empty, this signals some +// sort of failure in the call to GetWindowRect() This tests that in this case +// the window is marked as aura::Window::OcclusionState::VISIBLE to avoid +// falsely marking it as occluded. +TEST_P(WindowOcclusionWinTest, EmptyWindowIsVisible) { + aura::WindowTreeHost* window = + AddRootAuraWindowWithBounds(gfx::Rect(0, 0, 0, 0)); + + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> result = + ComputeOcclusion(); + + EXPECT_EQ(result.size(), 1U); + + ASSERT_TRUE(base::ContainsKey(result, window)); + EXPECT_EQ(result[window], aura::Window::OcclusionState::VISIBLE); +} + +INSTANTIATE_TEST_CASE_P(/* no prefix */ + , + WindowOcclusionWinTest, + ::testing::Values( + OffsetAndBoundsPair(5, gfx::Rect(0, 0, 100, 100)), + OffsetAndBoundsPair(10, gfx::Rect(0, 0, 100, 200)), + OffsetAndBoundsPair(15, gfx::Rect(0, 0, 200, 100)), + OffsetAndBoundsPair(20, gfx::Rect(0, 0, 200, 200)), + OffsetAndBoundsPair(25, gfx::Rect(0, 50, 100, 100)), + OffsetAndBoundsPair(50, gfx::Rect(0, 50, 100, 200)), + OffsetAndBoundsPair(75, gfx::Rect(0, 50, 200, 100)), + OffsetAndBoundsPair(100, + gfx::Rect(0, 50, 200, 200)), + OffsetAndBoundsPair(125, + gfx::Rect(100, 0, 100, 100)), + OffsetAndBoundsPair(150, + gfx::Rect(100, 0, 100, 200)), + OffsetAndBoundsPair(200, + gfx::Rect(100, 0, 200, 100)), + OffsetAndBoundsPair(250, + gfx::Rect(100, 0, 200, 200)), + OffsetAndBoundsPair(300, + gfx::Rect(100, 50, 100, 100)), + OffsetAndBoundsPair(400, + gfx::Rect(100, 50, 100, 200)), + OffsetAndBoundsPair(500, + gfx::Rect(100, 50, 200, 100)), + OffsetAndBoundsPair(750, + gfx::Rect(100, 50, 200, 200)))); + +class WindowFitnessFunctionTest : public testing::Test { + public: + HWND CreateNativeWindow(gfx::Rect bounds) { + HWND hwnd = CreateWindow(L"STATIC", L"TestWindow", WS_OVERLAPPED, + bounds.x(), bounds.y(), bounds.width(), + bounds.height(), (HWND)NULL, NULL, NULL, NULL); + + return hwnd; + } + + // Adds the windows style |style| to |hwnd|. + void AddStyle(HWND hwnd, int style_type, DWORD style) { + SetWindowLong(hwnd, style_type, GetWindowLong(hwnd, style_type) | style); + } + + void RemoveStyle(HWND hwnd, int style_type, DWORD style) { + SetWindowLong(hwnd, style_type, GetWindowLong(hwnd, style_type) & ~style); + } +}; + +TEST_F(WindowFitnessFunctionTest, FitnessTest) { + HWND hwnd = CreateNativeWindow(gfx::Rect(0, 0, 100, 100)); + gfx::Rect rect; + + // The window doesn't have the WS_VISIBLE style yet, so it should not pass. + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_STYLE, WS_VISIBLE); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_STYLE, WS_MINIMIZE); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_STYLE, WS_MINIMIZE); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + SetLayeredWindowAttributes(hwnd, RGB(10, 10, 10), NULL, LWA_COLORKEY); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + SetLayeredWindowAttributes(hwnd, NULL, 0, LWA_ALPHA); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + AddStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + SetLayeredWindowAttributes(hwnd, NULL, 255, LWA_ALPHA); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + RemoveStyle(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + // Any complex region should fail, as we only consider simple rectangular + // windows. In this case, we make the region a triangle. + POINT point1; + point1.x = 0; + point1.y = 0; + POINT point2; + point2.x = 50; + point2.y = 0; + POINT point3; + point3.x = 0; + point3.y = 50; + POINT points[] = {point1, point2, point3}; + base::win::ScopedRegion complex_region(CreatePolygonRgn(points, 3, WINDING)); + SetWindowRgn(hwnd, complex_region.get(), TRUE); + EXPECT_FALSE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); + + // A rectangular region should pass. + base::win::ScopedRegion rectangular_region(CreateRectRgn(200, 200, 200, 200)); + SetWindowRgn(hwnd, rectangular_region.get(), TRUE); + EXPECT_TRUE(IsWindowVisibleAndFullyOpaque(hwnd, &rect)); +} + +class MockWindowEvaluator : public WindowEvaluator { + public: + // At the end of the test, the window_stack must be empty, otherwise not all + // the windows were seen. + ~MockWindowEvaluator() { EXPECT_TRUE(window_stack.empty()); } + + // Tests that EnumWindows goes front to back by creating a stack of aura + // windows and popping the top window off the stack as its HWND is seen in + // this callback. If the stack isn't empty at the end, EnumWindows did not see + // all the windows, or did not see them in the correct order. + bool EvaluateWindow(bool is_relevant, + const gfx::Rect& window_rect_in_pixels, + HWND hwnd) override { + if (window_stack.empty()) + return FALSE; + + HWND top_window_hwnd = + window_stack.top()->GetHost()->GetAcceleratedWidget(); + + if (hwnd == top_window_hwnd) + window_stack.pop(); + + return TRUE; + } + + void AddToStack(aura::Window* window) { window_stack.push(window); } + + private: + base::stack<aura::Window*> window_stack; +}; + +// Tests the functionality of EnumWindows. Specifically: +// 1) EnumWindows enumerates all windows on the desktop. +// 2) EnumWindows enumerates from front to back in the Z-order. +// This needs to be tested because 2) is undocumented behavior. However, this +// behavior has been observed in the community and tested to be true. +// ComputeNativeWindowOcclusionStatus() relies on this assumption. +class EnumWindowsTest : public aura::test::AuraTestBase { + public: + EnumWindowsTest() {} + + void TearDown() override { + window_tree_hosts_.clear(); + aura::test::AuraTestBase::TearDown(); + } + + void CreateAuraWindowWithBounds(const gfx::Rect& bounds) { + std::unique_ptr<aura::WindowTreeHost> host( + aura::WindowTreeHost::Create(bounds)); + host->window()->Show(); + evaluator_.AddToStack(host->window()); + window_tree_hosts_.push_back(std::move(host)); + } + + void TestIterator() { + // The iterator will validate that the OS returns the full set of windows in + // the expected order, as encoded by |window_stack| in |evaluator_| + WindowsDesktopWindowIterator iterator; + iterator.Iterate(&evaluator_); + } + + private: + std::vector<std::unique_ptr<aura::WindowTreeHost>> window_tree_hosts_; + + MockWindowEvaluator evaluator_; + + DISALLOW_COPY_AND_ASSIGN(EnumWindowsTest); +}; + +TEST_F(EnumWindowsTest, EnumWindowsGoesFrontToBack) { + CreateAuraWindowWithBounds(gfx::Rect(0, 0, 100, 100)); + CreateAuraWindowWithBounds(gfx::Rect(50, 50, 500, 500)); + CreateAuraWindowWithBounds(gfx::Rect(20, 20, 300, 50)); + CreateAuraWindowWithBounds(gfx::Rect(200, 200, 10, 10)); + CreateAuraWindowWithBounds(gfx::Rect(0, 0, 100, 100)); + + TestIterator(); +} + +} // namespace aura_extra
diff --git a/ui/aura_extra/window_occlusion_impl_win.cc b/ui/aura_extra/window_occlusion_impl_win.cc new file mode 100644 index 0000000..271578a --- /dev/null +++ b/ui/aura_extra/window_occlusion_impl_win.cc
@@ -0,0 +1,234 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/aura_extra/window_occlusion_impl_win.h" + +#include "base/win/scoped_gdi_object.h" +#include "ui/aura/window_tree_host.h" +#include "ui/gfx/geometry/rect.h" + +namespace aura_extra { + +namespace { + +// Determines the occlusion status of each aura::Window in |windows_of_interest| +// passed to the constructor. Evaluates a window by subtracting its bounds from +// every window beneath it in the z-order. +class WindowEvaluatorImpl : public WindowEvaluator { + public: + // |windows_of_interest| are the aura::WindowTreeHost's whose occlusion + // status are being calculated. |bounds_delegate| is used to obtain the bounds + // in pixels of each root aura::Window in |windows_of_interest|. + WindowEvaluatorImpl( + const std::vector<aura::WindowTreeHost*>& windows_of_interest, + std::unique_ptr<WindowBoundsDelegate> bounds_delegate); + ~WindowEvaluatorImpl(); + + // WindowEvaluator. + bool EvaluateWindow(bool is_relevant, + const gfx::Rect& window_rect_in_pixels, + HWND hwnd) override; + + // Returns whether there was at least one visible root aura::Window passed to + // ComputeNativeWindowOcclusionStatus(). + bool HasAtLeastOneVisibleWindow() const { + return !unoccluded_regions_.empty(); + } + + // Called once the occlusion computation is done. Returns |occlusion_states_| + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> + TakeResult(); + + private: + using WindowRegionPair = std::pair<aura::WindowTreeHost*, SkRegion>; + + // Stores intermediate values for the unoccluded regions of an aura::Window in + // pixels. Once an aura::Window::OcclusionState is determined for a root + // aura::Window, that aura::Window is removed from |unoccluded_regions_| and + // added to |occlusion_states_| with the computed + // aura::Window::OcclusionState. + std::vector<WindowRegionPair> unoccluded_regions_; + + // Stores the final aura::Window::OcclusionState for each root + // aura::WindowTreeHost that is passed to + // ComputeNativeWindowOcclusionStatus(). + base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> + occlusion_states_; + + DISALLOW_COPY_AND_ASSIGN(WindowEvaluatorImpl); +}; + +WindowEvaluatorImpl::WindowEvaluatorImpl( + const std::vector<aura::WindowTreeHost*>& windows_of_interest, + std::unique_ptr<WindowBoundsDelegate> bounds_delegate) { + for (aura::WindowTreeHost* window : windows_of_interest) { + // If the window isn't visible at this time, it is + // aura::Window::OcclusionState::HIDDEN. + if (!window->window()->IsVisible() || + IsIconic(window->GetAcceleratedWidget())) { + occlusion_states_[window] = aura::Window::OcclusionState::HIDDEN; + continue; + } + + gfx::Rect window_rect_in_pixels = + bounds_delegate->GetBoundsInPixels(window); + + SkRegion window_region(SkIRect::MakeXYWH( + window_rect_in_pixels.x(), window_rect_in_pixels.y(), + window_rect_in_pixels.width(), window_rect_in_pixels.height())); + + unoccluded_regions_.emplace_back(window, window_region); + } +} + +WindowEvaluatorImpl::~WindowEvaluatorImpl() = default; + +bool WindowEvaluatorImpl::EvaluateWindow(bool is_relevant, + const gfx::Rect& window_rect_in_pixels, + HWND hwnd) { + // Loop through |unoccluded_regions_| and determine how |hwnd| affects each + // root window with respect to occlusion. + for (WindowRegionPair& root_window_pair : unoccluded_regions_) { + HWND window_hwnd = root_window_pair.first->GetAcceleratedWidget(); + + // The EnumWindows callbacks have reached this window in the Z-order + // (EnumWindows goes from front to back). This window must be visible + // because we did not discover that it was completely occluded earlier. + if (hwnd == window_hwnd) { + occlusion_states_[root_window_pair.first] = + aura::Window::OcclusionState::VISIBLE; + // Set the unoccluded region for this window to empty as a signal that the + // occlusion computation is complete. + root_window_pair.second.setEmpty(); + continue; + } + + // |hwnd| is not taken into account for occlusion computations, move on. + if (!is_relevant) + continue; + + // Current occlusion state for this window cannot be determined yet. The + // EnumWindows callbacks are currently above this window in the Z-order. + // Subtract the other windows bounding rectangle from this window's + // unoccluded region if the two regions intersect. + SkRegion window_region(SkIRect::MakeXYWH( + window_rect_in_pixels.x(), window_rect_in_pixels.y(), + window_rect_in_pixels.width(), window_rect_in_pixels.height())); + + if (root_window_pair.second.intersects(window_region)) { + root_window_pair.second.op(window_region, SkRegion::kDifference_Op); + + if (root_window_pair.second.isEmpty()) { + occlusion_states_[root_window_pair.first] = + aura::Window::OcclusionState::OCCLUDED; + } + } + } + + // Occlusion computation is done for windows with an empty region in + // |unoccluded_regions_|. If the window is visible, the region is set to empty + // explicitly. If it is occluded, the region is implicitly empty. + base::EraseIf(unoccluded_regions_, [](const WindowRegionPair& element) { + return element.second.isEmpty(); + }); + + // If |unoccluded_regions_| is empty, the occlusion calculation is complete. + // So, we return false to signal to EnumWindows to stop enumerating. + // Otherwise, we want EnumWindows to continue, and return true. + return !unoccluded_regions_.empty(); +} + +base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> +WindowEvaluatorImpl::TakeResult() { + return std::move(occlusion_states_); +} + +} // namespace + +WindowsDesktopWindowIterator::WindowsDesktopWindowIterator() = default; + +void WindowsDesktopWindowIterator::Iterate(WindowEvaluator* evaluator) { + evaluator_ = evaluator; + EnumWindows(&EnumWindowsOcclusionCallback, reinterpret_cast<LPARAM>(this)); +} + +BOOL WindowsDesktopWindowIterator::RunEvaluator(HWND hwnd) { + gfx::Rect window_rect; + bool is_relevant = IsWindowVisibleAndFullyOpaque(hwnd, &window_rect); + return evaluator_->EvaluateWindow(is_relevant, window_rect, hwnd); +} + +// static +BOOL CALLBACK +WindowsDesktopWindowIterator::EnumWindowsOcclusionCallback(HWND hwnd, + LPARAM lParam) { + WindowsDesktopWindowIterator* iterator = + reinterpret_cast<WindowsDesktopWindowIterator*>(lParam); + return iterator->RunEvaluator(hwnd); +} + +base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> +ComputeNativeWindowOcclusionStatusImpl( + const std::vector<aura::WindowTreeHost*>& windows, + std::unique_ptr<NativeWindowIterator> iterator, + std::unique_ptr<WindowBoundsDelegate> bounds_delegate) { + WindowEvaluatorImpl window_evaluator(windows, std::move(bounds_delegate)); + + // Only compute occlusion if there was at least one window that is visible. + if (window_evaluator.HasAtLeastOneVisibleWindow()) + iterator->Iterate(&window_evaluator); + + return window_evaluator.TakeResult(); +} + +bool IsWindowVisibleAndFullyOpaque(HWND hwnd, gfx::Rect* rect_in_pixels) { + // Filter out invalid hwnds. + if (!IsWindow(hwnd)) + return false; + + // Filter out windows that are not “visible”. + if (!IsWindowVisible(hwnd)) + return false; + + // Filter out minimized windows. + if (IsIconic(hwnd)) + return false; + + LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE); + + // Filter out “transparent” windows, windows where the mouse clicks fall + // through them. + if (ex_styles & WS_EX_TRANSPARENT) + return false; + + // Filter out “tool windows”, which are floating windows that do not appear on + // the taskbar or ALT-TAB. Floating windows can have larger window rectangles + // than what is visible to the user, so by filtering them out we will avoid + // incorrectly marking native windows as occluded. + if (ex_styles & WS_EX_TOOLWINDOW) + return false; + + // Filter out layered windows. + if (ex_styles & WS_EX_LAYERED) + return false; + + // Filter out windows that do not have a simple rectangular region. + base::win::ScopedRegion region(CreateRectRgn(0, 0, 0, 0)); + if (GetWindowRgn(hwnd, region.get()) == COMPLEXREGION) + return false; + + RECT window_rect; + // Filter out windows that take up zero area. The call to GetWindowRect is one + // of the most expensive parts of this function, so it is last. + if (!GetWindowRect(hwnd, &window_rect)) + return false; + if (IsRectEmpty(&window_rect)) + return false; + + rect_in_pixels->SetByBounds(window_rect.left, window_rect.top, + window_rect.right, window_rect.bottom); + return true; +} + +} // namespace aura_extra
diff --git a/ui/aura_extra/window_occlusion_impl_win.h b/ui/aura_extra/window_occlusion_impl_win.h new file mode 100644 index 0000000..2f0aa13f --- /dev/null +++ b/ui/aura_extra/window_occlusion_impl_win.h
@@ -0,0 +1,100 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_AURA_EXTRA_WINDOW_OCCLUSION_IMPL_WIN_H_ +#define UI_AURA_EXTRA_WINDOW_OCCLUSION_IMPL_WIN_H_ + +#include <windows.h> +#include <winuser.h> + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#include "ui/aura_extra/aura_extra_export.h" + +namespace aura_extra { + +// Delegate to get the native window bounds in pixels for a root aura::Window. +class WindowBoundsDelegate { + public: + WindowBoundsDelegate() {} + virtual ~WindowBoundsDelegate() {} + + // Gets the bounds in pixels for |window|. + virtual gfx::Rect GetBoundsInPixels(aura::WindowTreeHost* window) = 0; + + DISALLOW_COPY_AND_ASSIGN(WindowBoundsDelegate); +}; + +// Stores internal state during occlusion computation by +// ComputeNativeWindowOcclusionStatus(). +class AURA_EXTRA_EXPORT WindowEvaluator { + public: + WindowEvaluator() {} + // Called by NativeWindowIterator::Iterate and processes the metadata for a + // single window. It is assumed that this is called in reverse z-order + // (topmost window first, bottom window last). |is_relevant| describes if the + // window is relevant to this calculation (it is visible and fully opaque), + // |window_rect_in_pixels| is the bounds of the window in pixels, and |hwnd| + // is the HWND of the window. Returns false if no more windows need to be + // evaluated (this happens when all the desired occlusion states have been + // determined), true otherwise. + virtual bool EvaluateWindow(bool is_relevant, + const gfx::Rect& window_rect_in_pixels, + HWND hwnd) = 0; + + DISALLOW_COPY_AND_ASSIGN(WindowEvaluator); +}; + +// Interface to enumerate through all the native windows. Overriden in tests to +// avoid having to rely on the OS to enumerate native windows using +// EnumWindows(). +class NativeWindowIterator { + public: + virtual ~NativeWindowIterator() {} + + // Enumerates through a collection of windows and applies |evaluator| to each + // window. Enumeration is done from topmost to bottommost in the z-order, and + // will stop once the evaluator returns false. + virtual void Iterate(WindowEvaluator* evaluator) = 0; +}; + +class AURA_EXTRA_EXPORT WindowsDesktopWindowIterator + : public NativeWindowIterator { + public: + WindowsDesktopWindowIterator(); + + // NativeWindowIterator: + void Iterate(WindowEvaluator* evaluator) override; + + private: + // Runs |evaluator_| for |hwnd|. Returns TRUE if the evaluator should be run + // again, FALSE otherwise. + BOOL RunEvaluator(HWND hwnd); + + static BOOL CALLBACK EnumWindowsOcclusionCallback(HWND hwnd, LPARAM lParam); + + WindowEvaluator* evaluator_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(WindowsDesktopWindowIterator); +}; + +// Returns true if we are interested in |hwnd| for purposes of occlusion +// calculation. We are interested in |hwnd| if it is a window that is visible, +// opaque, and a simple rectangle. If we are interested in |hwnd|, stores the +// window rectangle in |rect| +bool AURA_EXTRA_EXPORT IsWindowVisibleAndFullyOpaque(HWND hwnd, + gfx::Rect* rect_in_pixels); + +// Implementation of ComputeNativeWindowOcclusionStatus(). +base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> + AURA_EXTRA_EXPORT ComputeNativeWindowOcclusionStatusImpl( + const std::vector<aura::WindowTreeHost*>& windows, + std::unique_ptr<NativeWindowIterator> iterator, + std::unique_ptr<WindowBoundsDelegate> bounds_delegate); + +} // namespace aura_extra + +#endif // UI_AURA_EXTRA_WINDOW_OCCLUSION_IMPL_WIN_H_
diff --git a/ui/aura_extra/window_occlusion_win.cc b/ui/aura_extra/window_occlusion_win.cc new file mode 100644 index 0000000..9a8c4be7 --- /dev/null +++ b/ui/aura_extra/window_occlusion_win.cc
@@ -0,0 +1,48 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/aura_extra/window_occlusion_win.h" + +#include "ui/aura_extra/window_occlusion_impl_win.h" + +namespace aura_extra { + +namespace { + +// Default implementation of WindowBoundsDelegate using GetWindowRect(). +class WindowBoundsDelegateImpl : public WindowBoundsDelegate { + public: + WindowBoundsDelegateImpl(); + ~WindowBoundsDelegateImpl() override {} + + // WindowBoundsDelegate: + gfx::Rect GetBoundsInPixels(aura::WindowTreeHost* window) override; + + DISALLOW_COPY_AND_ASSIGN(WindowBoundsDelegateImpl); +}; + +WindowBoundsDelegateImpl::WindowBoundsDelegateImpl() = default; + +gfx::Rect WindowBoundsDelegateImpl::GetBoundsInPixels( + aura::WindowTreeHost* window) { + HWND hwnd = window->GetAcceleratedWidget(); + RECT window_rect_in_pixels; + + bool success = GetWindowRect(hwnd, &window_rect_in_pixels); + DCHECK(success); + + return gfx::Rect(window_rect_in_pixels); +} + +} // namespace + +base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> +ComputeNativeWindowOcclusionStatus( + const std::vector<aura::WindowTreeHost*>& windows) { + return ComputeNativeWindowOcclusionStatusImpl( + windows, std::make_unique<WindowsDesktopWindowIterator>(), + std::make_unique<WindowBoundsDelegateImpl>()); +} + +} // namespace aura_extra
diff --git a/ui/aura_extra/window_occlusion_win.h b/ui/aura_extra/window_occlusion_win.h new file mode 100644 index 0000000..9e0096907 --- /dev/null +++ b/ui/aura_extra/window_occlusion_win.h
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_AURA_EXTRA_WINDOW_OCCLUSION_WIN_H_ +#define UI_AURA_EXTRA_WINDOW_OCCLUSION_WIN_H_ + +#include <vector> + +#include "base/containers/flat_map.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#include "ui/aura_extra/aura_extra_export.h" + +namespace aura_extra { + +// Computes the native window occlusion status for each aura::WindowTreeHost in +// |windows|. +AURA_EXTRA_EXPORT +base::flat_map<aura::WindowTreeHost*, aura::Window::OcclusionState> +ComputeNativeWindowOcclusionStatus( + const std::vector<aura::WindowTreeHost*>& windows); + +} // namespace aura_extra + +#endif // UI_AURA_EXTRA_WINDOW_OCCLUSION_WIN_H
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index b209b39..64d19b6 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -210,7 +210,6 @@ "l10n/l10n_util_collator.h", "l10n/l10n_util_mac.h", "l10n/l10n_util_mac.mm", - "l10n/l10n_util_posix.cc", "l10n/l10n_util_win.cc", "l10n/l10n_util_win.h", "l10n/time_format.cc", @@ -325,6 +324,10 @@ "work_area_watcher_observer.h", ] + if (is_posix) { + sources += [ "l10n/l10n_util_posix.cc" ] + } + if (!is_ios) { sources += [ "accelerators/accelerator.cc", @@ -394,6 +397,7 @@ if (is_fuchsia) { sources += [ "idle/idle_fuchsia.cc", + "l10n/l10n_util_posix.cc", "resource/resource_bundle_fuchsia.cc", ] }
diff --git a/ui/display/display_switches.cc b/ui/display/display_switches.cc index 880fba6..72da86a 100644 --- a/ui/display/display_switches.cc +++ b/ui/display/display_switches.cc
@@ -76,13 +76,7 @@ // TODO(malaykeshav): Remove this in M68 when the feature has been in stable for // atleast one milestone. constexpr base::Feature kEnableDisplayZoomSetting{ - "EnableDisplayZoomSetting", -#if defined(OS_CHROMEOS) - base::FEATURE_ENABLED_BY_DEFAULT -#else - base::FEATURE_DISABLED_BY_DEFAULT -#endif -}; + "EnableDisplayZoomSetting", base::FEATURE_DISABLED_BY_DEFAULT}; bool IsDisplayZoomSettingEnabled() { return base::FeatureList::IsEnabled(kEnableDisplayZoomSetting);
diff --git a/ui/display/manager/display_layout_store.h b/ui/display/manager/display_layout_store.h index 878e4cd..5c68352 100644 --- a/ui/display/manager/display_layout_store.h +++ b/ui/display/manager/display_layout_store.h
@@ -22,10 +22,15 @@ DisplayLayoutStore(); ~DisplayLayoutStore(); - // Set true to force mirror mode. - void set_forced_mirror_mode(bool forced) { forced_mirror_mode_ = forced; } + // Set true to force mirror mode. This should only be used when tablet mode is + // turned on/off. + void set_forced_mirror_mode_for_tablet(bool forced) { + forced_mirror_mode_for_tablet_ = forced; + } - bool forced_mirror_mode() const { return forced_mirror_mode_; } + bool forced_mirror_mode_for_tablet() const { + return forced_mirror_mode_for_tablet_; + } void SetDefaultDisplayPlacement(const DisplayPlacement& placement); @@ -50,7 +55,7 @@ // The default display placement. DisplayPlacement default_display_placement_; - bool forced_mirror_mode_ = false; + bool forced_mirror_mode_for_tablet_ = false; // Display layout per list of devices. std::map<DisplayIdList, std::unique_ptr<DisplayLayout>> layouts_;
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index 5301ee42..f1cccf22 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -1283,7 +1283,7 @@ bool DisplayManager::ShouldSetMirrorModeOn(const DisplayIdList& new_id_list) { DCHECK(new_id_list.size() > 1); - if (layout_store_->forced_mirror_mode()) + if (layout_store_->forced_mirror_mode_for_tablet()) return true; if (disable_restoring_mirror_mode_for_test_) @@ -1406,7 +1406,10 @@ bool DisplayManager::IsSoftwareMirroringEnforced() const { // There is no source display for hardware mirroring, so enforce software // mirroring if the mixed mirror mode parameters are specified. - return !!mixed_mirror_mode_params_; + // Enforce software mirroring if tablet mode is enabled as well because + // the tablet's rotation should be offset in external display. + return !!mixed_mirror_mode_params_ || + layout_store_->forced_mirror_mode_for_tablet(); } void DisplayManager::SetTouchCalibrationData(
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index dee370bf..42e62a1 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -159,7 +159,6 @@ "win/keyboard_hook_win.cc", "win/system_event_state_lookup.cc", "win/system_event_state_lookup.h", - "x/keyboard_hook_posix.cc", ] defines = [ "EVENTS_IMPLEMENTATION" ] @@ -179,7 +178,10 @@ ] if (use_x11) { - sources += [ "x/events_x.cc" ] + sources += [ + "x/events_x.cc", + "x/keyboard_hook_posix.cc", + ] configs += [ "//build/config/linux:x11" ] deps += [ "//ui/events/devices",
diff --git a/ui/file_manager/file_manager/background/js/media_import_handler.js b/ui/file_manager/file_manager/background/js/media_import_handler.js index c2655e5..5aa28d5 100644 --- a/ui/file_manager/file_manager/background/js/media_import_handler.js +++ b/ui/file_manager/file_manager/background/js/media_import_handler.js
@@ -242,7 +242,7 @@ tracker) { importer.TaskQueue.BaseTask.call(this, taskId); - /** @private {string} */ + /** @protected {string} */ this.taskId_ = taskId; /** @private {!importer.Destination} */
diff --git a/ui/file_manager/file_manager/background/js/task_queue.js b/ui/file_manager/file_manager/background/js/task_queue.js index 0170b28..1f1adea 100644 --- a/ui/file_manager/file_manager/background/js/task_queue.js +++ b/ui/file_manager/file_manager/background/js/task_queue.js
@@ -178,7 +178,7 @@ * @param {string} taskId */ importer.TaskQueue.BaseTask = function(taskId) { - /** @private {string} */ + /** @protected {string} */ this.taskId_ = taskId; /** @private {!Array<!importer.TaskQueue.Task.Observer>} */ this.observers_ = [];
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 7a2865d..9bc1e8fe 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -324,7 +324,6 @@ * returns it. * @param {string} query Query for the element. * @param {function(new: T, ...)} type Type used to decorate. - * @private * @template T * @return {!T} Decorated element. */
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index b687fd73..0e6da8e 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1680,6 +1680,11 @@ url(../images/files/ui/2x/person_add.png) 2x); } +#action-bar { + display: flex; + flex: none; +} + .detail-name > * { align-items: center; display: flex;
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js index acac23f3..0d4eb71 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -268,10 +268,11 @@ if (!this.ignoreCurrentDirectoryDeletion_) { // If the change is deletion of currentDir, move up to its parent directory. - directoryEntry.getDirectory(directoryEntry.fullPath, {create: false}, - function() {}, + directoryEntry.getDirectory( + directoryEntry.fullPath, {create: false}, function() {}, function() { - var volumeInfo = this.volumeManager_.getVolumeInfo(directoryEntry); + var volumeInfo = + this.volumeManager_.getVolumeInfo(assert(directoryEntry)); if (volumeInfo) { volumeInfo.resolveDisplayRoot().then(function(displayRoot) { this.changeDirectoryEntry(displayRoot); @@ -1156,8 +1157,8 @@ // When the volume where we are is unmounted, fallback to the default volume's // root. If current directory path is empty, stop the fallback // since the current directory is initializing now. - if (this.getCurrentDirEntry() && - !this.volumeManager_.getVolumeInfo(this.getCurrentDirEntry())) { + var entry = this.getCurrentDirEntry(); + if (entry && !this.volumeManager_.getVolumeInfo(entry)) { this.volumeManager_.getDefaultDisplayRoot(function(displayRoot) { this.changeDirectoryEntry(displayRoot); }.bind(this));
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 95c9035..0a55cc2 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -548,7 +548,7 @@ if (!root) root = directoryModel.getCurrentDirEntry(); - var volumeInfo = fileManager.volumeManager.getVolumeInfo(root); + var volumeInfo = fileManager.volumeManager.getVolumeInfo(assert(root)); if (volumeInfo) { fileManager.ui.confirmDialog.show( loadTimeData.getString('FORMATTING_WARNING'), @@ -1051,8 +1051,9 @@ event.target instanceof DirectoryItem) { var isRemovableRoot = false; var entry = CommandUtil.getCommandEntry(event.target); + var volumeInfo = null; if (entry) { - var volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); + volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); // Checks whether the target is actually external drive or just a folder // inside the drive. if (volumeInfo && @@ -1761,6 +1762,25 @@ }); /** + * Focus the first button visible on action bar (at the top). + * @type {Command} + */ +CommandHandler.COMMANDS_['focus-action-bar'] = /** @type {Command} */ ({ + /** + * @param {!Event} event Command event. + * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. + */ + execute: function(event, fileManager) { + fileManager.ui.actionbar.querySelector('button:not([hidden])').focus(); + }, + /** + * @param {!Event} event Command event. + * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. + */ + canExecute: CommandUtil.canExecuteAlways +}); + +/** * Handle back button. * @type {Command} */
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index 7e9f05d..1e1d1a34 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -516,7 +516,6 @@ * * @param {function(boolean, Array<!Entry>)=} opt_callback Called when the * default task is executed, or the error is occurred. - * @private */ FileTasks.prototype.executeDefault = function(opt_callback) { FileTasks.recordViewingFileTypeUMA_(this.entries_); @@ -652,7 +651,6 @@ * Executes a single task. * * @param {string} taskId Task identifier. - * @private */ FileTasks.prototype.execute = function(taskId) { FileTasks.recordViewingFileTypeUMA_(this.entries_);
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js index 087a7795..aa5b5ff 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js
@@ -244,7 +244,7 @@ var entry = /** @type {Entry} */ (this.dataModel_.item(this.cursor_)); // Check volume type for optimizing the parameters. - var volumeInfo = this.volumeManager_.getVolumeInfo(entry); + var volumeInfo = this.volumeManager_.getVolumeInfo(assert(entry)); this.currentVolumeType_ = volumeInfo ? volumeInfo.volumeType : null; // If tasks are running full or all items are scanned, do nothing.
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js index 098a64e..9f8a7b28 100644 --- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js +++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -200,7 +200,7 @@ this.shortcutList_ = []; for (var i = 0; i < this.shortcutListModel_.length; i++) { - var shortcutEntry = /** @type {Entry} */ (this.shortcutListModel_.item(i)); + var shortcutEntry = /** @type {!Entry} */ (this.shortcutListModel_.item(i)); var volumeInfo = this.volumeManager_.getVolumeInfo(shortcutEntry); this.shortcutList_.push(entryToModelItem(shortcutEntry)); }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/banners.js b/ui/file_manager/file_manager/foreground/js/ui/banners.js index f21eef6..408c7f5 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/banners.js +++ b/ui/file_manager/file_manager/foreground/js/ui/banners.js
@@ -554,7 +554,7 @@ if (!this.directoryModel_.getCurrentDirEntry()) return; - var currentDirEntry = this.directoryModel_.getCurrentDirEntry(); + var currentDirEntry = assert(this.directoryModel_.getCurrentDirEntry()); var currentVolume = currentDirEntry && this.volumeManager_.getVolumeInfo(currentDirEntry); var eventVolume = this.volumeManager_.getVolumeInfo(event.entry); @@ -592,10 +592,9 @@ return; chrome.fileManagerPrivate.getSizeStats( - volume.volumeId, - function(sizeStats) { + volume.volumeId, function(sizeStats) { var currentVolume = this.volumeManager_.getVolumeInfo( - this.directoryModel_.getCurrentDirEntry()); + assert(this.directoryModel_.getCurrentDirEntry())); if (volume !== currentVolume) { // This happens when the current directory is moved during requesting // the file system size. Just ignore it.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js index 63515a6f..6a70b68 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js
@@ -17,7 +17,7 @@ /** * One-time initialization of DOM. - * @private + * @protected */ ErrorDialog.prototype.initDom_ = function() { cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js index eb67a386..af808be 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -117,7 +117,6 @@ /** * Sets list thumbnail loader. * @param {ListThumbnailLoader} listThumbnailLoader A list thumbnail loader. - * @private */ FileGrid.prototype.setListThumbnailLoader = function(listThumbnailLoader) { if (this.listThumbnailLoader_) {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index b445455..abd6cd53 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -121,7 +121,6 @@ /** * The container element of the dialog. * @type {!HTMLElement} - * @private */ this.dialogContainer = queryRequiredElement('.dialog-container', this.element); @@ -148,6 +147,14 @@ this.toolbar = queryRequiredElement('.dialog-header', this.element); /** + * The actionbar which contains buttons to perform actions on selected + * file(s). + * @type {!HTMLElement} + * @const + */ + this.actionbar = queryRequiredElement('#action-bar', this.toolbar); + + /** * The navigation list. * @type {!HTMLElement} * @const @@ -189,7 +196,7 @@ /** * Ripple effect of sort button. - * @private {!FilesToggleRipple} + * @type {!FilesToggleRipple} * @const */ this.sortButtonToggleRipple = @@ -542,7 +549,7 @@ } }; - customSplitter.decorate(splitterElement); + /** @type Object */ (customSplitter).decorate(splitterElement); splitterElement.resizeNextElement = !!opt_resizeNextElement; };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index 0ec9ea30..d69727d 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -482,7 +482,7 @@ var currentSelection = []; var bottom = y + (opt_height || 0); for (var i = 0; i < this.selectionModel_.length; i++) { - var itemMetrics = this.getHeightsForIndex_(i); + var itemMetrics = this.getHeightsForIndex(i); if (itemMetrics.top < bottom && itemMetrics.top + itemMetrics.height >= y) currentSelection.push(i); }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js index 7cc90e7..3576bea 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -139,6 +139,7 @@ // Overriding the default role 'list' to 'listbox' for better // accessibility on ChromeOS. li.setAttribute('role', 'option'); + li.setAttribute('aria-describedby', 'more-actions-info'); Object.defineProperty(li, 'selected', { /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js index 3c1d404..b1e7cde 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js
@@ -15,7 +15,7 @@ FilesAlertDialog.prototype.__proto__ = cr.ui.dialogs.AlertDialog.prototype; /** - * @private + * @protected * @override */ FilesAlertDialog.prototype.initDom_ = function() {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js index 85e03460..3be04f8 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js
@@ -15,7 +15,7 @@ FilesConfirmDialog.prototype.__proto__ = cr.ui.dialogs.ConfirmDialog.prototype; /** - * @private + * @protected * @override */ FilesConfirmDialog.prototype.initDom_ = function() {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js index 3f94e0a..e6dcf93 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js
@@ -133,7 +133,7 @@ /** * One-time initialization of DOM. - * @private + * @protected */ ShareDialog.prototype.initDom_ = function() { FileManagerDialogBase.prototype.initDom_.call(this);
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index 52aa70bc..df35133b 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -172,6 +172,7 @@ i18n-values="label:INSTALL_NEW_EXTENSION_LABEL"> <command id="open-gear-menu" shortcut="e|Alt f|Alt"> <command id="browser-back" shortcut="BrowserBack"> + <command id="focus-action-bar" shortcut="a|Alt"> </commands> <cr-menu id="file-context-menu" class="chrome-menu files-menu" @@ -300,99 +301,101 @@ </div> <div id="files-selected-label"></div> <div class="spacer"></div> - <button id="tasks" class="combobutton menu-button" menu="#tasks-menu" - tabindex="10" hidden - i18n-values="aria-label:TASKS_BUTTON_LABEL"> - </button> - <button id="share-menu-button" class="icon-button menu-button" tabindex="11" hidden - menu="#share-menu" - i18n-values="aria-label:SHARE_BUTTON_TOOLTIP" - aria-activedescendant="share-menu" - has-tooltip> - <files-toggle-ripple></files-toggle-ripple> - <div class="icon"></div> - </button> - <button id="delete-button" class="icon-button menu-button" tabindex="12" hidden - i18n-values="aria-label:DELETE_BUTTON_LABEL" - visibleif="full-page" - has-tooltip> - <files-ripple></files-ripple> - <div class="icon"></div> - </button> - <button id="search-button" class="icon-button menu-button" tabindex="13" - i18n-values="aria-label:SEARCH_TEXT_LABEL" - has-tooltip> - <files-toggle-ripple></files-toggle-ripple> - <div class="icon"></div> - </button> - <div id="search-box"> - <paper-input-container no-label-float> - <input is="iron-input" type="search" tabindex="14" slot="input" - i18n-values="aria-label:SEARCH_TEXT_LABEL;placeholder:SEARCH_TEXT_LABEL" - hidden> - <span class="clear" slot="suffix"></span> - </paper-input-container> - </div> - <button id="refresh-button" class="icon-button menu-button" tabindex="15" hidden - i18n-values="aria-label:REFRESH_BUTTON_LABEL" - command="#refresh" has-tooltip> - <files-ripple></files-ripple> - <div class="icon"></div> - </button> - <div id="cloud-import-combo-button" - class="cloud-import-combo-button" - hidden> - <div class="buttons"> - <button id="cloud-import-button" - class="icon-button menu-button" - tabindex="16" - i18n-values="aria-label:CLOUD_IMPORT_COMMAND" - has-tooltip> - <iron-icon icon="files:cloud-queue"></iron-icon> - </button> - <button id="cloud-import-details-button" - class="icon-button menu-button" - tabindex="16" - i18n-values="aria-label:CLOUD_IMPORT_SHOW_DETAILS" - has-tooltip> - <iron-icon icon="files:arrow-drop-down"></iron-icon> - </button> - </div> - <div class="ripples"> - <paper-ripple></paper-ripple> + <div id="action-bar"> + <button id="tasks" class="combobutton menu-button" menu="#tasks-menu" + tabindex="10" hidden + i18n-values="aria-label:TASKS_BUTTON_LABEL"> + </button> + <button id="share-menu-button" class="icon-button menu-button" tabindex="11" hidden + menu="#share-menu" + i18n-values="aria-label:SHARE_BUTTON_TOOLTIP" + aria-activedescendant="share-menu" + has-tooltip> <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> + <button id="delete-button" class="icon-button menu-button" tabindex="12" hidden + i18n-values="aria-label:DELETE_BUTTON_LABEL" + visibleif="full-page" + has-tooltip> + <files-ripple></files-ripple> + <div class="icon"></div> + </button> + <button id="search-button" class="icon-button menu-button" tabindex="13" + i18n-values="aria-label:SEARCH_TEXT_LABEL" + has-tooltip> + <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> + <div id="search-box"> + <paper-input-container no-label-float> + <input is="iron-input" type="search" tabindex="14" slot="input" + i18n-values="aria-label:SEARCH_TEXT_LABEL;placeholder:SEARCH_TEXT_LABEL" + hidden> + <span class="clear" slot="suffix"></span> + </paper-input-container> </div> + <button id="refresh-button" class="icon-button menu-button" tabindex="15" hidden + i18n-values="aria-label:REFRESH_BUTTON_LABEL" + command="#refresh" has-tooltip> + <files-ripple></files-ripple> + <div class="icon"></div> + </button> + <div id="cloud-import-combo-button" + class="cloud-import-combo-button" + hidden> + <div class="buttons"> + <button id="cloud-import-button" + class="icon-button menu-button" + tabindex="16" + i18n-values="aria-label:CLOUD_IMPORT_COMMAND" + has-tooltip> + <iron-icon icon="files:cloud-queue"></iron-icon> + </button> + <button id="cloud-import-details-button" + class="icon-button menu-button" + tabindex="16" + i18n-values="aria-label:CLOUD_IMPORT_SHOW_DETAILS" + has-tooltip> + <iron-icon icon="files:arrow-drop-down"></iron-icon> + </button> + </div> + <div class="ripples"> + <paper-ripple></paper-ripple> + <files-toggle-ripple></files-toggle-ripple> + </div> + </div> + <button id="view-button" class="icon-button menu-button" tabindex="17" + i18n-values="aria-label:CHANGE_TO_THUMBNAILVIEW_BUTTON_LABEL" + has-tooltip> + <files-ripple></files-ripple> + <div class="icon"></div> + </button> + <button id="sort-button" class="icon-button menu-button" tabindex="18" + menu="#sort-menu" + i18n-values="aria-label:SORT_BUTTON_TOOLTIP" + aria-activedescendant="sort-menu" + has-tooltip> + <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> + <button id="gear-button" class="icon-button menu-button" tabindex="19" + menu="#gear-menu" + i18n-values="aria-label:GEAR_BUTTON_TOOLTIP" + aria-activedescendant="gear-menu" + has-tooltip> + <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> + <button id="selection-menu-button" class="icon-button menu-button" tabindex="19" + menu="#file-context-menu" + i18n-values="aria-label:SELECTION_MENU_BUTTON_TOOLTIP" + aria-activedescendant="file-context-menu" + has-tooltip hidden> + <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> </div> - <button id="view-button" class="icon-button menu-button" tabindex="17" - i18n-values="aria-label:CHANGE_TO_THUMBNAILVIEW_BUTTON_LABEL" - has-tooltip> - <files-ripple></files-ripple> - <div class="icon"></div> - </button> - <button id="sort-button" class="icon-button menu-button" tabindex="18" - menu="#sort-menu" - i18n-values="aria-label:SORT_BUTTON_TOOLTIP" - aria-activedescendant="sort-menu" - has-tooltip> - <files-toggle-ripple></files-toggle-ripple> - <div class="icon"></div> - </button> - <button id="gear-button" class="icon-button menu-button" tabindex="19" - menu="#gear-menu" - i18n-values="aria-label:GEAR_BUTTON_TOOLTIP" - aria-activedescendant="gear-menu" - has-tooltip> - <files-toggle-ripple></files-toggle-ripple> - <div class="icon"></div> - </button> - <button id="selection-menu-button" class="icon-button menu-button" tabindex="19" - menu="#file-context-menu" - i18n-values="aria-label:SELECTION_MENU_BUTTON_TOOLTIP" - aria-activedescendant="file-context-menu" - has-tooltip hidden> - <files-toggle-ripple></files-toggle-ripple> - <div class="icon"></div> - </button> </div> <div id="cloud-import-details" class="hidden" hidden> @@ -459,6 +462,7 @@ Welcome to the new epic photo importer! </div> <div id="list-container"> + <div id="more-actions-info" i18n-content="SEE_MENU_FOR_ACTIONS" hidden></div> <div id="empty-folder" hidden> <div class="image"></div> <span id="empty-folder-label" class="label" i18n-content="EMPTY_FOLDER"></span>
diff --git a/ui/file_manager/gallery/js/background.js b/ui/file_manager/gallery/js/background.js index c4ddb512..d5b9ac2 100644 --- a/ui/file_manager/gallery/js/background.js +++ b/ui/file_manager/gallery/js/background.js
@@ -29,8 +29,8 @@ * Gallery app window wrapper. * @type {!SingletonAppWindowWrapper} */ -var gallery = new SingletonAppWindowWrapper('gallery.html', - windowCreateOptions); +var galleryWrapper = + new SingletonAppWindowWrapper('gallery.html', windowCreateOptions); /** * Opens gallery window. @@ -39,41 +39,46 @@ */ function openGalleryWindow(urls) { return new Promise(function(fulfill, reject) { - util.URLsToEntries(urls).then(function(result) { - fulfill(util.entriesToURLs(result.entries)); - }).catch(reject); - }).then(function(urls) { - if (urls.length === 0) - return Promise.reject('No file to open.'); + util.URLsToEntries(urls) + .then(function(result) { + fulfill(util.entriesToURLs(result.entries)); + }) + .catch(reject); + }) + .then(function(urls) { + if (urls.length === 0) + return Promise.reject('No file to open.'); - // Opens a window. - return new Promise(function(fulfill, reject) { - gallery.launch( - {urls: urls}, - false, - fulfill.bind(null, gallery)); - }).then(function(gallery) { - var galleryDocument = gallery.rawAppWindow.contentWindow.document; - if (galleryDocument.readyState == 'complete') - return gallery; + // Opens a window. + return new Promise(function(fulfill, reject) { + galleryWrapper.launch( + {urls: urls}, false, fulfill.bind(null, galleryWrapper)); + }) + .then(function(galleryWrapper) { + var galleryWrapperDocument = + galleryWrapper.rawAppWindow.contentWindow.document; + if (galleryWrapperDocument.readyState == 'complete') + return galleryWrapper; - return new Promise(function(fulfill, reject) { - galleryDocument.addEventListener( - 'DOMContentLoaded', fulfill.bind(null, gallery)); + return new Promise(function(fulfill, reject) { + galleryWrapperDocument.addEventListener( + 'DOMContentLoaded', fulfill.bind(null, galleryWrapper)); + }); + }); + }) + .then(function(galleryWrapper) { + // If the window is minimized, we need to restore it first. + if (galleryWrapper.rawAppWindow.isMinimized()) + galleryWrapper.rawAppWindow.restore(); + + galleryWrapper.rawAppWindow.show(); + + return galleryWrapper.rawAppWindow.contentWindow.appID; + }) + .catch(function(error) { + console.error('Launch failed' + error.stack || error); + return Promise.reject(error); }); - }); - }).then(function(gallery) { - // If the window is minimized, we need to restore it first. - if (gallery.rawAppWindow.isMinimized()) - gallery.rawAppWindow.restore(); - - gallery.rawAppWindow.show(); - - return gallery.rawAppWindow.contentWindow.appID; - }).catch(function(error) { - console.error('Launch failed' + error.stack || error); - return Promise.reject(error); - }); } background.setLaunchHandler(openGalleryWindow);
diff --git a/ui/file_manager/gallery/js/entry_list_watcher.js b/ui/file_manager/gallery/js/entry_list_watcher.js index 453a29d..35fda26b 100644 --- a/ui/file_manager/gallery/js/entry_list_watcher.js +++ b/ui/file_manager/gallery/js/entry_list_watcher.js
@@ -37,7 +37,6 @@ /** * Obtains entry from ArrayDataModel's item. * @param {*} item Item in ArrayDataModel. - * @protected * @return {!FileEntry} */ EntryListWatcher.prototype.getEntry = function(item) {
diff --git a/ui/file_manager/gallery/js/image_editor/image_editor_mode.js b/ui/file_manager/gallery/js/image_editor/image_editor_mode.js index 64b02d62a..b7914ac7 100644 --- a/ui/file_manager/gallery/js/image_editor/image_editor_mode.js +++ b/ui/file_manager/gallery/js/image_editor/image_editor_mode.js
@@ -40,13 +40,11 @@ /** * @type {Viewport} - * @private */ this.viewport_ = null; /** * @type {HTMLElement} - * @private */ this.button_ = null; @@ -58,7 +56,6 @@ /** * @type {boolean} - * @private */ this.updated_ = false; @@ -67,7 +64,7 @@ * @private */ this.imageView_ = null; -}; +} ImageEditorMode.prototype = { __proto__: ImageBuffer.Overlay.prototype
diff --git a/ui/file_manager/gallery/js/image_editor/image_view.js b/ui/file_manager/gallery/js/image_editor/image_view.js index a75282d7..6333f02 100644 --- a/ui/file_manager/gallery/js/image_editor/image_view.js +++ b/ui/file_manager/gallery/js/image_editor/image_view.js
@@ -666,7 +666,6 @@ * transformation. * @param {ImageView.Effect=} opt_effect The effect to apply. * @param {number=} opt_duration Transition duration. - * @private */ ImageView.prototype.setTransform_ = function( element, viewport, opt_effect, opt_duration) {
diff --git a/ui/file_manager/integration_tests/audio_player/background.js b/ui/file_manager/integration_tests/audio_player/background.js index 2638afc..973a752 100644 --- a/ui/file_manager/integration_tests/audio_player/background.js +++ b/ui/file_manager/integration_tests/audio_player/background.js
@@ -56,24 +56,29 @@ */ var testcase = {}; -// Ensure the test cases are loaded. +/** + * When the FileManagerBrowserTest harness loads this test extension, request + * configuration and other details from that harness, including the test case + * name to run. Use the configuration/details to setup the test ennvironment, + * then run the test case using chrome.test.RunTests. + */ window.addEventListener('load', function() { var steps = [ - // Check for the guest mode. + // Request the guest mode state. function() { chrome.test.sendMessage( JSON.stringify({name: 'isInGuestMode'}), steps.shift()); }, - // Obtain the test case name. - function(result) { - if (JSON.parse(result) != chrome.extension.inIncognitoContext) + // Request the root entry paths. + function(mode) { + if (JSON.parse(mode) != chrome.extension.inIncognitoContext) return; chrome.test.sendMessage( JSON.stringify({name: 'getRootPaths'}), steps.shift()); }, - // Obtain the root entry paths. - function(result) { - var roots = JSON.parse(result); + // Request the test case name. + function(paths) { + var roots = JSON.parse(paths); RootPath.DOWNLOADS = roots.downloads; RootPath.DRIVE = roots.drive; chrome.test.sendMessage( @@ -81,16 +86,23 @@ }, // Run the test case. function(testCaseName) { - var targetTest = testcase[testCaseName]; - if (!targetTest) { - chrome.test.fail(testCaseName + ' is not found.'); + // Get the test function from testcase namespace testCaseName. + var test = testcase[testCaseName]; + // Verify test is an unnamed (aka 'anonymous') Function. + if (!test instanceof Function || test.name) { + chrome.test.fail('[' + testCaseName + '] not found.'); return; } - // Specify the name of test to the test system. - targetTest.generatedName = testCaseName; - chrome.test.runTests([function() { - return testPromiseAndApps(targetTest(), [remoteCallAudioPlayer]); - }]); + // Define the test case and its name for chrome.test logging. + test.generatedName = testCaseName; + var testCaseSymbol = Symbol(testCaseName); + var testCase = { + [testCaseSymbol] :() => { + return testPromiseAndApps(test(), [remoteCallAudioPlayer]); + }, + }; + // Run the test. + chrome.test.runTests([testCase[testCaseSymbol]]); } ]; steps.shift()();
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js index 0d1837a..ed671c1 100644 --- a/ui/file_manager/integration_tests/file_manager/background.js +++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -374,24 +374,29 @@ */ var testcase = {}; -// Ensure the test cases are loaded. +/** + * When the FileManagerBrowserTest harness loads this test extension, request + * configuration and other details from that harness, including the test case + * name to run. Use the configuration/details to setup the test ennvironment, + * then run the test case using chrome.test.RunTests. + */ window.addEventListener('load', function() { var steps = [ - // Check for the guest mode. + // Request the guest mode state. function() { chrome.test.sendMessage( JSON.stringify({name: 'isInGuestMode'}), steps.shift()); }, - // Obtain the test case name. - function(result) { - if (JSON.parse(result) != chrome.extension.inIncognitoContext) + // Request the root entry paths. + function(mode) { + if (JSON.parse(mode) != chrome.extension.inIncognitoContext) return; chrome.test.sendMessage( JSON.stringify({name: 'getRootPaths'}), steps.shift()); }, - // Obtain the root entry paths. - function(result) { - var roots = JSON.parse(result); + // Request the test case name. + function(paths) { + var roots = JSON.parse(paths); RootPath.DOWNLOADS = roots.downloads; RootPath.DRIVE = roots.drive; chrome.test.sendMessage( @@ -399,14 +404,23 @@ }, // Run the test case. function(testCaseName) { - var targetTest = testcase[testCaseName]; - if (!targetTest) { - chrome.test.fail(testCaseName + ' is not found.'); + // Get the test function from testcase namespace testCaseName. + var test = testcase[testCaseName]; + // Verify test is an unnamed (aka 'anonymous') Function. + if (!test instanceof Function || test.name) { + chrome.test.fail('[' + testCaseName + '] not found.'); return; } - // Specify the name of test to the test system. - targetTest.generatedName = testCaseName; - chrome.test.runTests([targetTest]); + // Define the test case and its name for chrome.test logging. + test.generatedName = testCaseName; + var testCaseSymbol = Symbol(testCaseName); + var testCase = { + [testCaseSymbol] :() => { + return test(); + }, + }; + // Run the test. + chrome.test.runTests([testCase[testCaseSymbol]]); } ]; steps.shift()();
diff --git a/ui/file_manager/integration_tests/file_manager/providers.js b/ui/file_manager/integration_tests/file_manager/providers.js index 04b8c26f..d61eb15 100644 --- a/ui/file_manager/integration_tests/file_manager/providers.js +++ b/ui/file_manager/integration_tests/file_manager/providers.js
@@ -175,27 +175,34 @@ ]); } -function requestMount() { - requestMountInternal(false /* multipleMounts */, 'manifest.json'); -} +/** + * Tests mounting a single mount point in the button menu. + */ +testcase.requestMount = function() { + const multipleMounts = false; + requestMountInternal(multipleMounts, 'manifest.json'); +}; -function requestMountMultipleMounts() { - requestMountInternal( - true /* multipleMounts */, 'manifest_multiple_mounts.json'); -} +/** + * Tests mounting multiple mount points in the button menu. + */ +testcase.requestMountMultipleMounts = function() { + const multipleMounts = true; + requestMountInternal(multipleMounts, 'manifest_multiple_mounts.json'); +}; -function requestMountSourceDevice() { +/** + * Tests mounting a device not present in the button menu. + */ +testcase.requestMountSourceDevice = function() { requestMountNotInMenuInternal('manifest_source_device.json'); -} +}; -function requestMountSourceFile() { +/** + * Tests mounting a file not present in the button menu. + */ +testcase.requestMountSourceFile = function() { requestMountNotInMenuInternal('manifest_source_file.json'); -} - -// Exports test functions. -testcase.requestMount = requestMount; -testcase.requestMountMultipleMounts = requestMountMultipleMounts; -testcase.requestMountSourceDevice = requestMountSourceDevice; -testcase.requestMountSourceFile = requestMountSourceFile; +}; })();
diff --git a/ui/file_manager/integration_tests/file_manager/transfer.js b/ui/file_manager/integration_tests/file_manager/transfer.js index 8806cf1..bc5f1668 100644 --- a/ui/file_manager/integration_tests/file_manager/transfer.js +++ b/ui/file_manager/integration_tests/file_manager/transfer.js
@@ -96,68 +96,82 @@ ]); } -/** - * Tests copy from drive's root to local's downloads. - */ -testcase.transferFromDriveToDownloads = copyBetweenVolumes.bind( - null, - ENTRIES.hello, - 'drive', - BASIC_DRIVE_ENTRY_SET, - 'downloads', - BASIC_LOCAL_ENTRY_SET); +// TODO(noel): transfer implies move to some. Change these test names to say +// "copy" rather than "transfer" because all these tests copy something from +// a volume to another volume. /** - * Tests copy from local's downloads to drive's root. + * Tests copying from Drive to Downloads. */ -testcase.transferFromDownloadsToDrive = copyBetweenVolumes.bind( - null, - ENTRIES.hello, - 'downloads', - BASIC_LOCAL_ENTRY_SET, - 'drive', - BASIC_DRIVE_ENTRY_SET); +testcase.transferFromDriveToDownloads = function() { + copyBetweenVolumes( + ENTRIES.hello, + 'drive', + BASIC_DRIVE_ENTRY_SET, + 'downloads', + BASIC_LOCAL_ENTRY_SET); +}; /** - * Tests copy from drive's shared_with_me to local's downloads. + * Tests copying from Downloads to Drive. */ -testcase.transferFromSharedToDownloads = copyBetweenVolumes.bind( - null, - ENTRIES.testSharedDocument, - 'drive_shared_with_me', - SHARED_WITH_ME_ENTRY_SET, - 'downloads', - BASIC_LOCAL_ENTRY_SET); +testcase.transferFromDownloadsToDrive = function() { + copyBetweenVolumes( + ENTRIES.hello, + 'downloads', + BASIC_LOCAL_ENTRY_SET, + 'drive', + BASIC_DRIVE_ENTRY_SET); +}; /** - * Tests copy from drive's shared_with_me to drive's root. + * Tests copying from Drive shared with me to Downloads. + * TODO(noel) naming: ...fromDriveSharedToDownloads? */ -testcase.transferFromSharedToDrive = copyBetweenVolumes.bind( - null, - ENTRIES.testSharedDocument, - 'drive_shared_with_me', - SHARED_WITH_ME_ENTRY_SET, - 'drive', - BASIC_DRIVE_ENTRY_SET); +testcase.transferFromSharedToDownloads = function() { + copyBetweenVolumes( + ENTRIES.testSharedDocument, + 'drive_shared_with_me', + SHARED_WITH_ME_ENTRY_SET, + 'downloads', + BASIC_LOCAL_ENTRY_SET); +}; /** - * Tests copy from drive's offline to local's downloads. + * Tests copying from Drive shared with me to Drive. + * TODO(noel) naming: ...fromDriveSharedToDrive? */ -testcase.transferFromOfflineToDownloads = copyBetweenVolumes.bind( - null, - ENTRIES.testDocument, - 'drive_offline', - OFFLINE_ENTRY_SET, - 'downloads', - BASIC_LOCAL_ENTRY_SET); +testcase.transferFromSharedToDrive = function() { + copyBetweenVolumes( + ENTRIES.testSharedDocument, + 'drive_shared_with_me', + SHARED_WITH_ME_ENTRY_SET, + 'drive', + BASIC_DRIVE_ENTRY_SET); +}; /** - * Tests copy from drive's offline to drive's root. + * Tests copying from Drive offline to Downloads. + * TODO(noel) naming: ...fromDriveOfflineToDownloads? */ -testcase.transferFromOfflineToDrive = copyBetweenVolumes.bind( - null, - ENTRIES.testDocument, - 'drive_offline', - OFFLINE_ENTRY_SET, - 'drive', - BASIC_DRIVE_ENTRY_SET); +testcase.transferFromOfflineToDownloads = function() { + copyBetweenVolumes( + ENTRIES.testDocument, + 'drive_offline', + OFFLINE_ENTRY_SET, + 'downloads', + BASIC_LOCAL_ENTRY_SET); +}; + +/** + * Tests copying from Drive offline to Drive. + * TODO(noel): naming: ...fromDriveOfflinetoDrive? + */ +testcase.transferFromOfflineToDrive = function() { + copyBetweenVolumes( + ENTRIES.testDocument, + 'drive_offline', + OFFLINE_ENTRY_SET, + 'drive', + BASIC_DRIVE_ENTRY_SET); +};
diff --git a/ui/file_manager/integration_tests/gallery/background.js b/ui/file_manager/integration_tests/gallery/background.js index ffaba3de..41def38 100644 --- a/ui/file_manager/integration_tests/gallery/background.js +++ b/ui/file_manager/integration_tests/gallery/background.js
@@ -58,24 +58,29 @@ */ var testcase = {}; -// Ensure the test cases are loaded. +/** + * When the FileManagerBrowserTest harness loads this test extension, request + * configuration and other details from that harness, including the test case + * name to run. Use the configuration/details to setup the test ennvironment, + * then run the test case using chrome.test.RunTests. + */ window.addEventListener('load', function() { var steps = [ - // Check for the guest mode. + // Request the guest mode state. function() { chrome.test.sendMessage( JSON.stringify({name: 'isInGuestMode'}), steps.shift()); }, - // Obtain the test case name. - function(result) { - if (JSON.parse(result) != chrome.extension.inIncognitoContext) + // Request the root entry paths. + function(mode) { + if (JSON.parse(mode) != chrome.extension.inIncognitoContext) return; chrome.test.sendMessage( JSON.stringify({name: 'getRootPaths'}), steps.shift()); }, - // Obtain the root entry paths. - function(result) { - var roots = JSON.parse(result); + // Request the test case name. + function(paths) { + var roots = JSON.parse(paths); RootPath.DOWNLOADS = roots.downloads; RootPath.DRIVE = roots.drive; chrome.test.sendMessage( @@ -83,16 +88,23 @@ }, // Run the test case. function(testCaseName) { - var targetTest = testcase[testCaseName]; - if (!targetTest) { - chrome.test.fail(testCaseName + ' is not found.'); + // Get the test function from testcase namespace testCaseName. + var test = testcase[testCaseName]; + // Verify test is an unnamed (aka 'anonymous') Function. + if (!test instanceof Function || test.name) { + chrome.test.fail('[' + testCaseName + '] not found.'); return; } - // Specify the name of test to the test system. - targetTest.generatedName = testCaseName; - chrome.test.runTests([function() { - return testPromiseAndApps(targetTest(), [gallery]); - }]); + // Define the test case and its name for chrome.test logging. + test.generatedName = testCaseName; + var testCaseSymbol = Symbol(testCaseName); + var testCase = { + [testCaseSymbol] :() => { + return testPromiseAndApps(test(), [gallery]); + }, + }; + // Run the test. + chrome.test.runTests([testCase[testCaseSymbol]]); } ]; steps.shift()();
diff --git a/ui/file_manager/integration_tests/video_player/background.js b/ui/file_manager/integration_tests/video_player/background.js index 2ff6007c..76f9f04d 100644 --- a/ui/file_manager/integration_tests/video_player/background.js +++ b/ui/file_manager/integration_tests/video_player/background.js
@@ -72,31 +72,36 @@ chrome.test.assertFalse('disabled' in videoPlayer.attributes); return args; }); -}; +} /** * Namespace for test cases. */ var testcase = {}; -// Ensure the test cases are loaded. +/** + * When the FileManagerBrowserTest harness loads this test extension, request + * configuration and other details from that harness, including the test case + * name to run. Use the configuration/details to setup the test ennvironment, + * then run the test case using chrome.test.RunTests. + */ window.addEventListener('load', function() { var steps = [ - // Check for the guest mode. + // Request the guest mode state. function() { chrome.test.sendMessage( JSON.stringify({name: 'isInGuestMode'}), steps.shift()); }, - // Obtain the test case name. - function(result) { - if (JSON.parse(result) != chrome.extension.inIncognitoContext) + // Request the root entry paths. + function(mode) { + if (JSON.parse(mode) != chrome.extension.inIncognitoContext) return; chrome.test.sendMessage( JSON.stringify({name: 'getRootPaths'}), steps.shift()); }, - // Obtain the root entry paths. - function(result) { - var roots = JSON.parse(result); + // Request the test case name. + function(paths) { + var roots = JSON.parse(paths); RootPath.DOWNLOADS = roots.downloads; RootPath.DRIVE = roots.drive; chrome.test.sendMessage( @@ -104,16 +109,23 @@ }, // Run the test case. function(testCaseName) { - var targetTest = testcase[testCaseName]; - if (!targetTest) { - chrome.test.fail(testCaseName + ' is not found.'); + // Get the test function from testcase namespace testCaseName. + var test = testcase[testCaseName]; + // Verify test is an unnamed (aka 'anonymous') Function. + if (!test instanceof Function || test.name) { + chrome.test.fail('[' + testCaseName + '] not found.'); return; } - // Specify the name of test to the test system. - targetTest.generatedName = testCaseName; - chrome.test.runTests([function() { - return testPromiseAndApps(targetTest(), [remoteCallVideoPlayer]); - }]); + // Define the test case and its name for chrome.test logging. + test.generatedName = testCaseName; + var testCaseSymbol = Symbol(testCaseName); + var testCase = { + [testCaseSymbol] :() => { + return testPromiseAndApps(test(), [remoteCallVideoPlayer]); + }, + }; + // Run the test. + chrome.test.runTests([testCase[testCaseSymbol]]); } ]; steps.shift()();
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index aa5a3de..4230f62 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -284,7 +284,7 @@ } TEST(SimpleColorSpace, ICCProfileOnlyColorSpin) { - const float kEpsilon = 2.5f / 255.f; + const float kEpsilon = 3.0f / 255.f; ICCProfile icc_profile = ICCProfileForTestingNoAnalyticTrFn(); ColorSpace icc_space = icc_profile.GetColorSpace(); ColorSpace colorspin =
diff --git a/ui/gfx/paint_vector_icon.cc b/ui/gfx/paint_vector_icon.cc index d2968ffe..b60aab1 100644 --- a/ui/gfx/paint_vector_icon.cc +++ b/ui/gfx/paint_vector_icon.cc
@@ -4,6 +4,7 @@ #include "ui/gfx/paint_vector_icon.h" +#include <algorithm> #include <map> #include <tuple> @@ -27,6 +28,30 @@ namespace { +// Retrieves the specified CANVAS_DIMENSIONS size from a PathElement. +int GetCanvasDimensions(const PathElement* path) { + if (!path) + return kReferenceSizeDip; + return path[0].command == CANVAS_DIMENSIONS ? path[1].arg : kReferenceSizeDip; +} + +// Retrieves the appropriate icon representation to draw when the pixel size +// requested is |icon_size_px|. VectorIconReps may only be downscaled, not +// upscaled (with the exception of the largest VectorIconRep), so the return +// result will be the smallest VectorIconRep greater or equal to |icon_size_px|. +const VectorIconRep* GetRepForPxSize(const VectorIcon& icon, int icon_size_px) { + if (icon.is_empty()) + return nullptr; + + // Since |VectorIcon::reps| is sorted in descending order by size, search in + // reverse order for an icon that is equal to or greater than |icon_size_px|. + for (int i = icon.reps_size - 1; i >= 0; --i) { + if (GetCanvasDimensions(icon.reps[i].path) >= icon_size_px) + return &icon.reps[i]; + } + return &icon.reps[0]; +} + struct CompareIconDescription { bool operator()(const IconDescription& a, const IconDescription& b) const { const VectorIcon* a_icon = &a.icon; @@ -534,11 +559,6 @@ badge_icon(badge_icon) { if (dip_size == 0) this->dip_size = GetDefaultSizeOfVectorIcon(icon); - - // If an icon has a .1x.icon version, it should only be rendered at the size - // specified in that definition. - if (icon.rep_1x) - DCHECK_EQ(this->dip_size, GetDefaultSizeOfVectorIcon(icon)); } IconDescription::~IconDescription() {} @@ -559,12 +579,10 @@ SkColor color, const base::TimeDelta& elapsed_time) { DCHECK(!icon.is_empty()); - if (icon.rep) - DCHECK(icon.rep->path_size > 0); - if (icon.rep_1x) - DCHECK(icon.rep_1x->path_size > 0); - const VectorIconRep* rep = - (canvas->image_scale() == 1.f && icon.rep_1x) ? icon.rep_1x : icon.rep; + for (size_t i = 0; i < icon.reps_size; ++i) + DCHECK(icon.reps[i].path_size > 0); + const int px_size = gfx::ToCeiledInt(canvas->image_scale() * dip_size); + const VectorIconRep* rep = GetRepForPxSize(icon, px_size); PaintPath(canvas, rep->path, rep->path_size, dip_size, color, elapsed_time); } @@ -602,15 +620,15 @@ } int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) { - const PathElement* one_x_path = - icon.rep_1x ? icon.rep_1x->path : icon.rep->path; - return one_x_path[0].command == CANVAS_DIMENSIONS ? one_x_path[1].arg - : kReferenceSizeDip; + if (icon.is_empty()) + return -1; + const PathElement* default_icon_path = icon.reps[icon.reps_size - 1].path; + return GetCanvasDimensions(default_icon_path); } base::TimeDelta GetDurationOfAnimation(const VectorIcon& icon) { base::TimeDelta last_motion; - for (PathParser parser(icon.rep->path, icon.rep->path_size); + for (PathParser parser(icon.reps[0].path, icon.reps[0].path_size); parser.HasCommandsRemaining(); parser.Advance()) { if (parser.CurrentCommand() != TRANSITION_END) continue;
diff --git a/ui/gfx/paint_vector_icon.h b/ui/gfx/paint_vector_icon.h index b953dce1..2c6871b 100644 --- a/ui/gfx/paint_vector_icon.h +++ b/ui/gfx/paint_vector_icon.h
@@ -86,7 +86,8 @@ SkColor color); #endif -// Calculates the size that will be default for |icon|, in dip. +// Calculates the size that will be default for |icon|, in dip. This will be the +// smallest icon size |icon| contains. GFX_EXPORT int GetDefaultSizeOfVectorIcon(const gfx::VectorIcon& icon); // Calculates and returns the elapsed time at which all animations/transitions
diff --git a/ui/gfx/paint_vector_icon_unittest.cc b/ui/gfx/paint_vector_icon_unittest.cc index 1188c35e..b472dff7 100644 --- a/ui/gfx/paint_vector_icon_unittest.cc +++ b/ui/gfx/paint_vector_icon_unittest.cc
@@ -19,6 +19,10 @@ namespace { +SkColor GetColorAtTopLeft(const Canvas& canvas) { + return canvas.GetBitmap().getColor(0, 0); +} + class MockCanvas : public SkCanvas { public: MockCanvas(int width, int height) : SkCanvas(width, height) {} @@ -46,8 +50,8 @@ MOVE_TO, 4, 5, LINE_TO, 10, 11, CLOSE, // This move should use (4, 5) as the start point rather than (10, 11). R_MOVE_TO, 20, 21, R_LINE_TO, 50, 51}; - const VectorIconRep icon_rep = {elements, arraysize(elements)}; - const VectorIcon icon = {&icon_rep}; + const VectorIconRep rep_list[] = {{elements, arraysize(elements)}}; + const VectorIcon icon = {rep_list, 1u}; PaintVectorIcon(&canvas, icon, 100, SK_ColorMAGENTA); sk_sp<cc::PaintRecord> record = recorder.finishRecordingAsPicture(); @@ -87,8 +91,8 @@ R_H_LINE_TO, -20, CLOSE}; - const VectorIconRep icon_rep = {elements, arraysize(elements)}; - const VectorIcon icon = {&icon_rep}; + const VectorIconRep rep_list[] = {{elements, arraysize(elements)}}; + const VectorIcon icon = {rep_list, 1u}; PaintVectorIcon(&canvas, icon, canvas_size, color); // Count the number of pixels in the canvas. @@ -107,6 +111,173 @@ EXPECT_EQ(100, colored_pixel_count); } +TEST(VectorIconTest, CorrectSizePainted) { + // Create a set of 5 icons reps, sized {48, 32, 24, 20, 16} for the test icon. + // Color each of them differently so they can be differentiated (the parts of + // an icon painted with PATH_COLOR_ARGB will not be overwritten by the color + // provided to it at creation time). + // SK_ColorRED. + const PathElement elements48[] = {CANVAS_DIMENSIONS, + 48, + PATH_COLOR_ARGB, + 0xFF, + 0xFF, + 0x00, + 0x00, + MOVE_TO, + 0, + 0, + H_LINE_TO, + 48, + V_LINE_TO, + 48, + H_LINE_TO, + 0, + V_LINE_TO, + 0, + CLOSE}; + // SK_ColorGREEN. + const PathElement elements32[] = {CANVAS_DIMENSIONS, + 32, + PATH_COLOR_ARGB, + 0xFF, + 0x00, + 0xFF, + 0x00, + MOVE_TO, + 0, + 0, + H_LINE_TO, + 32, + V_LINE_TO, + 32, + H_LINE_TO, + 0, + V_LINE_TO, + 0, + CLOSE}; + // SK_ColorBLUE. + const PathElement elements24[] = {CANVAS_DIMENSIONS, + 24, + PATH_COLOR_ARGB, + 0xFF, + 0x00, + 0x00, + 0xFF, + MOVE_TO, + 0, + 0, + H_LINE_TO, + 24, + V_LINE_TO, + 24, + H_LINE_TO, + 0, + V_LINE_TO, + 0, + CLOSE}; + // SK_ColorYELLOW. + const PathElement elements20[] = {CANVAS_DIMENSIONS, + 20, + PATH_COLOR_ARGB, + 0xFF, + 0xFF, + 0xFF, + 0x00, + MOVE_TO, + 0, + 0, + H_LINE_TO, + 20, + V_LINE_TO, + 20, + H_LINE_TO, + 0, + V_LINE_TO, + 0, + CLOSE}; + // SK_ColorCYAN. + const PathElement elements16[] = {CANVAS_DIMENSIONS, + 16, + PATH_COLOR_ARGB, + 0xFF, + 0x00, + 0xFF, + 0xFF, + MOVE_TO, + 0, + 0, + H_LINE_TO, + 16, + V_LINE_TO, + 16, + H_LINE_TO, + 0, + V_LINE_TO, + 0, + CLOSE}; + // VectorIconReps are always sorted in descending order of size. + const VectorIconRep rep_list[] = {{elements48, arraysize(elements48)}, + {elements32, arraysize(elements32)}, + {elements24, arraysize(elements24)}, + {elements20, arraysize(elements20)}, + {elements16, arraysize(elements16)}}; + const VectorIcon icon = {rep_list, 5u}; + + // Test exact sizes paint the correctly sized icon, including the largest and + // smallest icon. + Canvas canvas_100(gfx::Size(100, 100), 1.0, true); + PaintVectorIcon(&canvas_100, icon, 48, SK_ColorBLACK); + EXPECT_EQ(SK_ColorRED, GetColorAtTopLeft(canvas_100)); + PaintVectorIcon(&canvas_100, icon, 32, SK_ColorBLACK); + EXPECT_EQ(SK_ColorGREEN, GetColorAtTopLeft(canvas_100)); + PaintVectorIcon(&canvas_100, icon, 16, SK_ColorBLACK); + EXPECT_EQ(SK_ColorCYAN, GetColorAtTopLeft(canvas_100)); + + // Only the largest icon may be upscaled to a size larger than what it was + // designed for. + PaintVectorIcon(&canvas_100, icon, 50, SK_ColorBLACK); + EXPECT_EQ(SK_ColorRED, GetColorAtTopLeft(canvas_100)); + + // All other icons may never be upscaled. + PaintVectorIcon(&canvas_100, icon, 27, SK_ColorBLACK); + EXPECT_EQ(SK_ColorGREEN, GetColorAtTopLeft(canvas_100)); + PaintVectorIcon(&canvas_100, icon, 8, SK_ColorBLACK); + EXPECT_EQ(SK_ColorCYAN, GetColorAtTopLeft(canvas_100)); + + // Test icons at a scale factor < 100%, still with an exact size, paint the + // correctly sized icon. + Canvas canvas_75(gfx::Size(100, 100), 0.75, true); + PaintVectorIcon(&canvas_75, icon, 32, SK_ColorBLACK); // 32 * 0.75 = 24. + EXPECT_EQ(SK_ColorBLUE, GetColorAtTopLeft(canvas_75)); + + // Test icons at a scale factor > 100%, still with an exact size, paint the + // correctly sized icon. + Canvas canvas_125(gfx::Size(100, 100), 1.25, true); + PaintVectorIcon(&canvas_125, icon, 16, SK_ColorBLACK); // 16 * 1.25 = 20. + EXPECT_EQ(SK_ColorYELLOW, GetColorAtTopLeft(canvas_125)); + + // Inexact sizes at scale factors < 100%. + PaintVectorIcon(&canvas_75, icon, 12, SK_ColorBLACK); // 12 * 0.75 = 9. + EXPECT_EQ(SK_ColorCYAN, GetColorAtTopLeft(canvas_75)); + PaintVectorIcon(&canvas_75, icon, 28, SK_ColorBLACK); // 28 * 0.75 = 21. + EXPECT_EQ(SK_ColorBLUE, GetColorAtTopLeft(canvas_75)); + + // Inexact sizes at scale factors > 100%. + PaintVectorIcon(&canvas_125, icon, 12, SK_ColorBLACK); // 12 * 1.25 = 15. + EXPECT_EQ(SK_ColorCYAN, GetColorAtTopLeft(canvas_125)); + PaintVectorIcon(&canvas_125, icon, 28, SK_ColorBLACK); // 28 * 1.25 = 35. + EXPECT_EQ(SK_ColorRED, GetColorAtTopLeft(canvas_125)); + + // Painting without a requested size will default to the smallest icon rep. + PaintVectorIcon(&canvas_100, icon, SK_ColorBLACK); + EXPECT_EQ(SK_ColorCYAN, GetColorAtTopLeft(canvas_100)); + // But doing this in another scale factor should assume the smallest icon rep + // size, then scale it up by the DSF. + PaintVectorIcon(&canvas_125, icon, SK_ColorBLACK); // 16 * 1.25 = 20. + EXPECT_EQ(SK_ColorYELLOW, GetColorAtTopLeft(canvas_125)); +} + } // namespace } // namespace gfx
diff --git a/ui/gfx/vector_icon_types.h b/ui/gfx/vector_icon_types.h index e03aa126..195de85a 100644 --- a/ui/gfx/vector_icon_types.h +++ b/ui/gfx/vector_icon_types.h
@@ -95,10 +95,10 @@ struct VectorIcon { VectorIcon() = default; - bool is_empty() const { return !rep; } + bool is_empty() const { return !reps; } - const VectorIconRep* rep = nullptr; - const VectorIconRep* rep_1x = nullptr; + const VectorIconRep* const reps = nullptr; + size_t reps_size = 0u; // A human-readable name, useful for debugging, derived from the name of the // icon file. This can also be used as an identifier, but vector icon targets
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc index cfca601..5a76f78 100644 --- a/ui/gl/gl_surface_glx.cc +++ b/ui/gl/gl_surface_glx.cc
@@ -419,7 +419,7 @@ return false; } - int major, minor; + int major = 0, minor = 0; if (!glXQueryVersion(gfx::GetXDisplay(), &major, &minor)) { LOG(ERROR) << "glxQueryVersion failed"; return false;
diff --git a/ui/surface/BUILD.gn b/ui/surface/BUILD.gn index 6f171275..2790a3d 100644 --- a/ui/surface/BUILD.gn +++ b/ui/surface/BUILD.gn
@@ -10,7 +10,6 @@ "surface_export.h", "transport_dib.cc", "transport_dib.h", - "transport_dib_posix.cc", "transport_dib_win.cc", ] @@ -26,4 +25,8 @@ "//ui/gfx/geometry", "//ui/gl", ] + + if (is_posix) { + sources += [ "transport_dib_posix.cc" ] + } }
diff --git a/ui/views/accessibility/native_view_accessibility_base.cc b/ui/views/accessibility/native_view_accessibility_base.cc index e895c9d..c3ae609 100644 --- a/ui/views/accessibility/native_view_accessibility_base.cc +++ b/ui/views/accessibility/native_view_accessibility_base.cc
@@ -291,8 +291,9 @@ } void NativeViewAccessibilityBase::OnAutofillHidden() { - DCHECK(fake_focus_view_id_ == GetUniqueId().Get()) - << "Cannot clear fake focus on an object that did not have fake focus."; + DCHECK(fake_focus_view_id_) << "No autofill fake focus set."; + DCHECK_EQ(fake_focus_view_id_, GetUniqueId().Get()) + << "Cannot clear autofill fake focus on an object that did not have it."; fake_focus_view_id_ = 0; ui::AXPlatformNode::OnAutofillHidden(); }
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index fd0748f..5021792 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc
@@ -134,7 +134,7 @@ ImageButton* close_button = nullptr; if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { close_button = CreateVectorImageButton(listener); - SetImageFromVectorIcon(close_button, vector_icons::kClose16Icon); + SetImageFromVectorIcon(close_button, vector_icons::kCloseRoundedIcon); } else { ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); close_button = new ImageButton(listener);
diff --git a/ui/views/controls/button/image_button_factory_unittest.cc b/ui/views/controls/button/image_button_factory_unittest.cc index 52728ff3..6a2e776d 100644 --- a/ui/views/controls/button/image_button_factory_unittest.cc +++ b/ui/views/controls/button/image_button_factory_unittest.cc
@@ -26,14 +26,14 @@ TEST_F(ImageButtonFactoryTest, SetImageFromVectorIcon) { ImageButton* button = CreateVectorImageButton(nullptr); - SetImageFromVectorIcon(button, vector_icons::kClose16Icon, SK_ColorRED); + SetImageFromVectorIcon(button, vector_icons::kCloseRoundedIcon, SK_ColorRED); EXPECT_FALSE(button->GetImage(Button::STATE_NORMAL).isNull()); EXPECT_FALSE(button->GetImage(Button::STATE_DISABLED).isNull()); EXPECT_EQ(color_utils::DeriveDefaultIconColor(SK_ColorRED), button->GetInkDropBaseColor()); // Default to GoogleGrey900. - SetImageFromVectorIcon(button, vector_icons::kClose16Icon); + SetImageFromVectorIcon(button, vector_icons::kCloseRoundedIcon); EXPECT_EQ(color_utils::DeriveDefaultIconColor(gfx::kGoogleGrey900), button->GetInkDropBaseColor()); delete button;
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc index 7129685..97d9260d 100644 --- a/ui/views/focus/focus_manager.cc +++ b/ui/views/focus/focus_manager.cc
@@ -345,6 +345,9 @@ for (FocusChangeListener& observer : focus_change_listeners_) observer.OnDidChangeFocus(old_focused_view, focused_view_); + + if (delegate_) + delegate_->OnDidChangeFocus(old_focused_view, focused_view_); } void FocusManager::ClearFocus() {
diff --git a/ui/views/focus/focus_manager_delegate.h b/ui/views/focus/focus_manager_delegate.h index a4d9186..c57571b 100644 --- a/ui/views/focus/focus_manager_delegate.h +++ b/ui/views/focus/focus_manager_delegate.h
@@ -13,6 +13,8 @@ namespace views { +class View; + // Delegate interface for views::FocusManager. class VIEWS_EXPORT FocusManagerDelegate { public: @@ -25,6 +27,9 @@ // target, and so on. // Returns true if an accelerator was activated. virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) = 0; + + // Called after focus state has changed. + virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0; }; } // namespace views
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index 3e88b8d..739e5e5 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -42,11 +42,6 @@ creation_time_ = base::TimeTicks::Now(); } -DialogDelegate::~DialogDelegate() { - UMA_HISTOGRAM_LONG_TIMES("Dialog.DialogDelegate.Duration", - base::TimeTicks::Now() - creation_time_); -} - // static Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate, gfx::NativeWindow context, @@ -249,6 +244,11 @@ observer.OnDialogModelChanged(); } +DialogDelegate::~DialogDelegate() { + UMA_HISTOGRAM_LONG_TIMES("Dialog.DialogDelegate.Duration", + base::TimeTicks::Now() - creation_time_); +} + ax::mojom::Role DialogDelegate::GetAccessibleWindowRole() const { return ax::mojom::Role::kDialog; }
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 69add25..83019bb 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h
@@ -35,7 +35,6 @@ public WidgetDelegate { public: DialogDelegate(); - ~DialogDelegate() override; // Creates a widget at a default location. static Widget* CreateDialogWidget(WidgetDelegate* delegate, @@ -129,6 +128,8 @@ void DialogModelChanged(); protected: + ~DialogDelegate() override; + // Overridden from WidgetDelegate: ax::mojom::Role GetAccessibleWindowRole() const override;
diff --git a/ui/webui/resources/js/cr/ui/dialogs.js b/ui/webui/resources/js/cr/ui/dialogs.js index 96693e0..089e0b6 100644 --- a/ui/webui/resources/js/cr/ui/dialogs.js +++ b/ui/webui/resources/js/cr/ui/dialogs.js
@@ -35,7 +35,7 @@ */ BaseDialog.ANIMATE_STABLE_DURATION = 500; - /** @private */ + /** @protected */ BaseDialog.prototype.initDom_ = function() { var doc = this.document_; this.container_ = doc.createElement('div'); @@ -94,7 +94,7 @@ /** @private {Function|undefined} */ BaseDialog.prototype.onCancel_ = null; - /** @private */ + /** @protected */ BaseDialog.prototype.onContainerKeyDown_ = function(event) { // Handle Escape. if (event.keyCode == 27 && !this.cancelButton_.disabled) {
diff --git a/ui/webui/resources/js/cr/ui/list.js b/ui/webui/resources/js/cr/ui/list.js index 6cf92762..f370f0f 100644 --- a/ui/webui/resources/js/cr/ui/list.js +++ b/ui/webui/resources/js/cr/ui/list.js
@@ -873,9 +873,8 @@ * possibility that the lead item may be a different height. * @param {number} index The index to find the top height of. * @return {{top: number, height: number}} The heights for the given index. - * @private */ - getHeightsForIndex_: function(index) { + getHeightsForIndex: function(index) { var itemHeight = this.getItemHeightByIndex_(index); var top = this.getItemTop(index); return {top: top, height: itemHeight}; @@ -901,7 +900,7 @@ // If offset exceeds the height of list. var lastHeight = 0; if (this.dataModel.length) { - var h = this.getHeightsForIndex_(this.dataModel.length - 1); + var h = this.getHeightsForIndex(this.dataModel.length - 1); lastHeight = h.top + h.height; } if (lastHeight < offset) @@ -914,7 +913,7 @@ // Searchs the correct index. do { - var heights = this.getHeightsForIndex_(estimatedIndex); + var heights = this.getHeightsForIndex(estimatedIndex); var top = heights.top; var height = heights.height;
diff --git a/ui/webui/resources/js/cr/ui/splitter.js b/ui/webui/resources/js/cr/ui/splitter.js index b655f5b..4c97d691 100644 --- a/ui/webui/resources/js/cr/ui/splitter.js +++ b/ui/webui/resources/js/cr/ui/splitter.js
@@ -229,7 +229,6 @@ /** * Handles start of the splitter dragging. Saves current width of the * element being resized. - * @protected */ handleSplitterDragStart: function() { // Use the computed width style as the base so that we can ignore what @@ -247,7 +246,6 @@ /** * Handles splitter moves. Updates width of the element being resized. * @param {number} deltaX The change of splitter horizontal position. - * @protected */ handleSplitterDragMove: function(deltaX) { var targetElement = this.getResizeTarget_(); @@ -259,7 +257,6 @@ /** * Handles end of the splitter dragging. This fires a 'resize' event if the * size changed. - * @protected */ handleSplitterDragEnd: function() { // Check if the size changed.