diff --git a/DEPS b/DEPS index 33ef221..c4b0c0f 100644 --- a/DEPS +++ b/DEPS
@@ -112,7 +112,7 @@ # 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': '2ed78209704418aebfb99e858866af249da594c7', + 'skia_revision': '4bff78e57c5457bc3fd01e57ea1a2e1088eefc4b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -124,7 +124,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': '9f379f493cd7a020b9feb09b1ddd1db1f89f9f61', + 'angle_revision': 'efe061bd4f9de0f8da3135bcabff7f40e05e91f7', # 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. @@ -160,7 +160,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': '99673869a3cd8731d924bd32fa486feebfdc6c4f', + 'nacl_revision': 'f701a90597fc85979319447c0cd44c3b52201c78', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -172,7 +172,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'aa21a922d4a8fb32bf9f24a0cfbeec8c2ed1f963', + 'catapult_revision': '4176781039b6d4b8c9fa709d477adcffd15fcca4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -651,7 +651,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1b079a6aacabb49ed9dc8984560d7481f831f5c7', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0d55bcab63bea4816e536ec78c533ec08d8033f9', 'condition': 'checkout_linux', }, @@ -676,7 +676,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd66dad7fc2c3caad80c0117ae0ee625d7367a14a', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '25c4fce2cebbd11987a9eadafdf9258b10efcb7e', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1160,7 +1160,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5b6cbd789b9b91b4e46dde883c9f2ecb31eddade', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e4cccae299411193e0a0fdec9f58f4255429f95a', + Var('webrtc_git') + '/src.git' + '@' + 'af228ee761e1ad927652566bb746684274bbc5b6', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1191,7 +1191,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e89f85283d4c1ab3e270bf8b4848ebb6962c91db', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@eec675da4cadda08240c4241673c6b9747725133', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/common/android_webview_message_generator.cc b/android_webview/common/android_webview_message_generator.cc index d8b0080..8c5451ee 100644 --- a/android_webview/common/android_webview_message_generator.cc +++ b/android_webview/common/android_webview_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "android_webview/common/android_webview_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "android_webview/common/android_webview_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 3050b442..fdde7c7a 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -1242,6 +1242,10 @@ if (is_app_list_visible_ && !IsHomeLauncherEnabledInTabletMode()) return false; + // Also disable shelf drags until the overflow shelf is closed. + if (shelf_widget_->IsShowingOverflowBubble()) + return false; + gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ? auto_hide_state() @@ -1390,6 +1394,11 @@ if (!IsVisible()) return false; + // Do not show the fullscreen app list until the overflow bubble has been + // closed. + if (shelf_widget_->IsShowingOverflowBubble()) + return false; + // If app list is already opened, swiping up on the shelf should keep the app // list opened. if (is_app_list_visible_)
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 4c23fb8e..82a37794 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -1807,14 +1807,6 @@ } void ShelfView::OnGestureEvent(ui::GestureEvent* event) { - // Do not forward events to |shelf_| (which forwards events to the shelf - // layout manager) as we do not want gestures on the overflow to open the app - // list for example. - if (is_overflow_mode()) { - main_shelf_->overflow_bubble()->bubble_view()->ProcessGestureEvent(*event); - event->StopPropagation(); - return; - } // Convert the event location from current view to screen, since swiping up on // the shelf can open the fullscreen app list. Updating the bounds of the app @@ -1824,6 +1816,13 @@ event->set_location(location_in_screen); if (shelf_->ProcessGestureEvent(*event)) event->StopPropagation(); + else if (is_overflow_mode()) { + // If the event hasn't been processed and the overflow shelf is showing, + // let the bubble process the event. + main_shelf_->overflow_bubble()->bubble_view()->ProcessGestureEvent(*event); + event->StopPropagation(); + return; + } } bool ShelfView::OnMouseWheel(const ui::MouseWheelEvent& event) {
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index f09a3e51..cf91010 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -276,7 +276,7 @@ flag_warning->SetVisible(false); } - // The bounds should be big enough for 4 buttons + overflow chevron. + // The bounds should be big enough for 4 buttons + overflow button. ASSERT_GE(shelf_view_->width(), 500); test_api_.reset(new ShelfViewTestAPI(shelf_view_)); @@ -1759,6 +1759,53 @@ true /* cancel */); } +// Checks drag-reorder items within the overflow shelf. +TEST_F(ShelfViewTest, TestDragWithinOverflow) { + // Prepare the overflow and open it. + AddButtonsUntilOverflow(); + // Add a couple more to make sure we have things to drag. + AddAppShortcut(); + AddAppShortcut(); + test_api_->ShowOverflowBubble(); + ShelfView* overflow_shelf_view = + shelf_view_->overflow_bubble()->bubble_view()->shelf_view(); + ASSERT_TRUE(test_api_->IsShowingOverflowBubble()); + + ShelfViewTestAPI overflow_api(overflow_shelf_view); + + // We are going to drag the first item in the overflow (A) onto the last + // one (B). + int item_a_initial_index = overflow_api.GetFirstVisibleIndex(); + int item_b_initial_index = overflow_api.GetLastVisibleIndex(); + ShelfID item_a = GetItemId(item_a_initial_index); + ShelfID item_b = GetItemId(item_b_initial_index); + ShelfButton* item_a_button = overflow_api.GetButton(item_a_initial_index); + ShelfButton* item_b_button = overflow_api.GetButton(item_b_initial_index); + gfx::Point drag_point = GetButtonCenter(item_a_button); + gfx::Point drop_point = GetButtonCenter(item_b_button); + + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->set_current_location(drag_point); + EXPECT_EQ(nullptr, overflow_shelf_view->drag_view()); + + // TODO(manucornet): Test the same thing with only touches. + generator->PressLeftButton(); + + generator->MoveMouseTo(drop_point); + EXPECT_NE(nullptr, overflow_shelf_view->drag_view()); + generator->ReleaseLeftButton(); + overflow_api.RunMessageLoopUntilAnimationsDone(); + + // Now, item A should be the last item, and item B should be just before it. + ShelfID new_first_visible_item = + GetItemId(overflow_api.GetFirstVisibleIndex()); + EXPECT_NE(item_a, new_first_visible_item); + EXPECT_EQ(item_a, GetItemId(overflow_api.GetLastVisibleIndex())); + EXPECT_EQ(item_b, GetItemId(overflow_api.GetLastVisibleIndex() - 1)); + + test_api_->HideOverflowBubble(); +} + // Checks creating app shortcut for an opened platform app in overflow bubble // should be invisible to the shelf. See crbug.com/605793. TEST_F(ShelfViewTest, CheckOverflowStatusPinOpenedAppToShelf) {
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 1cc8ebd..b829d2a 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -152,27 +152,6 @@ DISALLOW_COPY_AND_ASSIGN(TweenTester); }; -// WindowState that lets us specify an initial state. -class InitialStateTestState : public wm::WindowState::State { - public: - explicit InitialStateTestState(mojom::WindowStateType initial_state_type) - : state_type_(initial_state_type) {} - ~InitialStateTestState() override = default; - - // WindowState::State overrides: - void OnWMEvent(wm::WindowState* window_state, - const wm::WMEvent* event) override {} - mojom::WindowStateType GetType() const override { return state_type_; } - void AttachState(wm::WindowState* window_state, - wm::WindowState::State* previous_state) override {} - void DetachState(wm::WindowState* window_state) override {} - - private: - mojom::WindowStateType state_type_; - - DISALLOW_COPY_AND_ASSIGN(InitialStateTestState); -}; - } // namespace // TODO(bruthig): Move all non-simple method definitions out of class @@ -3044,9 +3023,9 @@ const gfx::Rect bounds(200, 200); std::unique_ptr<aura::Window> pip_window(CreateWindow(bounds)); - wm::GetWindowState(pip_window.get()) - ->SetStateObject(std::unique_ptr<wm::WindowState::State>( - new InitialStateTestState(mojom::WindowStateType::PIP))); + wm::WindowState* window_state = wm::GetWindowState(pip_window.get()); + const wm::WMEvent enter_pip(wm::WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); // Enter overview. ToggleOverview();
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc index b29a1c1d..111d655 100644 --- a/ash/wm/window_state_unittest.cc +++ b/ash/wm/window_state_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/public/cpp/window_properties.h" #include "ash/shelf/shelf_constants.h" #include "ash/test/ash_test_base.h" -#include "ash/wm/window_state.h" #include "ash/wm/window_state_util.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -57,31 +56,6 @@ } // namespace -class InitialStateTestState : public WindowState::State { - public: - explicit InitialStateTestState(WindowStateType initial_state_type) - : state_type_(initial_state_type) {} - ~InitialStateTestState() override = default; - - // WindowState::State overrides: - void OnWMEvent(WindowState* window_state, const WMEvent* event) override { - if (event->type() == WM_EVENT_SET_BOUNDS) { - const SetBoundsEvent* set_bounds_event = - static_cast<const SetBoundsEvent*>(event); - window_state->SetBoundsDirect(set_bounds_event->requested_bounds()); - } - } - WindowStateType GetType() const override { return state_type_; } - void AttachState(WindowState* window_state, - WindowState::State* previous_state) override {} - void DetachState(WindowState* window_state) override {} - - private: - WindowStateType state_type_; - - DISALLOW_COPY_AND_ASSIGN(InitialStateTestState); -}; - using WindowStateTest = AshTestBase; // Test that a window gets properly snapped to the display's edges in a @@ -160,6 +134,20 @@ EXPECT_TRUE(window_state->CanSnap()); } +// Test that a window's state type can be changed to PIP via a WM transition +// event. +TEST_F(WindowStateTest, CanTransitionToPipWindow) { + std::unique_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + + WindowState* window_state = GetWindowState(window.get()); + EXPECT_FALSE(window_state->IsPip()); + + const WMEvent enter_pip(WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); + EXPECT_TRUE(window_state->IsPip()); +} + // Test that a PIP window cannot be snapped. TEST_F(WindowStateTest, PipWindowCannotSnap) { std::unique_ptr<aura::Window> window( @@ -168,8 +156,9 @@ WindowState* window_state = GetWindowState(window.get()); EXPECT_TRUE(window_state->CanSnap()); - window_state->SetStateObject(std::unique_ptr<WindowState::State>( - new InitialStateTestState(mojom::WindowStateType::PIP))); + const WMEvent enter_pip(WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); + EXPECT_FALSE(window_state->CanSnap()); } @@ -179,8 +168,9 @@ std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); WindowState* window_state = GetWindowState(window.get()); - window_state->SetStateObject(std::unique_ptr<WindowState::State>( - new InitialStateTestState(mojom::WindowStateType::PIP))); + + const WMEvent enter_pip(WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); window_state->UpdatePipRoundedCorners(); // Mask layer exists. @@ -204,8 +194,9 @@ std::unique_ptr<aura::Window> window( CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); WindowState* window_state = GetWindowState(window.get()); - window_state->SetStateObject(std::unique_ptr<WindowState::State>( - new InitialStateTestState(mojom::WindowStateType::PIP))); + + const WMEvent enter_pip(WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); EXPECT_TRUE(window->layer()); // No mask layer exist at this time.
diff --git a/base/allocator/partition_allocator/page_allocator_internals_win.h b/base/allocator/partition_allocator/page_allocator_internals_win.h index 4ef9b23..23f7a43 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_win.h +++ b/base/allocator/partition_allocator/page_allocator_internals_win.h
@@ -5,6 +5,7 @@ #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_INTERNALS_WIN_H_ #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_INTERNALS_WIN_H_ +#include "base/allocator/partition_allocator/oom.h" #include "base/allocator/partition_allocator/page_allocator_internal.h" #include "base/logging.h" @@ -88,9 +89,12 @@ } else { if (!VirtualAlloc(address, length, MEM_COMMIT, GetAccessFlags(accessibility))) { + int32_t error = GetLastError(); + if (error == ERROR_COMMITMENT_LIMIT) + OOM_CRASH(); // We check `GetLastError` for `ERROR_SUCCESS` here so that in a crash // report we get the error number. - CHECK_EQ(static_cast<uint32_t>(ERROR_SUCCESS), GetLastError()); + CHECK_EQ(ERROR_SUCCESS, error); } } }
diff --git a/base/profiler/win32_stack_frame_unwinder.cc b/base/profiler/win32_stack_frame_unwinder.cc index a6d1d45..204b3983 100644 --- a/base/profiler/win32_stack_frame_unwinder.cc +++ b/base/profiler/win32_stack_frame_unwinder.cc
@@ -119,7 +119,7 @@ bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context, ScopedModuleHandle* module) { #ifdef _WIN64 - // TODO(chengx): update base::ModuleCache to return a ScopedModuleHandle and + // TODO(wittman): update base::ModuleCache to return a ScopedModuleHandle and // use it for this module lookup. ScopedModuleHandle frame_module = unwind_functions_->GetModuleForProgramCounter(ContextPC(context));
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc index 1e66bc5..56361df 100644 --- a/base/test/scoped_task_environment_unittest.cc +++ b/base/test/scoped_task_environment_unittest.cc
@@ -9,6 +9,7 @@ #include "base/atomicops.h" #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/cancelable_callback.h" #include "base/run_loop.h" #include "base/synchronization/atomic_flag.h" #include "base/synchronization/waitable_event.h" @@ -161,7 +162,7 @@ // Should run only in MOCK_TIME environment when time is fast-forwarded. ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - Bind( + BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 4); }, @@ -170,7 +171,7 @@ // TODO(gab): This currently doesn't run because the TaskScheduler's clock // isn't mocked but it should be. PostDelayedTask(FROM_HERE, - Bind( + BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 128); }, @@ -182,7 +183,7 @@ // FastForwardUntilNoTasksRemain(). ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - Bind( + BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 8); }, @@ -190,7 +191,7 @@ TimeDelta::FromDays(5)); ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - Bind( + BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 16); }, @@ -198,12 +199,12 @@ kLongTaskDelay); ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, Bind( + FROM_HERE, BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 1); }, Unretained(&counter))); - PostTask(FROM_HERE, Bind( + PostTask(FROM_HERE, BindOnce( [](subtle::Atomic32* counter) { subtle::NoBarrier_AtomicIncrement(counter, 2); }, @@ -366,5 +367,212 @@ ScopedTaskEnvironmentTest, ::testing::Values(ScopedTaskEnvironment::MainThreadType::IO)); +class ScopedTaskEnvironmentMockedTime + : public testing::TestWithParam<ScopedTaskEnvironment::MainThreadType> {}; + +TEST_P(ScopedTaskEnvironmentMockedTime, Basic) { + ScopedTaskEnvironment scoped_task_environment( + GetParam(), ScopedTaskEnvironment::ExecutionMode::QUEUED); + + int counter = 0; + + ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 1; }, Unretained(&counter))); + ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 32; }, Unretained(&counter))); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 256; }, Unretained(&counter)), + TimeDelta::FromSeconds(3)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 64; }, Unretained(&counter)), + TimeDelta::FromSeconds(1)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 1024; }, Unretained(&counter)), + TimeDelta::FromMinutes(20)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + BindOnce([](int* counter) { *counter += 4096; }, Unretained(&counter)), + TimeDelta::FromDays(20)); + + int expected_value = 0; + EXPECT_EQ(expected_value, counter); + scoped_task_environment.RunUntilIdle(); + expected_value += 1; + expected_value += 32; + EXPECT_EQ(expected_value, counter); + + scoped_task_environment.RunUntilIdle(); + EXPECT_EQ(expected_value, counter); + + scoped_task_environment.FastForwardBy(TimeDelta::FromSeconds(1)); + expected_value += 64; + EXPECT_EQ(expected_value, counter); + + scoped_task_environment.FastForwardBy(TimeDelta::FromSeconds(5)); + expected_value += 256; + EXPECT_EQ(expected_value, counter); + + scoped_task_environment.FastForwardUntilNoTasksRemain(); + expected_value += 1024; + expected_value += 4096; + EXPECT_EQ(expected_value, counter); +} + +TEST_P(ScopedTaskEnvironmentMockedTime, RunLoopDriveable) { + ScopedTaskEnvironment scoped_task_environment( + GetParam(), ScopedTaskEnvironment::ExecutionMode::QUEUED); + + int counter = 0; + ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce([](int* counter) { *counter += 1; }, + Unretained(&counter))); + ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce([](int* counter) { *counter += 32; }, + Unretained(&counter))); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 256; }, + Unretained(&counter)), + TimeDelta::FromSeconds(3)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 64; }, + Unretained(&counter)), + TimeDelta::FromSeconds(1)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 1024; }, + Unretained(&counter)), + TimeDelta::FromMinutes(20)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 4096; }, + Unretained(&counter)), + TimeDelta::FromDays(20)); + + int expected_value = 0; + EXPECT_EQ(expected_value, counter); + RunLoop().RunUntilIdle(); + expected_value += 1; + expected_value += 32; + EXPECT_EQ(expected_value, counter); + + RunLoop().RunUntilIdle(); + EXPECT_EQ(expected_value, counter); + + { + RunLoop run_loop; + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TimeDelta::FromSeconds(1)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 8192; }, + Unretained(&counter)), + TimeDelta::FromSeconds(1)); + + // The QuitClosure() should be ordered between the 64 and the 8192 + // increments and should preempt the latter. + run_loop.Run(); + expected_value += 64; + EXPECT_EQ(expected_value, counter); + + // Running until idle should process the 8192 increment whose delay has + // expired in the previous Run(). + RunLoop().RunUntilIdle(); + expected_value += 8192; + EXPECT_EQ(expected_value, counter); + } + + { + RunLoop run_loop; + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitWhenIdleClosure(), TimeDelta::FromSeconds(5)); + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 16384; }, + Unretained(&counter)), + TimeDelta::FromSeconds(5)); + + // The QuitWhenIdleClosure() shouldn't preempt equally delayed tasks and as + // such the 16384 increment should be processed before quitting. + run_loop.Run(); + expected_value += 256; + expected_value += 16384; + EXPECT_EQ(expected_value, counter); + } + + // Process the remaining tasks (note: do not mimic this elsewhere, + // TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() is a better API to + // do this, this is just done here for the purpose of extensively testing the + // RunLoop approach). + RunLoop run_loop; + ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitWhenIdleClosure(), TimeDelta::FromDays(50)); + + run_loop.Run(); + expected_value += 1024; + expected_value += 4096; + EXPECT_EQ(expected_value, counter); +} + +TEST_P(ScopedTaskEnvironmentMockedTime, CancelPendingTask) { + ScopedTaskEnvironment scoped_task_environment( + GetParam(), ScopedTaskEnvironment::ExecutionMode::QUEUED); + + CancelableOnceClosure task1(Bind([]() {})); + ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, task1.callback(), + TimeDelta::FromSeconds(1)); + EXPECT_TRUE(scoped_task_environment.MainThreadHasPendingTask()); + EXPECT_EQ(1u, scoped_task_environment.GetPendingMainThreadTaskCount()); + EXPECT_EQ(TimeDelta::FromSeconds(1), + scoped_task_environment.NextMainThreadPendingTaskDelay()); + task1.Cancel(); + EXPECT_FALSE(scoped_task_environment.MainThreadHasPendingTask()); + + CancelableClosure task2(Bind([]() {})); + ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, task2.callback(), + TimeDelta::FromSeconds(1)); + task2.Cancel(); + EXPECT_EQ(0u, scoped_task_environment.GetPendingMainThreadTaskCount()); + + CancelableClosure task3(Bind([]() {})); + ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, task3.callback(), + TimeDelta::FromSeconds(1)); + task3.Cancel(); + EXPECT_EQ(TimeDelta::Max(), + scoped_task_environment.NextMainThreadPendingTaskDelay()); + + CancelableClosure task4(Bind([]() {})); + ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, task4.callback(), + TimeDelta::FromSeconds(1)); + task4.Cancel(); + EXPECT_FALSE(scoped_task_environment.MainThreadHasPendingTask()); +} + +TEST_P(ScopedTaskEnvironmentMockedTime, NoFastForwardToCancelledTask) { + ScopedTaskEnvironment scoped_task_environment( + GetParam(), ScopedTaskEnvironment::ExecutionMode::QUEUED); + + TimeTicks start_time = scoped_task_environment.NowTicks(); + CancelableClosure task(Bind([]() {})); + ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, task.callback(), + TimeDelta::FromSeconds(1)); + EXPECT_EQ(TimeDelta::FromSeconds(1), + scoped_task_environment.NextMainThreadPendingTaskDelay()); + task.Cancel(); + scoped_task_environment.FastForwardUntilNoTasksRemain(); + EXPECT_EQ(start_time, scoped_task_environment.NowTicks()); +} + +INSTANTIATE_TEST_CASE_P( + MainThreadMockTime, + ScopedTaskEnvironmentMockedTime, + ::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME)); + } // namespace test } // namespace base
diff --git a/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java b/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java index bb9c7159..10e438f 100644 --- a/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java +++ b/build/android/incremental_install/java/org/chromium/incrementalinstall/ClassLoaderPatcher.java
@@ -67,7 +67,9 @@ dexDir = incrementalDexesDir; } - File[] dexFilesArr = dexDir.listFiles((File f) -> f.isFile()); // Ignore "oat" directory. + // Ignore "oat" directory. + // Also ignore files that sometimes show up (e.g. .jar.arm.flock). + File[] dexFilesArr = dexDir.listFiles(f -> f.getName().endsWith(".jar")); if (dexFilesArr == null) { throw new FileNotFoundException("Dex dir does not exist: " + dexDir); }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 75b99f1..b00b0f6f 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -661,16 +661,22 @@ # linker jobs. This is still suboptimal to a potential dynamic # resource allocation scheme, but should be good enough. if (use_lld) { - # Limit the size of the ThinLTO cache to the lesser of 10% of available disk - # space, 10GB and 100000 files. - cache_policy = - "cache_size=10%:cache_size_bytes=10g:cache_size_files=100000" ldflags += [ "-Wl,--thinlto-jobs=8", - "-Wl,--thinlto-cache-dir=" + - rebase_path("$root_out_dir/thinlto-cache", root_build_dir), - "-Wl,--thinlto-cache-policy,$cache_policy", ] + + # Disable caching on Chrome OS temporarily (crbug.com/889967) + if (!is_chromeos) { + # Limit the size of the ThinLTO cache to the lesser of 10% of + # available disk space, 10GB and 100000 files. + cache_policy = + "cache_size=10%:cache_size_bytes=10g:cache_size_files=100000" + ldflags += [ + "-Wl,--thinlto-cache-dir=" + + rebase_path("$root_out_dir/thinlto-cache", root_build_dir), + "-Wl,--thinlto-cache-policy,$cache_policy", + ] + } } else { ldflags += [ "-Wl,-plugin-opt,jobs=8" ] } @@ -1486,10 +1492,13 @@ # Ignore warnings about MSVC optimization pragmas. # TODO(thakis): Only for no_chromium_code? http://crbug.com/505314 "-Wno-ignored-pragma-optimize", - - # TODO(hans): https://crbug.com/890307 - "-Wno-defaulted-function-deleted", ] + if (is_fuchsia) { + cflags += [ + # TODO(hans): https://crbug.com/890307 + "-Wno-defaulted-function-deleted", + ] + } } } }
diff --git a/build/sanitizers/sanitizer_options.cc b/build/sanitizers/sanitizer_options.cc index 9a5a179..7f90f19 100644 --- a/build/sanitizers/sanitizer_options.cc +++ b/build/sanitizers/sanitizer_options.cc
@@ -77,15 +77,9 @@ "check_printf=1 use_sigaltstack=1 " "strip_path_prefix=/../../ fast_unwind_on_fatal=1 " "detect_stack_use_after_return=1 detect_odr_violation=0 "; - -#elif defined(OS_WIN) -const char* kAsanDefaultOptions = - "check_printf=1 use_sigaltstack=1 " - "strip_path_prefix=\\..\\..\\ fast_unwind_on_fatal=1 " - "detect_stack_use_after_return=1 "; #endif // OS_LINUX -#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_MACOSX) // Allow NaCl to override the default asan options. extern const char* kAsanDefaultOptionsNaCl; __attribute__((weak)) const char* kAsanDefaultOptionsNaCl = nullptr; @@ -101,7 +95,7 @@ SANITIZER_HOOK_ATTRIBUTE const char *__asan_default_suppressions() { return kASanDefaultSuppressions; } -#endif // OS_LINUX || OS_MACOSX || OS_WIN +#endif // OS_LINUX || OS_MACOSX #endif // ADDRESS_SANITIZER #if defined(THREAD_SANITIZER) && defined(OS_LINUX)
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index bd370b3..a70c99ee 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -530,6 +530,7 @@ "//components/bookmarks/common/android:bookmarks_java", "//components/invalidation/impl:java", "//components/minidump_uploader:minidump_uploader_java", + "//components/module_installer/android:module_installer_stub_java", "//components/offline_items_collection/core:core_java", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", @@ -774,6 +775,7 @@ "//base:base_java", "//base:base_java_test_support", "//chrome/android:app_hooks_java", + "//components/module_installer/android:module_installer_stub_java", "//chrome/android:chrome_java", "//chrome/browser/android/vr:java", "//chrome/test/android:chrome_java_test_support", @@ -1882,7 +1884,12 @@ android_app_bundle("chrome_modern_public_bundle") { bundle_name = "ChromeModernPublic" base_module_target = ":chrome_modern_public_base_module" - proguard_enabled = !is_java_debug + if (!is_java_debug) { + proguard_enabled = true + if (experimental_r8_path == "") { + enable_multidex = true + } + } enable_language_splits = enable_chrome_language_splits if (modularize_vr) { extra_modules = [
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 79148181..3915df1f 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -145,6 +145,17 @@ } } } + + # Only bundles can install modules. Therefore, include stub implementation + # for all other targets to save some binary size. + if (_target_type == "android_app_bundle_module") { + deps += + [ "//components/module_installer/android:module_installer_impl_java" ] + } else { + deps += + [ "//components/module_installer/android:module_installer_stub_java" ] + } + if (!is_java_debug) { proguard_enabled = true if (!defined(proguard_configs)) {
diff --git a/chrome/android/java/res/layout/ephemeral_tab_text_view.xml b/chrome/android/java/res/layout/ephemeral_tab_text_view.xml new file mode 100644 index 0000000..92df4dc --- /dev/null +++ b/chrome/android/java/res/layout/ephemeral_tab_text_view.xml
@@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<!-- Ephemeral Tab bar text --> +<!-- TODO(jinsukkim): Define Ephemeral Tab's own text view style --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/ephemeral_tab_text_view" + style="@style/ContextualSearchTextViewLayout" > + <TextView + android:id="@+id/ephemeral_tab_text" + style="@style/ContextualSearchTextView" + android:layout_width="match_parent" + android:layout_gravity="bottom" + android:background="@android:color/white" + android:layout_marginStart="7dp" + android:layout_marginEnd="7dp" /> +</FrameLayout>
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index 47286b4..1ba77d75 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -92,6 +92,7 @@ <item type="id" name="contextmenu_save_image" /> <item type="id" name="contextmenu_open_image" /> <item type="id" name="contextmenu_open_image_in_new_tab" /> + <item type="id" name="contextmenu_open_image_in_ephemeral_tab" /> <item type="id" name="contextmenu_search_by_image" /> <item type="id" name="contextmenu_share_image" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index b3dcf47..0550a04 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -63,6 +63,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; +import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabPanel; import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; @@ -263,6 +264,7 @@ private CompositorViewHolder mCompositorViewHolder; private InsetObserverView mInsetObserverView; private ContextualSearchManager mContextualSearchManager; + private EphemeralTabPanel mEphemeralTabPanel; protected ReaderModeManager mReaderModeManager; private SnackbarManager mSnackbarManager; private DataReductionPromoSnackbarController mDataReductionPromoSnackbarController; @@ -1533,6 +1535,10 @@ return false; } + if (getEphemeralTabPanel() != null && getEphemeralTabPanel().isPanelOpened()) { + return false; + } + // Do not show the menu if we are in find in page view. if (mFindToolbarManager != null && mFindToolbarManager.isShowing() && !isTablet()) { return false; @@ -1800,6 +1806,10 @@ return mReaderModeManager; } + public EphemeralTabPanel getEphemeralTabPanel() { + return getCompositorViewHolder().getLayoutManager().getEphemeralTabPanel(); + } + /** * Create a full-screen manager to be used by this activity. * Note: This is called during {@link #postInflationStartup}, so native code may not have been @@ -1859,6 +1869,8 @@ } mActivityTabProvider.setLayoutManager(layoutManager); + EphemeralTabPanel panel = layoutManager.getEphemeralTabPanel(); + if (panel != null) panel.setChromeActivity(this); } /** @@ -2085,6 +2097,9 @@ if (mContextualSearchManager != null) { getContextualSearchManager().hideContextualSearch(StateChangeReason.UNKNOWN); } + if (getEphemeralTabPanel() != null) { + getEphemeralTabPanel().closePanel(StateChangeReason.UNKNOWN, true); + } if (fromMenu) { RecordUserAction.record("MobileMenuFindInPage"); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index 2deae9f..febee5e5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -183,6 +183,11 @@ } @CalledByNative + private String onGetStatusMessage() { + return mStatusMessage; + } + + @CalledByNative private void onShowOverlay() { mUiDelegateHolder.performUiOperation(uiDelegate -> { uiDelegate.showOverlay();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayContentProgressObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayContentProgressObserver.java index e44dafa..0fbe4e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayContentProgressObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayContentProgressObserver.java
@@ -25,4 +25,3 @@ */ public void onProgressBarFinished() {} } -
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java index 12fda211..3c2bb76 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Context; import android.graphics.RectF; +import android.os.Handler; import android.support.annotation.IntDef; import android.view.ViewGroup; @@ -47,6 +48,9 @@ /** The extra dp added around the close button touch target. */ private static final int CLOSE_BUTTON_TOUCH_SLOP_DP = 5; + /** The delay after which the hide progress will be hidden. */ + private static final long HIDE_PROGRESS_BAR_DELAY_MS = 1000 / 60 * 4; + /** State of the Overlay Panel. */ public static enum PanelState { // TODO(pedrosimonetti): consider removing the UNDEFINED state @@ -401,6 +405,37 @@ } /** + * Progress observer progress indicator animation for a panel. + */ + public class PanelProgressObserver extends OverlayContentProgressObserver { + @Override + public void onProgressBarStarted() { + setProgressBarCompletion(0); + setProgressBarVisible(true); + requestUpdate(); + } + + @Override + public void onProgressBarUpdated(int progress) { + setProgressBarCompletion(progress); + requestUpdate(); + } + + @Override + public void onProgressBarFinished() { + // Hides the Progress Bar after a delay to make sure it is rendered for at least + // a few frames, otherwise its completion won't be visually noticeable. + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + setProgressBarVisible(false); + requestUpdate(); + } + }, HIDE_PROGRESS_BAR_DELAY_MS); + } + } + + /** * Create a new OverlayPanelContent object. This can be overridden for tests. * @return A new OverlayPanelContent object. */
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 1e0bbda..6ff2ed2 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
@@ -8,15 +8,14 @@ import android.content.Context; import android.graphics.Rect; import android.graphics.RectF; -import android.os.Handler; import org.chromium.base.ActivityState; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.LayerTitleCache; -import org.chromium.chrome.browser.compositor.bottombar.OverlayContentProgressObserver; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelProgressObserver; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContent; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; @@ -37,12 +36,6 @@ * Controls the Contextual Search Panel. */ public class ContextualSearchPanel extends OverlayPanel { - - /** - * The delay after which the hide progress will be hidden. - */ - private static final long HIDE_PROGRESS_BAR_DELAY = 1000 / 60 * 4; - /** When using the Generic UX we never show the Arrow Icon */ private static final float ARROW_ICON_OPACITY_GENERIC_UX = 0.f; @@ -125,38 +118,6 @@ new PanelProgressObserver(), mActivity, getBarHeight()); } - /** - * Default loading animation for a panel. - */ - public class PanelProgressObserver extends OverlayContentProgressObserver { - - @Override - public void onProgressBarStarted() { - setProgressBarCompletion(0); - setProgressBarVisible(true); - requestUpdate(); - } - - @Override - public void onProgressBarUpdated(int progress) { - setProgressBarCompletion(progress); - requestUpdate(); - } - - @Override - public void onProgressBarFinished() { - // Hides the Progress Bar after a delay to make sure it is rendered for at least - // a few frames, otherwise its completion won't be visually noticeable. - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - setProgressBarVisible(false); - requestUpdate(); - } - }, HIDE_PROGRESS_BAR_DELAY); - } - } - // ============================================================================================ // Scene Overlay // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabBarControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabBarControl.java new file mode 100644 index 0000000..5b540eb --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabBarControl.java
@@ -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. + +package org.chromium.chrome.browser.compositor.bottombar.ephemeraltab; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelInflater; +import org.chromium.ui.resources.dynamics.DynamicResourceLoader; + +/** + * Top control used for ephemeral tab. + */ +public class EphemeralTabBarControl extends OverlayPanelInflater { + /** + * The tab title View. + */ + private TextView mBarText; + + /** + * @param panel The panel. + * @param context The Android Context used to inflate the View. + * @param container The container View used to inflate the View. + * @param resourceLoader The resource loader that will handle the snapshot capturing. + */ + public EphemeralTabBarControl(OverlayPanel panel, Context context, ViewGroup container, + DynamicResourceLoader resourceLoader) { + super(panel, R.layout.ephemeral_tab_text_view, R.id.ephemeral_tab_text_view, context, + container, resourceLoader); + invalidate(); + } + + /** + * Set the text in the panel. + * @param text The string to set the text to. + */ + public void setBarText(String text) { + inflate(); + mBarText.setText(text); + invalidate(); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + View view = getView(); + mBarText = (TextView) view.findViewById(R.id.ephemeral_tab_text); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabPanel.java new file mode 100644 index 0000000..bec43ea5 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabPanel.java
@@ -0,0 +1,191 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.compositor.bottombar.ephemeraltab; + +import android.content.Context; +import android.graphics.RectF; +import android.view.MotionEvent; + +import org.chromium.base.SysUtils; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.compositor.LayerTitleCache; +import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelProgressObserver; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContent; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; +import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; +import org.chromium.chrome.browser.compositor.layouts.eventfilter.OverlayPanelEventFilter; +import org.chromium.chrome.browser.compositor.scene_layer.EphemeralTabSceneLayer; +import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.resources.ResourceManager; + +/** + * The panel containing an ephemeral tab. + * TODO(jinsukkim): Make panel height in peeked state bigger to show the progress indicator clearly. + */ +public class EphemeralTabPanel extends OverlayPanel { + /** The compositor layer used for drawing the panel. */ + private EphemeralTabSceneLayer mSceneLayer; + + /** + * Checks if this feature (a.k.a. "Sneak peek") for html and image is supported. + * @return {@code true} if the feature is enabled. + */ + public static boolean isSupported() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.EPHEMERAL_TAB) + && !SysUtils.isLowEndDevice(); + } + + /** + * @param context The current Android {@link Context}. + * @param updateHost The {@link LayoutUpdateHost} used to request updates in the Layout. + * @param panelManager The {@link OverlayPanelManager} used to control panel show/hide. + */ + public EphemeralTabPanel( + Context context, LayoutUpdateHost updateHost, OverlayPanelManager panelManager) { + super(context, updateHost, panelManager); + mSceneLayer = + new EphemeralTabSceneLayer(mContext.getResources().getDisplayMetrics().density); + mEventFilter = new OverlayPanelEventFilter(mContext, this) { + @Override + public boolean onInterceptTouchEventInternal(MotionEvent e, boolean isKeyboardShowing) { + OverlayPanel panel = EphemeralTabPanel.this; + if (panel.isShowing() && panel.isPeeking() + && panel.isCoordinateInsideBar(e.getX() * mPxToDp, e.getY() * mPxToDp)) { + // Events go to base panel in peeked mode to scroll base page. + return super.onInterceptTouchEventInternal(e, isKeyboardShowing); + } + if (panel.isShowing() && panel.isMaximized()) return true; + return false; + } + }; + } + + @Override + public OverlayPanelContent createNewOverlayPanelContent() { + return new OverlayPanelContent(new OverlayContentDelegate(), new PanelProgressObserver(), + mActivity, getBarHeight()); + } + + @Override + protected float getMaximizedHeight() { + // Max height does not cover the entire content screen. + return getTabHeight() * 0.9f; + } + + @Override + public float getProgressBarOpacity() { + return 1.0f; + } + + // Scene Overlay + + @Override + public SceneOverlayLayer getUpdatedSceneOverlayTree(RectF viewport, RectF visibleViewport, + LayerTitleCache layerTitleCache, ResourceManager resourceManager, float yOffset) { + mSceneLayer.update(resourceManager, this, getBarTextViewId(), 1.0f); + return mSceneLayer; + } + + @Override + public boolean updateOverlay(long time, long dt) { + // Allow WebContents to size itself appropriately (includes browser controls height). + updateBrowserControlsState(); + return super.updateOverlay(time, dt); + } + + // Generic Event Handling + + @Override + public void handleBarClick(float x, float y) { + super.handleBarClick(x, y); + if (isCoordinateInsideCloseButton(x)) { + closePanel(StateChangeReason.CLOSE_BUTTON, true); + } else { + maximizePanel(StateChangeReason.SEARCH_BAR_TAP); + } + } + + // Panel base methods + + @Override + public void destroyComponents() { + super.destroyComponents(); + destroyEphemeralTabBarControl(); + } + + @Override + public @PanelPriority int getPriority() { + return PanelPriority.HIGH; + } + + @Override + protected boolean isSupportedState(PanelState state) { + return state != PanelState.EXPANDED; + } + + @Override + protected void onClosed(@StateChangeReason int reason) { + super.onClosed(reason); + if (mSceneLayer != null) mSceneLayer.hideTree(); + } + + /** + * Request opening the ephemeral tab panel when triggered from context menu. + * @param url URL of the content to open in the panel + * @param text Link text which will appear on the tab bar. + */ + public void requestOpenPanel(String url, String text) { + loadUrlInPanel(url); + WebContents panelWebContents = getWebContents(); + if (panelWebContents != null) panelWebContents.onShow(); + getEphemeralTabBarControl().setBarText(text); + requestPanelShow(StateChangeReason.CLICK); + } + + @Override + public void onLayoutChanged(float width, float height, float visibleViewportOffsetY) { + if (width != getWidth()) destroyEphemeralTabBarControl(); + super.onLayoutChanged(width, height, visibleViewportOffsetY); + } + + private EphemeralTabBarControl mEphemeralTabBarControl; + + /** + * @return The Id of the Search Term View. + */ + public int getBarTextViewId() { + return getEphemeralTabBarControl().getViewId(); + } + + /** + * Creates the EphemeralTabBarControl, if needed. The Views are set to INVISIBLE, because + * they won't actually be displayed on the screen (their snapshots will be displayed instead). + */ + protected EphemeralTabBarControl getEphemeralTabBarControl() { + assert mContainerView != null; + assert mResourceLoader != null; + if (mEphemeralTabBarControl == null) { + mEphemeralTabBarControl = + new EphemeralTabBarControl(this, mContext, mContainerView, mResourceLoader); + } + assert mEphemeralTabBarControl != null; + return mEphemeralTabBarControl; + } + + /** + * Destroys the EphemeralTabBarControl. + */ + protected void destroyEphemeralTabBarControl() { + if (mEphemeralTabBarControl != null) { + mEphemeralTabBarControl.destroy(); + mEphemeralTabBarControl = null; + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index 3c3ad09..d40da26a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContentViewDelegate; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel; +import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabPanel; import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.components.VirtualView; @@ -108,6 +109,7 @@ private int mControlsHidingToken = FullscreenManager.INVALID_TOKEN; private boolean mUpdateRequested; private final ContextualSearchPanel mContextualSearchPanel; + private final EphemeralTabPanel mEphemeralTabPanel; private final OverlayPanelManager mOverlayPanelManager; private final ToolbarSceneLayer mToolbarOverlay; @@ -220,6 +222,10 @@ // Contextual Search scene overlay. mContextualSearchPanel = new ContextualSearchPanel(mContext, this, mOverlayPanelManager); + mEphemeralTabPanel = EphemeralTabPanel.isSupported() + ? new EphemeralTabPanel(mContext, this, mOverlayPanelManager) + : null; + // Set up layout parameters mStaticLayout.setLayoutHandlesTabLifecycles(true); @@ -233,6 +239,13 @@ return mOverlayPanelManager; } + /** + * @return The layout manager's ephemeral tab panel manager. + */ + public EphemeralTabPanel getEphemeralTabPanel() { + return mEphemeralTabPanel; + } + @Override public CompositorAnimationHandler getAnimationHandler() { return mAnimationHandler; @@ -862,6 +875,7 @@ protected void addAllSceneOverlays() { addGlobalSceneOverlay(mToolbarOverlay); mStaticLayout.addSceneOverlay(mContextualSearchPanel); + if (mEphemeralTabPanel != null) mStaticLayout.addSceneOverlay(mEphemeralTabPanel); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index 66b62cb2..71de4d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -11,6 +11,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.compositor.TitleCache; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.components.VirtualView; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -188,11 +189,14 @@ Layout layoutBeingShown = getActiveLayout(); - // Check if a layout is showing that should hide the contextual search bar. - if (mContextualSearchDelegate != null - && (isOverviewLayout(layoutBeingShown) - || layoutBeingShown == mToolbarSwipeLayout)) { - mContextualSearchDelegate.dismissContextualSearchBar(); + // Check if a layout is showing that should hide the overlay panels. + if (isOverviewLayout(layoutBeingShown) || layoutBeingShown == mToolbarSwipeLayout) { + if (mContextualSearchDelegate != null) { + mContextualSearchDelegate.dismissContextualSearchBar(); + } + if (getEphemeralTabPanel() != null) { + getEphemeralTabPanel().closePanel(StateChangeReason.UNKNOWN, false); + } } // Check if we should notify OverviewModeObservers.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java new file mode 100644 index 0000000..2d6e7495 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java
@@ -0,0 +1,118 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.compositor.scene_layer; + +import org.chromium.base.annotations.JNINamespace; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.resources.ResourceManager; + +/** + * A SceneLayer to render layers for Ephemeral Tab. + */ +@JNINamespace("android") +public class EphemeralTabSceneLayer extends SceneOverlayLayer { + /** Pointer to native EphemeralTabSceneLayer. */ + private long mNativePtr; + + /** If the scene layer has been initialized. */ + private boolean mIsInitialized; + + /** The conversion multiple from dp to px. */ + private final float mDpToPx; + + /** + * @param dpToPx The conversion multiple from dp to px for the device. + */ + public EphemeralTabSceneLayer(float dpToPx) { + mDpToPx = dpToPx; + } + + /** + * Update the scene layer to draw an OverlayPanel. + * @param resourceManager Manager to get view and image resources. + * @param panel The OverlayPanel to render. + * @param barTextViewId The ID of the view containing the ephemeral tab bar. + * @param barTextOpacity The opacity of the text specified by {@code barTextViewId}. + */ + public void update(ResourceManager resourceManager, OverlayPanel panel, int barTextViewId, + float barTextOpacity) { + // Don't try to update the layer if not initialized or showing. + if (resourceManager == null || !panel.isShowing()) return; + if (!mIsInitialized) { + nativeCreateEphemeralTabLayer(mNativePtr, resourceManager); + + // TODO(jinsukkim): Find the right icon/background resource for the tab bar. + nativeSetResourceIds(mNativePtr, barTextViewId, + R.drawable.contextual_search_bar_background, R.drawable.modern_toolbar_shadow, + R.drawable.infobar_chrome, R.drawable.btn_close); + mIsInitialized = true; + } + boolean isProgressBarVisible = panel.isProgressBarVisible(); + float progressBarHeight = panel.getProgressBarHeight(); + float progressBarOpacity = panel.getProgressBarOpacity(); + int progressBarCompletion = panel.getProgressBarCompletion(); + + WebContents panelWebContents = panel.getWebContents(); + nativeUpdate(mNativePtr, R.drawable.progress_bar_background, + R.drawable.progress_bar_foreground, mDpToPx, panel.getBasePageBrightness(), + panel.getBasePageY() * mDpToPx, panelWebContents, panel.getOffsetX() * mDpToPx, + panel.getOffsetY() * mDpToPx, panel.getWidth() * mDpToPx, + panel.getHeight() * mDpToPx, panel.getBarMarginSide() * mDpToPx, + panel.getBarHeight() * mDpToPx, barTextOpacity, panel.isBarBorderVisible(), + panel.getBarBorderHeight() * mDpToPx, panel.getBarShadowVisible(), + panel.getBarShadowOpacity(), isProgressBarVisible, progressBarHeight * mDpToPx, + progressBarOpacity, progressBarCompletion); + } + + @Override + public void setContentTree(SceneLayer contentTree) { + nativeSetContentTree(mNativePtr, contentTree); + } + + /** + * Hide the layer tree; for use if the panel is not being shown. + */ + public void hideTree() { + if (!mIsInitialized) return; + nativeHideTree(mNativePtr); + } + + @Override + protected void initializeNative() { + if (mNativePtr == 0) { + mNativePtr = nativeInit(); + } + assert mNativePtr != 0; + } + + /** + * Destroys this object and the corresponding native component. + */ + @Override + public void destroy() { + super.destroy(); + mIsInitialized = false; + mNativePtr = 0; + } + + private native long nativeInit(); + private native void nativeCreateEphemeralTabLayer( + long nativeEphemeralTabSceneLayer, ResourceManager resourceManager); + private native void nativeSetContentTree( + long nativeEphemeralTabSceneLayer, SceneLayer contentTree); + private native void nativeHideTree(long nativeEphemeralTabSceneLayer); + private native void nativeSetResourceIds(long nativeEphemeralTabSceneLayer, + int barTextResourceId, int barBackgroundResourceId, int barShadowResourceId, + int panelIconResourceId, int closeIconResourceId); + private native void nativeUpdate(long nativeEphemeralTabSceneLayer, + int progressBarBackgroundResourceId, int progressBarResourceId, float dpToPx, + float basePageBrightness, float basePageYOffset, WebContents webContents, float panelX, + float panelY, float panelWidth, float panelHeight, float barMarginSide, float barHeight, + float textOpacity, boolean barBorderVisible, float barBorderHeight, + boolean barShadowVisible, float barShadowOpacity, boolean isProgressBarVisible, + float progressBarHeight, float progressBarOpacity, int progressBarCompletion); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java index 7a699d1..54f5efc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -26,9 +26,9 @@ Item.OPEN_IN_BROWSER_ID, Item.OPEN_IN_NEW_TAB, Item.OPEN_IN_INCOGNITO_TAB, Item.OPEN_IN_OTHER_WINDOW, Item.OPEN_IN_EPHEMERAL_TAB, Item.COPY_LINK_ADDRESS, Item.COPY_LINK_TEXT, Item.SAVE_LINK_AS, Item.LOAD_ORIGINAL_IMAGE, Item.SAVE_IMAGE, - Item.OPEN_IMAGE, Item.OPEN_IMAGE_IN_NEW_TAB, Item.SEARCH_BY_IMAGE, Item.CALL, - Item.SEND_MESSAGE, Item.ADD_TO_CONTACTS, Item.COPY, Item.SAVE_VIDEO, - Item.OPEN_IN_CHROME, Item.BROWSER_ACTIONS_OPEN_IN_BACKGROUND, + Item.OPEN_IMAGE, Item.OPEN_IMAGE_IN_NEW_TAB, Item.OPEN_IMAGE_IN_EPHEMERAL_TAB, + Item.SEARCH_BY_IMAGE, Item.CALL, Item.SEND_MESSAGE, Item.ADD_TO_CONTACTS, Item.COPY, + Item.SAVE_VIDEO, Item.OPEN_IN_CHROME, Item.BROWSER_ACTIONS_OPEN_IN_BACKGROUND, Item.BROWSER_ACTIONS_OPEN_IN_INCOGNITO_TAB, Item.BROWSER_ACTION_SAVE_LINK_AS, Item.BROWSER_ACTIONS_COPY_ADDRESS}) @Retention(RetentionPolicy.SOURCE) @@ -52,23 +52,24 @@ int SAVE_IMAGE = 11; int OPEN_IMAGE = 12; int OPEN_IMAGE_IN_NEW_TAB = 13; - int SEARCH_BY_IMAGE = 14; + int OPEN_IMAGE_IN_EPHEMERAL_TAB = 14; + int SEARCH_BY_IMAGE = 15; // Message Group - int CALL = 15; - int SEND_MESSAGE = 16; - int ADD_TO_CONTACTS = 17; - int COPY = 18; + int CALL = 16; + int SEND_MESSAGE = 17; + int ADD_TO_CONTACTS = 18; + int COPY = 19; // Video Group - int SAVE_VIDEO = 19; + int SAVE_VIDEO = 20; // Other - int OPEN_IN_CHROME = 20; + int OPEN_IN_CHROME = 21; // Browser Action Items - int BROWSER_ACTIONS_OPEN_IN_BACKGROUND = 21; - int BROWSER_ACTIONS_OPEN_IN_INCOGNITO_TAB = 22; - int BROWSER_ACTION_SAVE_LINK_AS = 23; - int BROWSER_ACTIONS_COPY_ADDRESS = 24; + int BROWSER_ACTIONS_OPEN_IN_BACKGROUND = 22; + int BROWSER_ACTIONS_OPEN_IN_INCOGNITO_TAB = 23; + int BROWSER_ACTION_SAVE_LINK_AS = 24; + int BROWSER_ACTIONS_COPY_ADDRESS = 25; // ALWAYS UPDATE! - int NUM_ENTRIES = 25; + int NUM_ENTRIES = 26; } /** @@ -89,6 +90,7 @@ R.id.contextmenu_save_image, // Item.SAVE_IMAGE R.id.contextmenu_open_image, // Item.OPEN_IMAGE R.id.contextmenu_open_image_in_new_tab, // Item.OPEN_IMAGE_IN_NEW_TAB + R.id.contextmenu_open_image_in_ephemeral_tab, // Item.OPEN_IMAGE_IN_EPHEMERAL_TAB R.id.contextmenu_search_by_image, // Item.SEARCH_BY_IMAGE R.id.contextmenu_call, // Item.CALL R.id.contextmenu_send_message, // Item.SEND_MESSAGE @@ -120,6 +122,7 @@ R.string.contextmenu_save_image, // Item.SAVE_IMAGE: R.string.contextmenu_open_image, // Item.OPEN_IMAGE: R.string.contextmenu_open_image_in_new_tab, // Item.OPEN_IMAGE_IN_NEW_TAB: + R.string.contextmenu_open_image_in_ephemeral_tab, // Item.OPEN_IMAGE_IN_EPHEMERAL_TAB: R.string.contextmenu_search_web_for_image, // Item.SEARCH_BY_IMAGE: R.string.contextmenu_call, // Item.CALL: R.string.contextmenu_send_message, // Item.SEND_MESSAGE:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 8b8f199a..d9c20f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -16,8 +16,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabPanel; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item; -import org.chromium.chrome.browser.experiments.EphemeralTab; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; @@ -79,7 +79,7 @@ Action.ADD_TO_CONTACTS, Action.CALL, Action.SEND_TEXT_MESSAGE, Action.COPY_PHONE_NUMBER, Action.OPEN_IN_NEW_CHROME_TAB, Action.OPEN_IN_CHROME_INCOGNITO_TAB, Action.OPEN_IN_BROWSER, Action.OPEN_IN_CHROME, - Action.SHARE_LINK, Action.OPEN_IN_EPHEMERAL_TAB, + Action.SHARE_LINK, Action.OPEN_IN_EPHEMERAL_TAB, Action.OPEN_IMAGE_IN_EPHEMERAL_TAB, }) @Retention(RetentionPolicy.SOURCE) public @interface Action { @@ -108,7 +108,8 @@ int OPEN_IN_CHROME = 36; int SHARE_LINK = 37; int OPEN_IN_EPHEMERAL_TAB = 38; - int NUM_ENTRIES = 39; + int OPEN_IMAGE_IN_EPHEMERAL_TAB = 39; + int NUM_ENTRIES = 40; } // Note: these values must match the ContextMenuSaveLinkType enum in enums.xml. @@ -258,7 +259,7 @@ if (mDelegate.isOpenInOtherWindowSupported()) { linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_OTHER_WINDOW)); } - if (EphemeralTab.isCapable()) { + if (EphemeralTabPanel.isSupported()) { linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_EPHEMERAL_TAB)); } } @@ -327,6 +328,9 @@ if (mMode == ContextMenuMode.NORMAL) { imageTab.add(new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_NEW_TAB)); } + if (EphemeralTabPanel.isSupported()) { + imageTab.add(new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_EPHEMERAL_TAB)); + } if (isSrcDownloadableScheme) { imageTab.add(new ChromeContextMenuItem(Item.SAVE_IMAGE)); hasSaveImage = true; @@ -417,13 +421,16 @@ mDelegate.onOpenInOtherWindow(params.getUrl(), params.getReferrer()); } else if (itemId == R.id.contextmenu_open_in_ephemeral_tab) { ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_EPHEMERAL_TAB); - mDelegate.onOpenInEphemeralTab(params.getUrl(), params.getReferrer()); + mDelegate.onOpenInEphemeralTab(params.getUrl(), params.getLinkText()); } else if (itemId == R.id.contextmenu_open_image) { ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE); mDelegate.onOpenImageUrl(params.getSrcUrl(), params.getReferrer()); } else if (itemId == R.id.contextmenu_open_image_in_new_tab) { ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE_IN_NEW_TAB); mDelegate.onOpenImageInNewTab(params.getSrcUrl(), params.getReferrer()); + } else if (itemId == R.id.contextmenu_open_image_in_ephemeral_tab) { + ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE_IN_EPHEMERAL_TAB); + mDelegate.onOpenInEphemeralTab(params.getSrcUrl(), params.getTitleText()); } else if (itemId == R.id.contextmenu_load_original_image) { ContextMenuUma.record(params, ContextMenuUma.Action.LOAD_ORIGINAL_IMAGE); DataReductionProxyUma.previewsLoFiContextMenuAction(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java index 05ab1b8..590bde13 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
@@ -186,9 +186,9 @@ void onOpenInDefaultBrowser(String url); /** - * Called when the {@code url} should be opened in an Ephemeral tab with the same incognito - * state as the current {@link Tab}. + * Called when the {@code url} should be opened in an ephemeral tab. * @param url The URL to open. + * @param title The title text to show on top control. */ - void onOpenInEphemeralTab(String url, Referrer referrer); + void onOpenInEphemeralTab(String url, String title); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/experiments/EphemeralTab.java b/chrome/android/java/src/org/chromium/chrome/browser/experiments/EphemeralTab.java deleted file mode 100644 index a5d7bff7..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/experiments/EphemeralTab.java +++ /dev/null
@@ -1,33 +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. -package org.chromium.chrome.browser.experiments; - -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.content_public.common.Referrer; - -/** - * Manages an Ephemeral Tab, which allows a "sneak peek" at a linked page using the Overlay Panel. - */ -public class EphemeralTab { - /** @return whether this feature is currently capable of being used. */ - public static boolean isCapable() { - // TODO(donnd): check if all the conditions are right to support an Overlay. - return isEnabled(); - } - - /** - * Called when an Open operation needs to be taken. - * @param url The URL of the page to open. - * @param referrer The current {@link Referrer}. - * @param isIncognito Whether the Overlay should use Incognito. - */ - public static void onOpen(String url, Referrer referrer, boolean isIncognito) { - // TODO(donnd): Implement. - } - - /** @return Whether this feature is enabled. */ - private static boolean isEnabled() { - return ChromeFeatureList.isEnabled(ChromeFeatureList.EPHEMERAL_TAB); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java index 1ce6edf..629b170 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
@@ -31,7 +31,6 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayUtil; @@ -251,6 +250,9 @@ mLayout.addAnimationListener(mIPHSupport); addObserver(mIPHSupport); + mTab.getWindowAndroid().getKeyboardDelegate().addKeyboardVisibilityListener( + this::updateVisibilityForKeyboard); + // Chromium's InfoBarContainer may add an InfoBar immediately during this initialization // call, so make sure everything in the InfoBarContainer is completely ready beforehand. mNativeInfoBarContainer = nativeInit(); @@ -517,15 +519,10 @@ } } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - // Hide the View when the keyboard is showing. + private void updateVisibilityForKeyboard(boolean isKeyboardShowing) { boolean isShowing = (getVisibility() == View.VISIBLE); - if (KeyboardVisibilityDelegate.getInstance().isKeyboardShowing( - getContext(), InfoBarContainer.this)) { + if (isKeyboardShowing) { if (isShowing) { - // Set to invisible (instead of gone) so that onLayout() will be called when the - // keyboard is dismissed. setVisibility(View.INVISIBLE); } } else { @@ -533,8 +530,6 @@ setVisibility(View.VISIBLE); } } - - super.onLayout(changed, l, t, r, b); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java index 83357a2..44d103a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.signin; +import android.os.SystemClock; import android.support.annotation.IntDef; import org.chromium.base.Log; @@ -11,6 +12,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.AsyncTask; import org.chromium.components.signin.AccountIdProvider; import org.chromium.components.signin.AccountManagerFacade; @@ -18,6 +20,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.TimeUnit; /** * Android wrapper of AccountTrackerService which provides access from the java layer. @@ -136,12 +139,20 @@ @Override public String[][] doInBackground() { Log.d(TAG, "Getting id/email mapping"); + + long seedingStartTime = SystemClock.elapsedRealtime(); + String[][] accountIdNameMap = new String[2][accounts.size()]; for (int i = 0; i < accounts.size(); ++i) { accountIdNameMap[0][i] = accountIdProvider.getAccountId(accounts.get(i).name); accountIdNameMap[1][i] = accounts.get(i).name; } + + RecordHistogram.recordTimesHistogram("Signin.AndroidGetAccountIdsTime", + SystemClock.elapsedRealtime() - seedingStartTime, + TimeUnit.MILLISECONDS); + return accountIdNameMap; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index 45c7a620..a1cc654 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -22,7 +22,6 @@ import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.download.ChromeDownloadDelegate; -import org.chromium.chrome.browser.experiments.EphemeralTab; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -223,6 +222,11 @@ } @Override + public void onOpenInEphemeralTab(String url, String title) { + mTab.getActivity().getEphemeralTabPanel().requestOpenPanel(url, title); + } + + @Override public void onOpenInChrome(String linkUrl, String pageUrl) { Context applicationContext = ContextUtils.getApplicationContext(); Intent chromeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); @@ -293,11 +297,6 @@ IntentUtils.safeStartActivity(mTab.getActivity(), intent); } - @Override - public void onOpenInEphemeralTab(String url, Referrer referrer) { - EphemeralTab.onOpen(url, referrer, isIncognito()); - } - /** * Checks if spdy proxy is enabled for input url. * @param url Input url to check for spdy setting.
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 574c684..41d9877 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2105,6 +2105,9 @@ <message name="IDS_CONTEXTMENU_OPEN_IMAGE_IN_NEW_TAB" desc="Context sensitive menu item for opening/viewing the selected image in a new tab. [CHAR-LIMIT=30]"> Open image in new tab </message> + <message name="IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB" desc="Context-sensitive menu item to open a quick preview of the selected image. In English we're currently calling this 'Sneak peek' which implies that it's a quick preview without commitment (to making a new Tab). The selected link will open in an overlay panel on top of the current tab which will go away easily too. [CHAR-LIMIT=30]"> + Sneak peek + </message> <message name="IDS_CONTEXTMENU_LOAD_ORIGINAL_IMAGE" desc="Context sensitive menu item for Data Saver low fidelity placeholder images that loads the original version in place. [CHAR-LIMIT=30]"> Load image </message>
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB.png.sha1 new file mode 100644 index 0000000..08480f1e --- /dev/null +++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB.png.sha1
@@ -0,0 +1 @@ +b76e9e3bdf35eaa7484958f29ce9da4e3a0c6b30 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IN_EPHEMERAL_TAB.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IN_EPHEMERAL_TAB.png.sha1 new file mode 100644 index 0000000..32a6d99 --- /dev/null +++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_OPEN_IN_EPHEMERAL_TAB.png.sha1
@@ -0,0 +1 @@ +1d97b6460747c21b975fe2dd3f756d1aa266f5ef \ No newline at end of file
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 546e317..18476cd 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -242,6 +242,8 @@ "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java", "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchQuickActionControl.java", "java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchTermControl.java", + "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabBarControl.java", + "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabPanel.java", "java/src/org/chromium/chrome/browser/compositor/layouts/ChromeAnimation.java", "java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java", "java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java", @@ -296,6 +298,7 @@ "java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java", "java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java", + "java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneOverlayLayer.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java", @@ -610,7 +613,6 @@ "java/src/org/chromium/chrome/browser/download/ui/OfflineGroupHeaderView.java", "java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java", "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java", - "java/src/org/chromium/chrome/browser/experiments/EphemeralTab.java", "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java", "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java", "java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesCategoryTileView.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/FakeKeyboard.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/FakeKeyboard.java index 7066c2e..cc92fd00 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/FakeKeyboard.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/FakeKeyboard.java
@@ -50,10 +50,10 @@ @Override public void showKeyboard(View view) { - boolean keyboardWasVisible = isKeyboardShowing(getActivity(), view); + boolean keyboardWasVisible = mIsShowing; mIsShowing = true; runOnUiThreadBlocking(() -> { - if (!keyboardWasVisible) notifyListeners(mIsShowing); + if (!keyboardWasVisible) notifyListeners(isKeyboardShowing(getActivity(), view)); // Pretend a layout change for components listening to the activity directly: View contentView = getActivity().findViewById(android.R.id.content); ViewGroup.LayoutParams p = contentView.getLayoutParams(); @@ -64,10 +64,10 @@ @Override protected boolean hideAndroidSoftKeyboard(View view) { - boolean keyboardWasVisible = isKeyboardShowing(getActivity(), view); + boolean keyboardWasVisible = mIsShowing; mIsShowing = false; runOnUiThreadBlocking(() -> { - if (keyboardWasVisible) notifyListeners(mIsShowing); + if (keyboardWasVisible) notifyListeners(isKeyboardShowing(getActivity(), view)); // Pretend a layout change for components listening to the activity directly: View contentView = getActivity().findViewById(android.R.id.content); ViewGroup.LayoutParams p = contentView.getLayoutParams();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingIntegrationTest.java index f59e330c..1ef6c90 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingIntegrationTest.java
@@ -465,4 +465,39 @@ mHelper.waitToBeHidden(withId(R.id.keyboard_accessory)); onView(withText(kSnackbarText)).check(matches(isCompletelyDisplayed())); } + + @Test + @SmallTest + public void testInfobarReopensOnPressingBack() + throws InterruptedException, TimeoutException, ExecutionException { + mHelper.loadTestPage(false); + + InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener(); + mActivityTestRule.getInfoBarContainer().addAnimationListener(listener); + final String kInfoBarText = "SomeInfoBar"; + ThreadUtils.runOnUiThread(() -> { + SimpleConfirmInfoBarBuilder.create(mActivityTestRule.getActivity().getActivityTab(), + InfoBarIdentifier.DUPLICATE_DOWNLOAD_INFOBAR_DELEGATE_ANDROID, kInfoBarText, + false); + }); + listener.addInfoBarAnimationFinished("InfoBar not added."); + + mHelper.createTestTab(); + assertThat(mActivityTestRule.getInfoBarContainer().getVisibility(), is(View.VISIBLE)); + + // Focus the field to bring up the accessory. + mHelper.clickPasswordField(); + whenDisplayed(withId(R.id.tabs)).perform(selectTabAtPosition(0)); + mHelper.waitForKeyboardToDisappear(); + whenDisplayed(withChild(withId(R.id.keyboard_accessory_sheet))); + assertThat(mActivityTestRule.getInfoBarContainer().getVisibility(), is(not(View.VISIBLE))); + + // Close the accessory using the back button. The Infobar should reappear. + Espresso.pressBack(); + + mHelper.waitToBeHidden(withChild(withId(R.id.keyboard_accessory_sheet))); + mHelper.waitToBeHidden(withId(R.id.keyboard_accessory)); + + whenDisplayed(withText(kInfoBarText)); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java index cf619c6..1f316eff 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java
@@ -227,7 +227,6 @@ notification = waitForNotification().notification; Assert.assertEquals(0, notification.flags & FLAG_ONGOING_EVENT); Assert.assertNotEquals(null, notification.deleteIntent); - Assert.assertEquals(0, NotificationCompat.getActionCount(notification)); PendingIntent deleteIntent = notification.deleteIntent; // The temporary tracing output file should now exist.
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c8eea42..a0511bf5 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2046,6 +2046,8 @@ "android/compositor/layer/content_layer.h", "android/compositor/layer/contextual_search_layer.cc", "android/compositor/layer/contextual_search_layer.h", + "android/compositor/layer/ephemeral_tab_layer.cc", + "android/compositor/layer/ephemeral_tab_layer.h", "android/compositor/layer/layer.h", "android/compositor/layer/overlay_panel_layer.cc", "android/compositor/layer/overlay_panel_layer.h", @@ -2065,6 +2067,8 @@ "android/compositor/resources/toolbar_resource.h", "android/compositor/scene_layer/contextual_search_scene_layer.cc", "android/compositor/scene_layer/contextual_search_scene_layer.h", + "android/compositor/scene_layer/ephemeral_tab_scene_layer.cc", + "android/compositor/scene_layer/ephemeral_tab_scene_layer.h", "android/compositor/scene_layer/scene_layer.cc", "android/compositor/scene_layer/scene_layer.h", "android/compositor/scene_layer/scrolling_bottom_view_scene_layer.cc", @@ -4663,6 +4667,7 @@ "../android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java", "../android/java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java", "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java", + "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java", "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java", "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java", "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 237ddbf86..3b9aee4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1499,9 +1499,6 @@ {"enable-javascript-harmony", flag_descriptions::kJavascriptHarmonyName, flag_descriptions::kJavascriptHarmonyDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kJavaScriptHarmony)}, - {"enable-webassembly", flag_descriptions::kEnableWasmName, - flag_descriptions::kEnableWasmDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kWebAssembly)}, {"enable-webassembly-baseline", flag_descriptions::kEnableWasmBaselineName, flag_descriptions::kEnableWasmBaselineDescription, kOsAll, FEATURE_VALUE_TYPE(features::kWebAssemblyBaseline)},
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index f04a562..1ed2b5f8 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -111,6 +111,16 @@ base::android::ConvertUTF8ToJavaString(env, message)); } +std::string UiControllerAndroid::GetStatusMessage() { + JNIEnv* env = AttachCurrentThread(); + std::string status; + base::android::ScopedJavaLocalRef<jstring> message = + Java_AutofillAssistantUiController_onGetStatusMessage( + env, java_autofill_assistant_ui_controller_); + base::android::ConvertJavaStringToUTF8(env, message.obj(), &status); + return status; +} + void UiControllerAndroid::ShowOverlay() { Java_AutofillAssistantUiController_onShowOverlay( AttachCurrentThread(), java_autofill_assistant_ui_controller_);
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index d6f3d1d..8c2613fe 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -38,6 +38,7 @@ // Overrides UiController: void SetUiDelegate(UiDelegate* ui_delegate) override; void ShowStatusMessage(const std::string& message) override; + std::string GetStatusMessage() override; void ShowOverlay() override; void HideOverlay() override; void Shutdown() override;
diff --git a/chrome/browser/android/compositor/layer/ephemeral_tab_layer.cc b/chrome/browser/android/compositor/layer/ephemeral_tab_layer.cc new file mode 100644 index 0000000..09681cea --- /dev/null +++ b/chrome/browser/android/compositor/layer/ephemeral_tab_layer.cc
@@ -0,0 +1,122 @@ +// 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/android/compositor/layer/ephemeral_tab_layer.h" + +#include "cc/layers/layer.h" +#include "cc/layers/nine_patch_layer.h" +#include "cc/resources/scoped_ui_resource.h" +#include "content/public/browser/android/compositor.h" +#include "ui/android/resources/nine_patch_resource.h" +#include "ui/android/resources/resource_manager.h" + +namespace android { +// static +scoped_refptr<EphemeralTabLayer> EphemeralTabLayer::Create( + ui::ResourceManager* resource_manager) { + return base::WrapRefCounted(new EphemeralTabLayer(resource_manager)); +} + +void EphemeralTabLayer::SetProperties( + int progress_bar_background_resource_id, + int progress_bar_resource_id, + float dp_to_px, + const scoped_refptr<cc::Layer>& content_layer, + float panel_x, + float panel_y, + float panel_width, + float panel_height, + float bar_margin_side, + float bar_height, + float text_opacity, + bool bar_border_visible, + float bar_border_height, + bool bar_shadow_visible, + float bar_shadow_opacity, + bool progress_bar_visible, + float progress_bar_height, + float progress_bar_opacity, + int progress_bar_completion) { + // Round values to avoid pixel gap between layers. + bar_height = floor(bar_height); + float bar_top = 0.f; + float bar_bottom = bar_top + bar_height; + bool should_render_progress_bar = + progress_bar_visible && progress_bar_opacity > 0.f; + + OverlayPanelLayer::SetProperties( + dp_to_px, content_layer, bar_height, panel_x, panel_y, panel_width, + panel_height, bar_margin_side, bar_height, 0.0f, text_opacity, + bar_border_visible, bar_border_height, bar_shadow_visible, + bar_shadow_opacity, 1.0f); + + // --------------------------------------------------------------------------- + // Progress Bar + // --------------------------------------------------------------------------- + + if (should_render_progress_bar) { + ui::NinePatchResource* progress_bar_background_resource = + ui::NinePatchResource::From(resource_manager_->GetResource( + ui::ANDROID_RESOURCE_TYPE_STATIC, + progress_bar_background_resource_id)); + ui::NinePatchResource* progress_bar_resource = + ui::NinePatchResource::From(resource_manager_->GetResource( + ui::ANDROID_RESOURCE_TYPE_STATIC, progress_bar_resource_id)); + + DCHECK(progress_bar_background_resource); + DCHECK(progress_bar_resource); + + // Progress Bar Background + if (progress_bar_background_->parent() != layer_) + layer_->AddChild(progress_bar_background_); + + float progress_bar_y = bar_bottom - progress_bar_height; + gfx::Size progress_bar_background_size(panel_width, progress_bar_height); + + progress_bar_background_->SetUIResourceId( + progress_bar_background_resource->ui_resource()->id()); + progress_bar_background_->SetBorder( + progress_bar_background_resource->Border(progress_bar_background_size)); + progress_bar_background_->SetAperture( + progress_bar_background_resource->aperture()); + progress_bar_background_->SetBounds(progress_bar_background_size); + progress_bar_background_->SetPosition(gfx::PointF(0.f, progress_bar_y)); + progress_bar_background_->SetOpacity(progress_bar_opacity); + + // Progress Bar + if (progress_bar_->parent() != layer_) + layer_->AddChild(progress_bar_); + + float progress_bar_width = + floor(panel_width * progress_bar_completion / 100.f); + gfx::Size progress_bar_size(progress_bar_width, progress_bar_height); + progress_bar_->SetUIResourceId(progress_bar_resource->ui_resource()->id()); + progress_bar_->SetBorder(progress_bar_resource->Border(progress_bar_size)); + progress_bar_->SetAperture(progress_bar_resource->aperture()); + progress_bar_->SetBounds(progress_bar_size); + progress_bar_->SetPosition(gfx::PointF(0.f, progress_bar_y)); + progress_bar_->SetOpacity(progress_bar_opacity); + } else { + // Removes Progress Bar and its Background from the Layer Tree. + if (progress_bar_background_.get() && progress_bar_background_->parent()) + progress_bar_background_->RemoveFromParent(); + + if (progress_bar_.get() && progress_bar_->parent()) + progress_bar_->RemoveFromParent(); + } +} + +EphemeralTabLayer::EphemeralTabLayer(ui::ResourceManager* resource_manager) + : OverlayPanelLayer(resource_manager), + progress_bar_(cc::NinePatchLayer::Create()), + progress_bar_background_(cc::NinePatchLayer::Create()) { + progress_bar_background_->SetIsDrawable(true); + progress_bar_background_->SetFillCenter(true); + progress_bar_->SetIsDrawable(true); + progress_bar_->SetFillCenter(true); +} + +EphemeralTabLayer::~EphemeralTabLayer() {} + +} // namespace android
diff --git a/chrome/browser/android/compositor/layer/ephemeral_tab_layer.h b/chrome/browser/android/compositor/layer/ephemeral_tab_layer.h new file mode 100644 index 0000000..f70c9fd --- /dev/null +++ b/chrome/browser/android/compositor/layer/ephemeral_tab_layer.h
@@ -0,0 +1,57 @@ +// 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_ANDROID_COMPOSITOR_LAYER_EPHEMERAL_TAB_LAYER_H_ +#define CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_EPHEMERAL_TAB_LAYER_H_ + +#include <memory> + +#include "chrome/browser/android/compositor/layer/overlay_panel_layer.h" + +namespace cc { +class Layer; +class NinePatchLayer; +} // namespace cc + +namespace ui { +class ResourceManager; +} + +namespace android { +class EphemeralTabLayer : public OverlayPanelLayer { + public: + static scoped_refptr<EphemeralTabLayer> Create( + ui::ResourceManager* resource_manager); + void SetProperties(int progress_bar_background_resource_id, + int progress_bar_resource_id, + float dp_to_px, + const scoped_refptr<cc::Layer>& content_layer, + float panel_x, + float panel_y, + float panel_width, + float panel_height, + float bar_margin_side, + float bar_height, + float text_opacity, + bool bar_border_visible, + float bar_border_height, + bool bar_shadow_visible, + float bar_shadow_opacity, + bool progress_bar_visible, + float progress_bar_height, + float progress_bar_opacity, + int progress_bar_completion); + + protected: + explicit EphemeralTabLayer(ui::ResourceManager* resource_manager); + ~EphemeralTabLayer() override; + + private: + scoped_refptr<cc::NinePatchLayer> progress_bar_; + scoped_refptr<cc::NinePatchLayer> progress_bar_background_; +}; + +} // namespace android + +#endif // CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_EPHEMERAL_TAB_LAYER_H_
diff --git a/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.cc new file mode 100644 index 0000000..67571aa --- /dev/null +++ b/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.cc
@@ -0,0 +1,149 @@ +// 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/android/compositor/scene_layer/ephemeral_tab_scene_layer.h" +#include "base/android/jni_android.h" +#include "base/android/jni_array.h" +#include "cc/layers/solid_color_layer.h" +#include "chrome/browser/android/compositor/layer/ephemeral_tab_layer.h" +#include "content/public/browser/android/compositor.h" +#include "content/public/browser/web_contents.h" +#include "jni/EphemeralTabSceneLayer_jni.h" +#include "ui/android/resources/resource_manager_impl.h" +#include "ui/android/view_android.h" +#include "ui/gfx/android/java_bitmap.h" + +using base::android::JavaParamRef; +using base::android::JavaRef; + +namespace android { + +EphemeralTabSceneLayer::EphemeralTabSceneLayer(JNIEnv* env, + const JavaRef<jobject>& jobj) + : SceneLayer(env, jobj), + base_page_brightness_(1.0f), + content_container_(cc::Layer::Create()) { + // Responsible for moving the base page without modifying the layer itself. + content_container_->SetIsDrawable(true); + content_container_->SetPosition(gfx::PointF(0.0f, 0.0f)); + layer()->AddChild(content_container_); +} + +EphemeralTabSceneLayer::~EphemeralTabSceneLayer() {} + +void EphemeralTabSceneLayer::CreateEphemeralTabLayer( + JNIEnv* env, + const JavaParamRef<jobject>& object, + const JavaParamRef<jobject>& jresource_manager) { + ui::ResourceManager* resource_manager = + ui::ResourceManagerImpl::FromJavaObject(jresource_manager); + ephemeral_tab_layer_ = EphemeralTabLayer::Create(resource_manager); + + // The layer is initially invisible. + ephemeral_tab_layer_->layer()->SetHideLayerAndSubtree(true); + layer()->AddChild(ephemeral_tab_layer_->layer()); +} + +void EphemeralTabSceneLayer::SetResourceIds(JNIEnv* env, + const JavaParamRef<jobject>& object, + jint text_resource_id, + jint bar_background_resource_id, + jint bar_shadow_resource_id, + jint panel_icon_resource_id, + jint close_icon_resource_id) { + ephemeral_tab_layer_->SetResourceIds( + text_resource_id, bar_background_resource_id, bar_shadow_resource_id, + panel_icon_resource_id, close_icon_resource_id); +} + +void EphemeralTabSceneLayer::Update(JNIEnv* env, + const JavaParamRef<jobject>& object, + jint progress_bar_background_resource_id, + jint progress_bar_resource_id, + jfloat dp_to_px, + jfloat base_page_brightness, + jfloat base_page_offset, + const JavaParamRef<jobject>& jweb_contents, + jfloat panel_X, + jfloat panel_y, + jfloat panel_width, + jfloat panel_height, + jfloat bar_margin_side, + jfloat bar_height, + jfloat text_opacity, + jboolean bar_border_visible, + jfloat bar_border_height, + jboolean bar_shadow_visible, + jfloat bar_shadow_opacity, + jboolean progress_bar_visible, + jfloat progress_bar_height, + jfloat progress_bar_opacity, + jint progress_bar_completion) { + // NOTE(mdjones): It is possible to render the panel before content has been + // created. If this is the case, do not attempt to access the WebContents + // and instead pass null. + content::WebContents* web_contents = + content::WebContents::FromJavaWebContents(jweb_contents); + scoped_refptr<cc::Layer> content_layer = + web_contents ? web_contents->GetNativeView()->GetLayer() : nullptr; + // Fade the base page out. + if (base_page_brightness_ != base_page_brightness) { + base_page_brightness_ = base_page_brightness; + cc::FilterOperations filters; + if (base_page_brightness < 1.f) { + filters.Append( + cc::FilterOperation::CreateBrightnessFilter(base_page_brightness)); + } + content_container_->SetFilters(filters); + } + // Move the base page contents up. + content_container_->SetPosition(gfx::PointF(0.0f, base_page_offset)); + ephemeral_tab_layer_->SetProperties( + progress_bar_background_resource_id, progress_bar_resource_id, dp_to_px, + content_layer, panel_X, panel_y, panel_width, panel_height, + bar_margin_side, bar_height, text_opacity, bar_border_visible, + bar_border_height, bar_shadow_visible, bar_shadow_opacity, + progress_bar_visible, progress_bar_height, progress_bar_opacity, + progress_bar_completion); + // Make the layer visible if it is not already. + ephemeral_tab_layer_->layer()->SetHideLayerAndSubtree(false); +} + +void EphemeralTabSceneLayer::SetContentTree( + JNIEnv* env, + const JavaParamRef<jobject>& jobj, + const JavaParamRef<jobject>& jcontent_tree) { + SceneLayer* content_tree = FromJavaObject(env, jcontent_tree); + if (!content_tree || !content_tree->layer()) + return; + if (!content_tree->layer()->parent() || + (content_tree->layer()->parent()->id() != content_container_->id())) { + content_container_->AddChild(content_tree->layer()); + } +} + +void EphemeralTabSceneLayer::HideTree(JNIEnv* env, + const JavaParamRef<jobject>& jobj) { + // TODO(mdjones): Create super class for this logic. + if (ephemeral_tab_layer_) { + ephemeral_tab_layer_->layer()->SetHideLayerAndSubtree(true); + } + // Reset base page brightness. + cc::FilterOperations filters; + filters.Append(cc::FilterOperation::CreateBrightnessFilter(1.0f)); + content_container_->SetFilters(filters); + // Reset base page offset. + content_container_->SetPosition(gfx::PointF(0.0f, 0.0f)); +} + +static jlong JNI_EphemeralTabSceneLayer_Init( + JNIEnv* env, + const JavaParamRef<jobject>& jobj) { + // This will automatically bind to the Java object and pass ownership there. + EphemeralTabSceneLayer* ephemeral_tab_scene_layer = + new EphemeralTabSceneLayer(env, jobj); + return reinterpret_cast<intptr_t>(ephemeral_tab_scene_layer); +} + +} // namespace android
diff --git a/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.h b/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.h new file mode 100644 index 0000000..4931df1b --- /dev/null +++ b/chrome/browser/android/compositor/scene_layer/ephemeral_tab_scene_layer.h
@@ -0,0 +1,89 @@ +// 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_ANDROID_COMPOSITOR_SCENE_LAYER_EPHEMERAL_TAB_SCENE_LAYER_H_ +#define CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_EPHEMERAL_TAB_SCENE_LAYER_H_ + +#include <memory> +#include <vector> + +#include "base/android/jni_android.h" +#include "base/android/jni_weak_ref.h" +#include "base/android/scoped_java_ref.h" +#include "base/macros.h" +#include "chrome/browser/android/compositor/scene_layer/scene_layer.h" +#include "ui/android/resources/resource_manager_impl.h" + +namespace cc { +class Layer; +class SolidColorLayer; +} // namespace cc + +namespace android { + +class EphemeralTabLayer; + +class EphemeralTabSceneLayer : public SceneLayer { + public: + EphemeralTabSceneLayer(JNIEnv* env, + const base::android::JavaRef<jobject>& jobj); + ~EphemeralTabSceneLayer() override; + + void CreateEphemeralTabLayer( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + const base::android::JavaParamRef<jobject>& jresource_manager); + + void SetResourceIds(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + jint text_resource_id, + jint bar_background_resource_id, + jint bar_shadow_resource_id, + jint panel_icon_resource_id, + jint close_icon_resource_id); + + void Update(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + jint progress_bar_background_resource_id, + jint progress_bar_resource_id, + jfloat dp_to_px, + jfloat base_page_brightness, + jfloat base_page_offset, + const base::android::JavaParamRef<jobject>& jcontent_view_core, + jfloat panel_X, + jfloat panel_y, + jfloat panel_width, + jfloat panel_height, + jfloat bar_margin_side, + jfloat bar_height, + jfloat text_opacity, + jboolean bar_border_visible, + jfloat bar_border_height, + jboolean bar_shadow_visible, + jfloat bar_shadow_opacity, + jboolean progress_bar_visible, + jfloat progress_bar_height, + jfloat progress_bar_opacity, + jint progress_bar_completion); + + void SetContentTree( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + const base::android::JavaParamRef<jobject>& jcontent_tree); + + void HideTree(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); + + private: + float base_page_brightness_; + scoped_refptr<cc::Layer> content_layer_; + scoped_refptr<EphemeralTabLayer> ephemeral_tab_layer_; + scoped_refptr<cc::SolidColorLayer> color_overlay_; + scoped_refptr<cc::Layer> content_container_; + DISALLOW_COPY_AND_ASSIGN(EphemeralTabSceneLayer); +}; + +bool RegisterEphemeralTabSceneLayer(JNIEnv* env); +} // namespace android + +#endif // CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_EPHEMERAL_TAB_SCENE_LAYER_H_
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index c0459f7..c2d663c 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -66,7 +66,6 @@ #include "content/public/test/simple_url_loader_test_helper.h" #include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/google_service_auth_error.h" -#include "media/base/media_switches.h" #include "media/mojo/services/video_decode_perf_history.h" #include "net/cookies/canonical_cookie.h" #include "net/dns/mock_host_resolver.h" @@ -81,15 +80,6 @@ #include "third_party/re2/src/re2/re2.h" #include "url/gurl.h" -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) -#if defined(OS_MACOSX) -#include "base/threading/platform_thread.h" -#endif -#include "base/memory/scoped_refptr.h" -#include "chrome/browser/browsing_data/browsing_data_media_license_helper.h" -#include "chrome/browser/media/library_cdm_test_helper.h" -#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - using content::BrowserThread; using content::BrowsingDataFilterBuilder; @@ -291,7 +281,14 @@ class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest { public: - BrowsingDataRemoverBrowserTest() {} + BrowsingDataRemoverBrowserTest() { + feature_list_.InitWithFeatures( + {leveldb::kLevelDBRewriteFeature, + // Ensure that kOnionSoupDOMStorage is enabled because the old + // SessionStorage implementation causes flaky tests. + blink::features::kOnionSoupDOMStorage}, + {}); + } // Call to use an Incognito browser rather than the default. void UseIncognitoBrowser() { @@ -355,22 +352,16 @@ } void RemoveAndWait(int remove_mask) { - RemoveAndWait(remove_mask, base::Time(), base::Time::Max()); + RemoveAndWait(remove_mask, base::Time()); } void RemoveAndWait(int remove_mask, base::Time delete_begin) { - RemoveAndWait(remove_mask, delete_begin, base::Time::Max()); - } - - void RemoveAndWait(int remove_mask, - base::Time delete_begin, - base::Time delete_end) { content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover( GetBrowser()->profile()); content::BrowsingDataRemoverCompletionObserver completion_observer(remover); remover->RemoveAndReply( - delete_begin, delete_end, remove_mask, + delete_begin, base::Time::Max(), remove_mask, content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &completion_observer); completion_observer.BlockUntilCompletion(); @@ -456,30 +447,6 @@ return count; } -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) - int GetMediaLicenseCount() { - base::RunLoop run_loop; - int count = -1; - content::StoragePartition* partition = - content::BrowserContext::GetDefaultStoragePartition( - browser()->profile()); - scoped_refptr<BrowsingDataMediaLicenseHelper> media_license_helper = - BrowsingDataMediaLicenseHelper::Create( - partition->GetFileSystemContext()); - media_license_helper->StartFetching(base::BindLambdaForTesting( - [&](const std::list<BrowsingDataMediaLicenseHelper::MediaLicenseInfo>& - licenses) { - count = licenses.size(); - LOG(INFO) << "Found " << count << " licenses."; - for (const auto& license : licenses) - LOG(INFO) << license.last_modified_time; - run_loop.Quit(); - })); - run_loop.Run(); - return count; - } -#endif - inline void ExpectCookieTreeModelCount(int expected) { std::unique_ptr<CookiesTreeModel> model = GetCookiesTreeModel(); EXPECT_EQ(expected, GetCookiesTreeModelCount(model->GetRoot())) @@ -554,25 +521,6 @@ return model; } - void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); - - std::vector<base::Feature> enabled_features = { - leveldb::kLevelDBRewriteFeature, - // Ensure that kOnionSoupDOMStorage is enabled because the old - // SessionStorage implementation causes flaky tests. - blink::features::kOnionSoupDOMStorage}; - -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) - // Testing MediaLicenses requires additional command line parameters as - // it uses the External Clear Key CDM. - RegisterClearKeyCdm(command_line); - enabled_features.push_back(media::kExternalClearKeyForTesting); -#endif - - feature_list_.InitWithFeatures(enabled_features, {}); - } - base::test::ScopedFeatureList feature_list_; Browser* incognito_browser_ = nullptr; }; @@ -1095,127 +1043,6 @@ TestEmptySiteData("IndexedDb", GetParam()); } -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) -// Test Media Licenses by creating one and checking it is counted by the -// cookie counter. Then delete it and check that the cookie counter is back -// to zero. -IN_PROC_BROWSER_TEST_P(BrowsingDataRemoverBrowserTestP, MediaLicenseDeletion) { - const std::string kMediaLicenseType = "MediaLicense"; - const base::Time delete_begin = GetParam(); - - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(0, GetMediaLicenseCount()); - GURL url = - embedded_test_server()->GetURL("/browsing_data/media_license.html"); - ui_test_utils::NavigateToURL(browser(), url); - - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(0, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(0); - EXPECT_FALSE(HasDataForType(kMediaLicenseType)); - - SetDataForType(kMediaLicenseType); - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(1, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(1); - EXPECT_TRUE(HasDataForType(kMediaLicenseType)); - - // Try to remove the Media Licenses using a time frame up until an hour ago, - // which should not remove the recently created Media License. - RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, - delete_begin, kLastHour); - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(1, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(1); - EXPECT_TRUE(HasDataForType(kMediaLicenseType)); - - // Now try with a time range that includes the current time, which should - // clear the Media License created for this test. - RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, - delete_begin, base::Time::Max()); - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(0, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(0); - EXPECT_FALSE(HasDataForType(kMediaLicenseType)); -} - -// Create and save a media license (which will be deleted in the following -// test). -IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, - PRE_MediaLicenseTimedDeletion) { - const std::string kMediaLicenseType = "MediaLicense"; - - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(0, GetMediaLicenseCount()); - - GURL url = - embedded_test_server()->GetURL("/browsing_data/media_license.html"); - ui_test_utils::NavigateToURL(browser(), url); - - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(0, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(0); - EXPECT_FALSE(HasDataForType(kMediaLicenseType)); - - SetDataForType(kMediaLicenseType); - EXPECT_EQ(0, GetSiteDataCount()); - EXPECT_EQ(1, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(1); - EXPECT_TRUE(HasDataForType(kMediaLicenseType)); -} - -// Create and save a second media license, and then verify that timed deletion -// selects the correct license to delete. -IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, - MediaLicenseTimedDeletion) { - const std::string kMediaLicenseType = "MediaLicense"; - - // As the PRE_ test should run first, there should be one media license - // still stored. The time of it's creation should be sometime before - // this test starts. We can't see the license, since it's stored for a - // different origin (but we can delete it). - const base::Time start = base::Time::Now(); - LOG(INFO) << "MediaLicenseTimedDeletion starting @ " << start; - EXPECT_EQ(1, GetMediaLicenseCount()); - - GURL url = - embedded_test_server()->GetURL("/browsing_data/media_license.html"); - ui_test_utils::NavigateToURL(browser(), url); - - // This test should use a different domain than the PRE_ test, so there - // should be no existing media license for it. - EXPECT_FALSE(HasDataForType(kMediaLicenseType)); - -#if defined(OS_MACOSX) - // On some Macs the file system uses second granularity. So before - // creating the second license, delay for 1 second so that the new - // license's time is not the same second as |start|. - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); -#endif - - // Create a media license for this domain. - SetDataForType(kMediaLicenseType); - EXPECT_EQ(2, GetMediaLicenseCount()); - EXPECT_TRUE(HasDataForType(kMediaLicenseType)); - - // Try to remove the Media Licenses using a time frame up until the start - // of this test, which should only delete the media license created by - // the PRE_ test. - RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, - base::Time(), start); - EXPECT_EQ(1, GetMediaLicenseCount()); - EXPECT_TRUE(HasDataForType(kMediaLicenseType)); - - // Now try with a time range that includes the current time, which should - // clear the media license created as part of this test. - RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, - base::Time(), base::Time::Now()); - EXPECT_EQ(0, GetMediaLicenseCount()); - ExpectCookieTreeModelCount(0); - EXPECT_FALSE(HasDataForType(kMediaLicenseType)); -} -#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - const std::vector<std::string> kStorageTypes{ "Cookie", "LocalStorage", "FileSystem", "SessionStorage", "IndexedDb", "WebSql", "ServiceWorker", "CacheStorage",
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 61fcb1c3..3acc593 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -783,16 +783,6 @@ ChromeAuthenticatorRequestDelegate:: TouchIdAuthenticatorConfigForProfile(profile_)) .DeleteCredentials(delete_begin_, delete_end_); - - // When clearing passwords for all time, reset preferences that are used to - // prevent overwriting the encryption key in the Keychain. - if (IsForAllTime()) { - PrefService* local_state = g_browser_process->local_state(); - if (local_state) { - local_state->ClearPref(os_crypt::prefs::kKeyCreated); - local_state->ClearPref(os_crypt::prefs::kKeyOverwritingPreventions); - } - } #endif // defined(OS_MACOSX) }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9773e90..bb63d42 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3716,14 +3716,6 @@ services->insert( std::make_pair(prefs::mojom::kLocalStateServiceName, info)); } - service_manager::EmbeddedServiceInfo info; -#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) - { - service_manager::EmbeddedServiceInfo info; - info.factory = base::Bind(&media::CreateMediaService); - services->insert(std::make_pair(media::mojom::kMediaServiceName, info)); - } -#endif #if defined(OS_ANDROID) { @@ -3877,6 +3869,17 @@ #endif } +void ChromeContentBrowserClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { +#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) + if (service_name == media::mojom::kMediaServiceName) { + service_manager::Service::RunUntilTermination( + media::CreateMediaService(std::move(request))); + } +#endif +} + bool ChromeContentBrowserClient::ShouldTerminateOnServiceQuit( const service_manager::Identity& id) { #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 23a3f2a..eefdb5f 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -397,6 +397,9 @@ content::ServiceManagerConnection* connection) override; void RegisterOutOfProcessServices( OutOfProcessServiceMap* services) override; + void HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; bool ShouldTerminateOnServiceQuit( const service_manager::Identity& id) override; std::unique_ptr<base::Value> GetServiceManifestOverlay(
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 763d775..b0ce3e2 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -487,6 +487,8 @@ "arc/intent_helper/start_smart_selection_action_menu.h", "arc/kiosk/arc_kiosk_bridge.cc", "arc/kiosk/arc_kiosk_bridge.h", + "arc/metrics/arc_metrics_service_proxy.cc", + "arc/metrics/arc_metrics_service_proxy.h", "arc/notification/arc_boot_error_notification.cc", "arc/notification/arc_boot_error_notification.h", "arc/notification/arc_provision_notification_service.cc",
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index bebb679..2c733f2 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.h" #include "chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h" #include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" +#include "chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.h" #include "chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h" #include "chrome/browser/chromeos/arc/notification/arc_provision_notification_service.h" #include "chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h" @@ -174,6 +175,7 @@ ArcLockScreenBridge::GetForBrowserContext(profile); ArcMediaSessionBridge::GetForBrowserContext(profile); ArcMetricsService::GetForBrowserContext(profile); + ArcMetricsServiceProxy::GetForBrowserContext(profile); ArcMidisBridge::GetForBrowserContext(profile); ArcNetHostImpl::GetForBrowserContext(profile)->SetPrefService( profile->GetPrefs());
diff --git a/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.cc b/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.cc new file mode 100644 index 0000000..25eaf42 --- /dev/null +++ b/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.cc
@@ -0,0 +1,69 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/arc/metrics/arc_metrics_service.h" + +namespace arc { +namespace { + +class ArcMetricsServiceProxyFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcMetricsServiceProxy, + ArcMetricsServiceProxyFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcMetricsServiceProxyFactory"; + + static ArcMetricsServiceProxyFactory* GetInstance() { + return base::Singleton<ArcMetricsServiceProxyFactory>::get(); + } + + private: + friend base::DefaultSingletonTraits<ArcMetricsServiceProxyFactory>; + + ArcMetricsServiceProxyFactory() { + DependsOn(ArcAppListPrefsFactory::GetInstance()); + DependsOn(ArcMetricsService::GetFactory()); + } + + ~ArcMetricsServiceProxyFactory() override = default; +}; + +} // namespace + +// static +ArcMetricsServiceProxy* ArcMetricsServiceProxy::GetForBrowserContext( + content::BrowserContext* context) { + return ArcMetricsServiceProxyFactory::GetForBrowserContext(context); +} + +ArcMetricsServiceProxy::ArcMetricsServiceProxy( + content::BrowserContext* context, + ArcBridgeService* arc_bridge_service) + : arc_app_list_prefs_(ArcAppListPrefs::Get(context)), + arc_metrics_service_(ArcMetricsService::GetForBrowserContext(context)) { + arc_app_list_prefs_->AddObserver(this); +} + +void ArcMetricsServiceProxy::Shutdown() { + arc_app_list_prefs_->RemoveObserver(this); +} + +void ArcMetricsServiceProxy::OnTaskCreated(int32_t task_id, + const std::string& package_name, + const std::string& activity, + const std::string& intent) { + arc_metrics_service_->OnTaskCreated(task_id, package_name, activity, intent); +} + +void ArcMetricsServiceProxy::OnTaskDestroyed(int32_t task_id) { + arc_metrics_service_->OnTaskDestroyed(task_id); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.h b/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.h new file mode 100644 index 0000000..ad70601 --- /dev/null +++ b/chrome/browser/chromeos/arc/metrics/arc_metrics_service_proxy.h
@@ -0,0 +1,53 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_METRICS_ARC_METRICS_SERVICE_PROXY_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_METRICS_ARC_METRICS_SERVICE_PROXY_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace arc { + +class ArcBridgeService; +class ArcMetricsService; + +// Proxy to ArcMetricsService for functionalities that depend on code under +// chrome/browser. Should be merged into ArcMetricsService once dependency +// issues are cleared. TODO(crbug.com/903048): Remove the proxy. +class ArcMetricsServiceProxy : public KeyedService, + public ArcAppListPrefs::Observer { + public: + static ArcMetricsServiceProxy* GetForBrowserContext( + content::BrowserContext* context); + + ArcMetricsServiceProxy(content::BrowserContext* context, + ArcBridgeService* arc_bridge_service); + ~ArcMetricsServiceProxy() override = default; + + // KeyedService overrides. + void Shutdown() override; + + // ArcAppListPrefs::Observer overrides. + void OnTaskCreated(int32_t task_id, + const std::string& package_name, + const std::string& activity, + const std::string& intent) override; + void OnTaskDestroyed(int32_t task_id) override; + + private: + ArcAppListPrefs* const arc_app_list_prefs_; + ArcMetricsService* const arc_metrics_service_; + + DISALLOW_COPY_AND_ASSIGN(ArcMetricsServiceProxy); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_METRICS_ARC_METRICS_SERVICE_PROXY_H_
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index d6f2d08..b28ec32 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -282,6 +282,7 @@ ZipCase("zipFileOpenDownloadsShiftJIS"), ZipCase("zipFileOpenDownloadsMacOs"), ZipCase("zipFileOpenDownloadsWithAbsolutePaths"), + ZipCase("zipFileOpenDownloadsEncryptedCancelPassphrase"), ZipCase("zipFileOpenDrive").DisableDriveFs(), ZipCase("zipFileOpenDrive").EnableDriveFs(), ZipCase("zipFileOpenUsb"), @@ -444,6 +445,7 @@ TestCase("openQuickViewCrostini"), TestCase("openQuickViewUsb"), TestCase("openQuickViewMtp"), + TestCase("pressEnterOnInfoBoxToOpenClose"), TestCase("closeQuickView"))); WRAPPED_INSTANTIATE_TEST_CASE_P(
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 681c27a88..90b87a4 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -18,7 +18,9 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" @@ -1600,6 +1602,71 @@ return; } + if (name == "getAppWindowId") { + std::string window_url; + ASSERT_TRUE(value.GetString("windowUrl", &window_url)); + + const auto& app_windows = + extensions::AppWindowRegistry::Get(profile())->app_windows(); + ASSERT_FALSE(app_windows.empty()); + *output = "none"; + for (auto* window : app_windows) { + if (!window->web_contents()) + continue; + + if (window->web_contents()->GetLastCommittedURL() == window_url) { + *output = base::NumberToString(window->session_id().id()); + break; + } + } + return; + } + + if (name == "countAppWindows") { + std::string app_id; + ASSERT_TRUE(value.GetString("appId", &app_id)); + + const auto& app_windows = + extensions::AppWindowRegistry::Get(profile())->app_windows(); + ASSERT_FALSE(app_windows.empty()); + int window_count = 0; + for (auto* window : app_windows) { + if (window->extension_id() == app_id) + window_count++; + } + *output = base::NumberToString(window_count); + return; + } + + if (name == "runJsInAppWindow") { + std::string window_id_str; + ASSERT_TRUE(value.GetString("windowId", &window_id_str)); + int window_id = 0; + ASSERT_TRUE(base::StringToInt(window_id_str, &window_id)); + std::string script; + ASSERT_TRUE(value.GetString("script", &script)); + + const auto& app_windows = + extensions::AppWindowRegistry::Get(profile())->app_windows(); + ASSERT_FALSE(app_windows.empty()); + for (auto* window : app_windows) { + CHECK(window); + if (window->session_id().id() != window_id) { + continue; + } + + if (!window->web_contents()) + break; + + CHECK(window->web_contents()->GetMainFrame()); + window->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests( + base::UTF8ToUTF16(script)); + + break; + } + return; + } + if (name == "enableTabletMode") { ::test::SetAndWaitForTabletMode(true); *output = "tabletModeEnabled";
diff --git a/chrome/browser/chromeos/file_manager/file_manager_uitest.cc b/chrome/browser/chromeos/file_manager/file_manager_uitest.cc index d742644..ec7d81d 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_uitest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_uitest.cc
@@ -73,10 +73,6 @@ RunTest("crostiniTasks"); } -IN_PROC_BROWSER_TEST_F(FileManagerUITest, QuickView) { - RunTest("quickview"); -} - IN_PROC_BROWSER_TEST_F(FileManagerUITest, UMA) { RunTest("uma"); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index cf59624..c961c7e 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1985,17 +1985,17 @@ }, { "name": "enable-webassembly", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "titzer", "wasm-team@google.com" ], + "expiry_milestone": 72 }, { "name": "enable-webassembly-baseline", - // "owners": [ "your-team" ], + "owners": [ "clemensh", "wasm-team@google.com" ], "expiry_milestone": 76 }, { "name": "enable-webassembly-threads", - // "owners": [ "your-team" ], + "owners": [ "binji", "hablich", "wasm-team@google.com" ], "expiry_milestone": 76 }, {
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index aad25d8..a41f3601 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -281,6 +281,9 @@ { key::kMachineLevelUserCloudPolicyEnrollmentToken, policy_prefs::kMachineLevelUserCloudPolicyEnrollmentToken, base::Value::Type::STRING }, + { key::kCloudManagementEnrollmentMandatory, + policy_prefs::kCloudManagementEnrollmentMandatory, + base::Value::Type::BOOLEAN }, { key::kRequireOnlineRevocationChecksForLocalAnchors, prefs::kCertRevocationCheckingRequiredLocalAnchors, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc index 1842c5ed..42f0c7b6 100644 --- a/chrome/browser/profiles/profiles_state.cc +++ b/chrome/browser/profiles/profiles_state.cc
@@ -34,9 +34,7 @@ #include <algorithm> #include "chrome/browser/profiles/gaia_info_update_service.h" #include "chrome/browser/profiles/gaia_info_update_service_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_error_controller_factory.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_pref_names.h" #endif
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index c15c0679..41007c1 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -1029,43 +1029,31 @@ void RenderViewContextMenu::AppendLinkItems() { if (!params_.link_url.is_empty()) { - if (base::FeatureList::IsEnabled(features::kDesktopPWAWindowing)) { - const Browser* browser = GetBrowser(); - const bool is_app = browser && browser->is_app(); + const Browser* browser = GetBrowser(); + const bool in_app = + base::FeatureList::IsEnabled(features::kDesktopPWAWindowing) && + browser && browser->is_app(); - AppendOpenInBookmarkAppLinkItems(); + AppendOpenInBookmarkAppLinkItems(); - menu_model_.AddItemWithStringId( - IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, - is_app ? IDS_CONTENT_CONTEXT_OPENLINKNEWTAB_INAPP - : IDS_CONTENT_CONTEXT_OPENLINKNEWTAB); - if (!is_app) { - menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, - IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW); - } - - if (params_.link_url.is_valid()) { - AppendProtocolHandlerSubMenu(); - } - - menu_model_.AddItemWithStringId( - IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, - is_app ? IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD_INAPP - : IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); - - } else { - menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, - IDS_CONTENT_CONTEXT_OPENLINKNEWTAB); + menu_model_.AddItemWithStringId( + IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, + in_app ? IDS_CONTENT_CONTEXT_OPENLINKNEWTAB_INAPP + : IDS_CONTENT_CONTEXT_OPENLINKNEWTAB); + if (!in_app) { menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW); - if (params_.link_url.is_valid()) { - AppendProtocolHandlerSubMenu(); - } - - menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, - IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); } + if (params_.link_url.is_valid()) { + AppendProtocolHandlerSubMenu(); + } + + menu_model_.AddItemWithStringId( + IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, + in_app ? IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD_INAPP + : IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); + AppendOpenWithLinkItems(); // While ChromeOS supports multiple profiles, only one can be open at a @@ -1187,6 +1175,9 @@ } void RenderViewContextMenu::AppendOpenInBookmarkAppLinkItems() { + if (!base::FeatureList::IsEnabled(features::kDesktopPWAWindowing)) + return; + const Extension* pwa = extensions::util::GetInstalledPwaForUrl( browser_context_, params_.link_url); if (!pwa)
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher.cc b/chrome/browser/resource_coordinator/tab_activity_watcher.cc index 00a2e3a..f43bd511 100644 --- a/chrome/browser/resource_coordinator/tab_activity_watcher.cc +++ b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
@@ -68,18 +68,13 @@ if (lru_index >= GetNumOldestTabsToScoreWithTabRanker()) return base::nullopt; - const Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); - if (!browser) + base::Optional<tab_ranker::TabFeatures> tab = GetTabFeatures(mru); + if (!tab.has_value()) return base::nullopt; - tab_ranker::TabFeatures tab = TabMetricsLogger::GetTabFeatures( - browser, tab_metrics_, NowTicks() - backgrounded_time_); - tab_ranker::WindowFeatures window = - WindowActivityWatcher::CreateWindowFeatures(browser); - float score; tab_ranker::TabRankerResult result = - TabActivityWatcher::GetInstance()->predictor_.ScoreTab(tab, window, mru, + TabActivityWatcher::GetInstance()->predictor_.ScoreTab(tab.value(), &score); if (result == tab_ranker::TabRankerResult::kSuccess) return score; @@ -140,8 +135,10 @@ // Logs TabMetrics for the tab if it is considered to be backgrounded. void LogTabIfBackgrounded() { if (!backgrounded_time_.is_null()) { - TabActivityWatcher::GetInstance()->tab_metrics_logger_->LogBackgroundTab( - ukm_source_id_, tab_metrics_); + base::Optional<tab_ranker::TabFeatures> tab = GetTabFeatures(); + if (tab.has_value()) + TabActivityWatcher::GetInstance()->tab_metrics_logger_->LogTabMetrics( + ukm_source_id_, tab.value(), web_contents()); } } @@ -203,13 +200,7 @@ return; // Log the event before updating times. - const ukm::SourceId source_id = discarded_since_backgrounded_ - ? previous_ukm_source_id_ - : ukm_source_id_; - TabActivityWatcher::GetInstance() - ->tab_metrics_logger_->LogBackgroundTabShown( - source_id, NowTicks() - backgrounded_time_, GetMRUFeatures(), - discarded_since_backgrounded_); + LogForegroundedOrClosedMetrics(true /* is_foregrounded */); backgrounded_time_ = base::TimeTicks(); foregrounded_time_ = NowTicks(); @@ -372,8 +363,54 @@ webcontents_a->creation_time_ > webcontents_b->creation_time_); } + // Returns the tabfeatures of current tab by combining TabMetrics, + // WindowFeatures and MRUFeatures. + base::Optional<tab_ranker::TabFeatures> GetTabFeatures( + const tab_ranker::MRUFeatures& mru = tab_ranker::MRUFeatures()) { + const Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); + if (!browser) + return base::nullopt; + + // For tab features. + tab_ranker::TabFeatures tab = TabMetricsLogger::GetTabFeatures( + browser, tab_metrics_, NowTicks() - backgrounded_time_); + + // For window features. + tab_ranker::WindowFeatures window = + WindowActivityWatcher::CreateWindowFeatures(browser); + tab.window_is_active = window.is_active; + tab.window_show_state = window.show_state; + tab.window_tab_count = window.tab_count; + tab.window_type = window.type; + + // For mru features. + tab.mru_index = mru.index; + tab.total_tab_count = mru.total; + return tab; + } + + // Collect current ForegroundedOrClosedMetrics and send to ukm. + void LogForegroundedOrClosedMetrics(bool is_foregrounded) { + TabMetricsLogger::ForegroundedOrClosedMetrics metrics; + metrics.is_foregrounded = is_foregrounded; + metrics.is_discarded = discarded_since_backgrounded_; + metrics.time_from_backgrounded = + (NowTicks() - backgrounded_time_).InMilliseconds(); + const auto mru = GetMRUFeatures(); + metrics.mru_index = mru.index; + metrics.total_tab_count = mru.total; + + const ukm::SourceId source_id = discarded_since_backgrounded_ + ? previous_ukm_source_id_ + : ukm_source_id_; + TabActivityWatcher::GetInstance() + ->tab_metrics_logger_->LogForegroundedOrClosedMetrics(source_id, + metrics); + } + // Updated when a navigation is finished. ukm::SourceId ukm_source_id_ = 0; + // Recorded when a WebContents is replaced by another. ukm::SourceId previous_ukm_source_id_ = 0; @@ -577,16 +614,10 @@ // Log ForegroundedOrClosed event. if (!web_contents_data->backgrounded_time_.is_null()) { - const ukm::SourceId source_id = - web_contents_data->discarded_since_backgrounded_ - ? web_contents_data->previous_ukm_source_id_ - : web_contents_data->ukm_source_id_; - - tab_metrics_logger_->LogBackgroundTabClosed( - source_id, NowTicks() - web_contents_data->backgrounded_time_, - web_contents_data->GetMRUFeatures(), - web_contents_data->discarded_since_backgrounded_); + web_contents_data->LogForegroundedOrClosedMetrics( + false /*is_foregrounded */); } + // Erase the pointer in |all_closing_tabs_| only when all logging finished. all_closing_tabs_.erase(web_contents_data); }
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc b/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc index 09c60c5..edad911 100644 --- a/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" +#include "chrome/browser/resource_coordinator/tab_metrics_event.pb.h" #include "chrome/browser/resource_coordinator/time.h" #include "chrome/browser/resource_coordinator/utils.h" #include "chrome/browser/ui/browser.h" @@ -237,8 +238,6 @@ EXPECT_EQ(0u, ukm_entry_checker_->NumEntries(kEntryName)); UkmMetricMap expected_metrics = kBasicMetricValues; - expected_metrics[TabManager_TabMetrics::kWindowIdName] = - browser()->session_id().id(); // Adding a new foreground tab logs the previously active tab. AddTabAtIndex(1, kTabUrls[1], ui::PAGE_TRANSITION_LINK); @@ -293,9 +292,6 @@ kCheckNavigationSuccess); { SCOPED_TRACE(""); - UkmMetricMap expected_metrics = kBasicMetricValues; - expected_metrics[TabManager_TabMetrics::kWindowIdName] = - browser()->session_id().id(); ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), kBasicMetricValues); } @@ -303,9 +299,6 @@ kCheckNavigationSuccess); { SCOPED_TRACE(""); - UkmMetricMap expected_metrics = kBasicMetricValues; - expected_metrics[TabManager_TabMetrics::kWindowIdName] = - browser_2->session_id().id(); ukm_entry_checker_->ExpectNewEntry(kEntryName, GURL(), kBasicMetricValues); } @@ -360,9 +353,10 @@ kCheckNavigationSuccess); { SCOPED_TRACE(""); - ukm_entry_checker_->ExpectNewEntry( - kEntryName, kBrowserStartUrl, - {{TabManager_TabMetrics::kWindowIdName, browser()->session_id().id()}}); + UkmMetricMap expected_metrics_1 = kBasicMetricValues; + expected_metrics_1[TabManager_TabMetrics::kNavigationEntryCountName] = 2; + ukm_entry_checker_->ExpectNewEntry(kEntryName, kBrowserStartUrl, + expected_metrics_1); } // "Drag" the new tab out of its browser. @@ -387,9 +381,10 @@ // inserted. { SCOPED_TRACE(""); - ukm_entry_checker_->ExpectNewEntry( - kEntryName, kBrowser2StartUrl, - {{TabManager_TabMetrics::kWindowIdName, browser_2->session_id().id()}}); + UkmMetricMap expected_metrics_2 = kBasicMetricValues; + expected_metrics_2[TabManager_TabMetrics::kNavigationEntryCountName] = 2; + ukm_entry_checker_->ExpectNewEntry(kEntryName, kBrowser2StartUrl, + expected_metrics_2); } // Closing the window with 2 tabs means we log the backgrounded tab as closed. @@ -467,4 +462,24 @@ } } +// Tests that all window metrics are logged with correct value which are +// different from their default values in TabFeatures. +IN_PROC_BROWSER_TEST_F(TabActivityWatcherUkmTest, + AllWindowMetricsArePopulated) { + ui_test_utils::NavigateToURL(browser(), test_urls_[0]); + + // Adding a new foreground tab logs the previously active tab. + AddTabAtIndex(1, test_urls_[1], ui::PAGE_TRANSITION_LINK); + { + SCOPED_TRACE(""); + UkmMetricMap expected_metrics = { + {"WindowShowState", metrics::WindowMetricsEvent::SHOW_STATE_NORMAL}, + {"WindowTabCount", 2}, + {"WindowType", metrics::WindowMetricsEvent::TYPE_TABBED}, + }; + ukm_entry_checker_->ExpectNewEntry(kEntryName, test_urls_[0], + expected_metrics); + } +} + } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.cc b/chrome/browser/resource_coordinator/tab_metrics_logger.cc index 47288b35..3933129 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
@@ -53,27 +53,6 @@ ui::PageTransitionIsRedirect(page_transition); } -// Logs the TabManager.Background.ForegroundedOrClosed event. -void LogBackgroundTabForegroundedOrClosed( - ukm::SourceId ukm_source_id, - base::TimeDelta inactive_duration, - const tab_ranker::MRUFeatures& mru_features, - bool is_foregrounded, - bool is_discarded, - int sequence_id) { - if (!ukm_source_id) - return; - - ukm::builders::TabManager_Background_ForegroundedOrClosed(ukm_source_id) - .SetSequenceId(sequence_id) - .SetIsForegrounded(is_foregrounded) - .SetMRUIndex(mru_features.index) - .SetTimeFromBackgrounded(inactive_duration.InMilliseconds()) - .SetTotalTabCount(mru_features.total) - .SetIsDiscarded(is_discarded) - .Record(ukm::UkmRecorder::Get()); -} - } // namespace TabMetricsLogger::TabMetricsLogger() = default; @@ -161,79 +140,51 @@ return tab; } -void TabMetricsLogger::LogBackgroundTab(ukm::SourceId ukm_source_id, - const TabMetrics& tab_metrics) { +void TabMetricsLogger::LogTabMetrics( + ukm::SourceId ukm_source_id, + const tab_ranker::TabFeatures& tab_features, + content::WebContents* web_contents) { if (!ukm_source_id) return; - content::WebContents* web_contents = tab_metrics.web_contents; + if (web_contents) { + // UKM recording is disabled in OTR. + if (web_contents->GetBrowserContext()->IsOffTheRecord()) + return; - // UKM recording is disabled in OTR. - if (web_contents->GetBrowserContext()->IsOffTheRecord()) - return; + // Verify that the browser is not closing. + const Browser* browser = chrome::FindBrowserWithWebContents(web_contents); + if (base::ContainsKey( + BrowserList::GetInstance()->currently_closing_browsers(), + browser)) { + return; + } - // Verify that the browser is not closing. - const Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - if (!browser || - base::ContainsKey( - BrowserList::GetInstance()->currently_closing_browsers(), browser)) { - return; + const TabStripModel* tab_strip_model = browser->tab_strip_model(); + if (tab_strip_model->closing_all()) + return; } - const TabStripModel* tab_strip_model = browser->tab_strip_model(); - if (tab_strip_model->closing_all()) - return; - - int index = tab_strip_model->GetIndexOfWebContents(web_contents); - DCHECK_NE(index, TabStripModel::kNoTab); - - // inactive_duration isn't used when logging a tab that gets backgrounded. - tab_ranker::TabFeatures tab = GetTabFeatures( - browser, tab_metrics, base::TimeDelta() /*inactive_duration*/); - - // Keep these Set functions in alphabetical order so they're easy to check - // against the list of metrics in the UKM event. ukm::builders::TabManager_TabMetrics entry(ukm_source_id); - entry.SetHasBeforeUnloadHandler(tab.has_before_unload_handler); - entry.SetHasFormEntry(tab.has_form_entry); - entry.SetIsPinned(tab.is_pinned); - entry.SetKeyEventCount(tab.key_event_count); - entry.SetMouseEventCount(tab.mouse_event_count); - entry.SetNavigationEntryCount(tab.navigation_entry_count); - if (tab.page_transition_core_type.has_value()) - entry.SetPageTransitionCoreType(tab.page_transition_core_type.value()); - entry.SetPageTransitionFromAddressBar(tab.page_transition_from_address_bar); - entry.SetPageTransitionIsRedirect(tab.page_transition_is_redirect); + PopulateTabFeaturesToUkmEntry(tab_features, &entry); entry.SetSequenceId(++sequence_id_); - if (tab.site_engagement_score.has_value()) - entry.SetSiteEngagementScore(tab.site_engagement_score.value()); - entry.SetTouchEventCount(tab.touch_event_count); - entry.SetWasRecentlyAudible(tab.was_recently_audible); - - // The browser window logs its own usage UKMs with its session ID. - entry.SetWindowId(browser->session_id().id()); - entry.Record(ukm::UkmRecorder::Get()); } -void TabMetricsLogger::LogBackgroundTabShown( +void TabMetricsLogger::LogForegroundedOrClosedMetrics( ukm::SourceId ukm_source_id, - base::TimeDelta inactive_duration, - const tab_ranker::MRUFeatures& mru_features, - const bool is_discarded) { - LogBackgroundTabForegroundedOrClosed(ukm_source_id, inactive_duration, - mru_features, true /* is_shown */, - is_discarded, ++sequence_id_); -} + const ForegroundedOrClosedMetrics& metrics) { + if (!ukm_source_id) + return; -void TabMetricsLogger::LogBackgroundTabClosed( - ukm::SourceId ukm_source_id, - base::TimeDelta inactive_duration, - const tab_ranker::MRUFeatures& mru_features, - const bool is_discarded) { - LogBackgroundTabForegroundedOrClosed(ukm_source_id, inactive_duration, - mru_features, false /* is_shown */, - is_discarded, ++sequence_id_); + ukm::builders::TabManager_Background_ForegroundedOrClosed(ukm_source_id) + .SetSequenceId(++sequence_id_) + .SetIsForegrounded(metrics.is_foregrounded) + .SetMRUIndex(metrics.mru_index) + .SetTimeFromBackgrounded(metrics.time_from_backgrounded) + .SetTotalTabCount(metrics.total_tab_count) + .SetIsDiscarded(metrics.is_discarded) + .Record(ukm::UkmRecorder::Get()); } void TabMetricsLogger::LogTabLifetime(ukm::SourceId ukm_source_id,
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.h b/chrome/browser/resource_coordinator/tab_metrics_logger.h index 72f97005..d0846b9 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.h +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.h
@@ -21,7 +21,6 @@ } // namespace content namespace tab_ranker { -struct MRUFeatures; struct TabFeatures; } // namespace tab_ranker @@ -54,27 +53,29 @@ PageMetrics page_metrics = {}; }; + // A struct that contains metrics to be logged in ForegroundedOrClosed event. + struct ForegroundedOrClosedMetrics { + bool is_foregrounded = false; + bool is_discarded = false; + int64_t time_from_backgrounded = 0; + int mru_index = 0; + int total_tab_count = 0; + }; + TabMetricsLogger(); ~TabMetricsLogger(); - // Logs metrics for the tab with the given main frame WebContents. Does - // nothing if |ukm_source_id| is zero. - void LogBackgroundTab(ukm::SourceId ukm_source_id, - const TabMetrics& tab_metrics); + // Logs metrics for the tab with the given |tab_features|. Does nothing if + // |ukm_source_id| is zero. + void LogTabMetrics(ukm::SourceId ukm_source_id, + const tab_ranker::TabFeatures& tab_features, + content::WebContents* web_contents); // Logs TabManager.Background.ForegroundedOrClosed UKM for a tab that was - // shown after being inactive. - void LogBackgroundTabShown(ukm::SourceId ukm_source_id, - base::TimeDelta inactive_duration, - const tab_ranker::MRUFeatures& mru_metrics, - bool is_discarded); - - // Logs TabManager.Background.ForegroundedOrClosed UKM for a tab that was - // closed after being inactive. - void LogBackgroundTabClosed(ukm::SourceId ukm_source_id, - base::TimeDelta inactive_duration, - const tab_ranker::MRUFeatures& mru_metrics, - bool is_discarded); + // shown or closed after being inactive. + void LogForegroundedOrClosedMetrics( + ukm::SourceId ukm_source_id, + const ForegroundedOrClosedMetrics& metrics); // Logs TabManager.TabLifetime UKM for a closed tab. void LogTabLifetime(ukm::SourceId ukm_source_id,
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc index 8a1a9cc..5ef7d68 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger_unittest.cc
@@ -4,11 +4,12 @@ #include "chrome/browser/resource_coordinator/tab_metrics_logger.h" +#include "base/containers/flat_map.h" #include "base/test/scoped_task_environment.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/engagement/site_engagement_service.h" -#include "chrome/browser/resource_coordinator/tab_ranker/mru_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" +#include "chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_activity_simulator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -28,7 +29,7 @@ // Tests creating a flat TabFeatures structure for logging a tab and its // TabMetrics state. -TEST_F(TabMetricsLoggerTest, TabFeatures) { +TEST_F(TabMetricsLoggerTest, GetTabFeatures) { TabActivitySimulator tab_activity_simulator; Browser::CreateParams params(profile(), true); std::unique_ptr<Browser> browser = @@ -64,9 +65,7 @@ EXPECT_EQ(bg_features.navigation_entry_count, 1); EXPECT_EQ(bg_features.num_reactivations, 0); ASSERT_TRUE(bg_features.page_transition_core_type.has_value()); - EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( - ui::PAGE_TRANSITION_FORM_SUBMIT, - bg_features.page_transition_core_type.value())); + EXPECT_EQ(bg_features.page_transition_core_type.value(), 7); EXPECT_EQ(bg_features.page_transition_from_address_bar, false); EXPECT_EQ(bg_features.page_transition_is_redirect, false); ASSERT_TRUE(bg_features.site_engagement_score.has_value()); @@ -108,9 +107,7 @@ EXPECT_EQ(bg_features.navigation_entry_count, 2); EXPECT_EQ(bg_features.num_reactivations, 5); ASSERT_TRUE(bg_features.page_transition_core_type.has_value()); - EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( - ui::PAGE_TRANSITION_LINK, - bg_features.page_transition_core_type.value())); + EXPECT_EQ(bg_features.page_transition_core_type.value(), 0); EXPECT_EQ(bg_features.page_transition_from_address_bar, true); EXPECT_EQ(bg_features.page_transition_is_redirect, false); ASSERT_TRUE(bg_features.site_engagement_score.has_value()); @@ -145,6 +142,17 @@ // Returns the TabMetricsLogger being tested. TabMetricsLogger* GetLogger() { return &logger_; } + // Expects all values inside the |map| appear in the |entry|. + void ExpectEntries(const ukm::mojom::UkmEntry* entry, + const base::flat_map<std::string, int64_t>& map) { + // Check all metrics are logged as expected. + EXPECT_EQ(entry->metrics.size(), map.size()); + + for (const auto& pair : map) { + GetTestUkmRecorder()->ExpectEntryMetric(entry, pair.first, pair.second); + } + } + private: // Sets up the task scheduling/task-runner environment for each test. base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -156,46 +164,56 @@ DISALLOW_COPY_AND_ASSIGN(TabMetricsLoggerUKMTest); }; -// Checks the foregrounded event is logged correctly. -TEST_F(TabMetricsLoggerUKMTest, LogBackgroundTabShown) { - const tab_ranker::MRUFeatures& mru_metrics{4, 7}; - const int64_t inactive_duration_ms = 1234; - const bool is_discarded = false; +// Checks TabFeature is logged correctly with TabMetricsLogger::LogTabMetrics. +TEST_F(TabMetricsLoggerUKMTest, LogTabMetrics) { + const tab_ranker::TabFeatures tab = + tab_ranker::GetFullTabFeaturesForTesting(); - GetLogger()->LogBackgroundTabShown( - GetSourceId(), base::TimeDelta::FromMilliseconds(inactive_duration_ms), - mru_metrics, is_discarded); + GetLogger()->LogTabMetrics(GetSourceId(), tab, nullptr); // Checks that the size is logged correctly. EXPECT_EQ(1U, GetTestUkmRecorder()->sources_count()); EXPECT_EQ(1U, GetTestUkmRecorder()->entries_count()); const std::vector<const ukm::mojom::UkmEntry*> entries = - GetTestUkmRecorder()->GetEntriesByName( - "TabManager.Background.ForegroundedOrClosed"); + GetTestUkmRecorder()->GetEntriesByName("TabManager.TabMetrics"); EXPECT_EQ(1U, entries.size()); // Checks that all the fields are logged correctly. - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "SequenceId", 1); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "IsForegrounded", 1); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "MRUIndex", - mru_metrics.index); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "TimeFromBackgrounded", - inactive_duration_ms); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "TotalTabCount", - mru_metrics.total); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "IsDiscarded", - is_discarded); + ExpectEntries(entries[0], { + {"HasBeforeUnloadHandler", 1}, + {"HasFormEntry", 1}, + {"IsPinned", 1}, + {"KeyEventCount", 21}, + {"MouseEventCount", 22}, + {"MRUIndex", 27}, + {"NavigationEntryCount", 24}, + {"NumReactivationBefore", 25}, + {"PageTransitionCoreType", 2}, + {"PageTransitionFromAddressBar", 1}, + {"PageTransitionIsRedirect", 1}, + {"SequenceId", 1}, + {"SiteEngagementScore", 26}, + {"TimeFromBackgrounded", 10000}, + {"TotalTabCount", 30}, + {"TouchEventCount", 28}, + {"WasRecentlyAudible", 1}, + {"WindowIsActive", 1}, + {"WindowShowState", 3}, + {"WindowTabCount", 27}, + {"WindowType", 4}, + }); } -// Checks the closed event is logged correctly. -TEST_F(TabMetricsLoggerUKMTest, LogBackgroundTabClosed) { - const tab_ranker::MRUFeatures& mru_metrics{4, 7}; - const int64_t inactive_duration_ms = 1234; - const bool is_discarded = true; +// Checks the ForegroundedOrClosed event is logged correctly. +TEST_F(TabMetricsLoggerUKMTest, LogForegroundedOrClosedMetrics) { + TabMetricsLogger::ForegroundedOrClosedMetrics foc_metrics; + foc_metrics.is_foregrounded = false; + foc_metrics.is_discarded = true; + foc_metrics.time_from_backgrounded = 1234; + foc_metrics.mru_index = 4; + foc_metrics.total_tab_count = 7; - GetLogger()->LogBackgroundTabClosed( - GetSourceId(), base::TimeDelta::FromMilliseconds(inactive_duration_ms), - mru_metrics, is_discarded); + GetLogger()->LogForegroundedOrClosedMetrics(GetSourceId(), foc_metrics); // Checks that the size is logged correctly. EXPECT_EQ(1U, GetTestUkmRecorder()->sources_count()); @@ -206,26 +224,24 @@ EXPECT_EQ(1U, entries.size()); // Checks that all the fields are logged correctly. - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "SequenceId", 1); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "IsForegrounded", 0); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "MRUIndex", - mru_metrics.index); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "TimeFromBackgrounded", - inactive_duration_ms); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "TotalTabCount", - mru_metrics.total); - GetTestUkmRecorder()->ExpectEntryMetric(entries[0], "IsDiscarded", - is_discarded); + ExpectEntries(entries[0], { + {"SequenceId", 1}, + {"IsForegrounded", 0}, + {"MRUIndex", foc_metrics.mru_index}, + {"TimeFromBackgrounded", + foc_metrics.time_from_backgrounded}, + {"TotalTabCount", foc_metrics.total_tab_count}, + {"IsDiscarded", foc_metrics.is_discarded}, + }); } // Checks the sequence id is logged as sequentially incremental sequence across // different events. TEST_F(TabMetricsLoggerUKMTest, SequenceIdShouldBeLoggedSequentially) { - const bool is_discarded = false; - GetLogger()->LogBackgroundTabShown(GetSourceId(), base::TimeDelta(), - tab_ranker::MRUFeatures(), is_discarded); - GetLogger()->LogBackgroundTabClosed(GetSourceId(), base::TimeDelta(), - tab_ranker::MRUFeatures(), is_discarded); + const TabMetricsLogger::ForegroundedOrClosedMetrics foc_metrics; + + GetLogger()->LogForegroundedOrClosedMetrics(GetSourceId(), foc_metrics); + GetLogger()->LogForegroundedOrClosedMetrics(GetSourceId(), foc_metrics); EXPECT_EQ(2U, GetTestUkmRecorder()->sources_count()); EXPECT_EQ(2U, GetTestUkmRecorder()->entries_count());
diff --git a/chrome/browser/resource_coordinator/tab_ranker/BUILD.gn b/chrome/browser/resource_coordinator/tab_ranker/BUILD.gn index 9ca357b..45f67a00 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/BUILD.gn +++ b/chrome/browser/resource_coordinator/tab_ranker/BUILD.gn
@@ -26,6 +26,20 @@ "//components/assist_ranker", "//components/assist_ranker/proto", "//components/sessions", + "//services/metrics/public/cpp:ukm_builders", "//ui/base", ] } + +# target for using GetFullTabFeaturesForTesting in unit tests. +static_library("tab_features_test_helper") { + testonly = true + sources = [ + "tab_features_test_helper.cc", + "tab_features_test_helper.h", + ] + + deps = [ + ":tab_ranker", + ] +}
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_features.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_features.cc index 7f1b5d4..7e604ee 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_features.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_features.cc
@@ -4,12 +4,118 @@ #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" +#include "base/metrics/metrics_hashes.h" +#include "components/assist_ranker/proto/ranker_example.pb.h" +#include "services/metrics/public/cpp/ukm_builders.h" + namespace tab_ranker { +using ukm::builders::TabManager_TabMetrics; + TabFeatures::TabFeatures() = default; TabFeatures::~TabFeatures() = default; TabFeatures::TabFeatures(const TabFeatures& other) = default; +void PopulateTabFeaturesToRankerExample(const TabFeatures& tab, + assist_ranker::RankerExample* example) { + auto& features = *example->mutable_features(); + + features[TabManager_TabMetrics::kHasBeforeUnloadHandlerName].set_bool_value( + tab.has_before_unload_handler); + features[TabManager_TabMetrics::kHasFormEntryName].set_bool_value( + tab.has_form_entry); + features[TabManager_TabMetrics::kIsPinnedName].set_bool_value(tab.is_pinned); + features[TabManager_TabMetrics::kKeyEventCountName].set_int32_value( + tab.key_event_count); + features[TabManager_TabMetrics::kMouseEventCountName].set_int32_value( + tab.mouse_event_count); + features[TabManager_TabMetrics::kNavigationEntryCountName].set_int32_value( + tab.navigation_entry_count); + features[TabManager_TabMetrics::kNumReactivationBeforeName].set_int32_value( + tab.num_reactivations); + // Nullable types indicate optional values; if not present, the corresponding + // feature should not be set. + if (tab.page_transition_core_type.has_value()) { + features[TabManager_TabMetrics::kPageTransitionCoreTypeName] + .set_int32_value(tab.page_transition_core_type.value()); + } + features[TabManager_TabMetrics::kPageTransitionFromAddressBarName] + .set_bool_value(tab.page_transition_from_address_bar); + features[TabManager_TabMetrics::kPageTransitionIsRedirectName].set_bool_value( + tab.page_transition_is_redirect); + if (tab.site_engagement_score.has_value()) { + features[TabManager_TabMetrics::kSiteEngagementScoreName].set_int32_value( + tab.site_engagement_score.value()); + } + features[TabManager_TabMetrics::kTimeFromBackgroundedName].set_int32_value( + tab.time_from_backgrounded); + features[TabManager_TabMetrics::kTouchEventCountName].set_int32_value( + tab.touch_event_count); + features[TabManager_TabMetrics::kWasRecentlyAudibleName].set_bool_value( + tab.was_recently_audible); + + // Mru features. + if (tab.total_tab_count > 0) { + features[TabManager_TabMetrics::kMRUIndexName].set_int32_value( + tab.mru_index); + features[TabManager_TabMetrics::kTotalTabCountName].set_int32_value( + tab.total_tab_count); + + features["NormalizedMRUIndex"].set_float_value(float(tab.mru_index) / + tab.total_tab_count); + } + + // Window features. + features[TabManager_TabMetrics::kWindowIsActiveName].set_bool_value( + tab.window_is_active); + features[TabManager_TabMetrics::kWindowShowStateName].set_int32_value( + tab.window_show_state); + features[TabManager_TabMetrics::kWindowTabCountName].set_int32_value( + tab.window_tab_count); + features[TabManager_TabMetrics::kWindowTypeName].set_int32_value( + tab.window_type); + // The new metric names are set as WindowTabCount, WindowType, in the ukm.xml, + // but we still need old feature names TabCount, Type for current model. + // TODO(charleszhao): remove old feature names once new model is trained. + features["IsActive"].set_bool_value(tab.window_is_active); + features["ShowState"].set_int32_value(tab.window_show_state); + features["TabCount"].set_int32_value(tab.window_tab_count); + features["Type"].set_int32_value(tab.window_type); + + features["TopDomain"].set_string_value( + std::to_string(base::HashMetricName(tab.host))); +} + +void PopulateTabFeaturesToUkmEntry( + const TabFeatures& tab, + ukm::builders::TabManager_TabMetrics* entry) { + entry->SetHasBeforeUnloadHandler(tab.has_before_unload_handler); + entry->SetHasFormEntry(tab.has_form_entry); + entry->SetIsPinned(tab.is_pinned); + entry->SetKeyEventCount(tab.key_event_count); + entry->SetMouseEventCount(tab.mouse_event_count); + entry->SetNavigationEntryCount(tab.navigation_entry_count); + entry->SetNumReactivationBefore(tab.num_reactivations); + if (tab.page_transition_core_type.has_value()) + entry->SetPageTransitionCoreType(tab.page_transition_core_type.value()); + entry->SetPageTransitionFromAddressBar(tab.page_transition_from_address_bar); + entry->SetPageTransitionIsRedirect(tab.page_transition_is_redirect); + if (tab.site_engagement_score.has_value()) + entry->SetSiteEngagementScore(tab.site_engagement_score.value()); + entry->SetTimeFromBackgrounded(tab.time_from_backgrounded); + entry->SetTouchEventCount(tab.touch_event_count); + entry->SetWasRecentlyAudible(tab.was_recently_audible); + entry->SetWindowIsActive(tab.window_is_active); + entry->SetWindowShowState(tab.window_show_state); + entry->SetWindowTabCount(tab.window_tab_count); + entry->SetWindowType(tab.window_type); + + if (tab.total_tab_count > 0) { + entry->SetMRUIndex(tab.mru_index); + entry->SetTotalTabCount(tab.total_tab_count); + } +} + } // namespace tab_ranker
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_features.h b/chrome/browser/resource_coordinator/tab_ranker/tab_features.h index 3724e871..0f08097 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_features.h +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_features.h
@@ -9,7 +9,16 @@ #include <string> #include "base/optional.h" -#include "ui/base/page_transition_types.h" + +namespace assist_ranker { +class RankerExample; +} + +namespace ukm { +namespace builders { +class TabManager_TabMetrics; +} +} // namespace ukm namespace tab_ranker { @@ -26,26 +35,41 @@ // properties are sent via UKM. bool has_before_unload_handler = false; bool has_form_entry = false; - std::string host; // Used for inference. bool is_pinned = false; int32_t key_event_count = 0; int32_t mouse_event_count = 0; + int32_t mru_index = 0; int32_t navigation_entry_count = 0; // Number of times the tab has been reactivated while showing the current // page. Reset to 0 when a tab navigates. int32_t num_reactivations = 0; // Null if the value is not one of the core values logged to UKM. - base::Optional<ui::PageTransition> page_transition_core_type; + base::Optional<int32_t> page_transition_core_type; bool page_transition_from_address_bar = false; bool page_transition_is_redirect = false; // Null if the SiteEngagementService is disabled. base::Optional<int32_t> site_engagement_score; // Time since tab was backgrounded, in milliseconds. int32_t time_from_backgrounded = 0; + int32_t total_tab_count = 0; int32_t touch_event_count = 0; bool was_recently_audible = false; + bool window_is_active = false; + int32_t window_show_state = 0; + int32_t window_tab_count = 0; + int32_t window_type = 0; + + std::string host; // Used only for inference. }; +// Populates |tab| features to ranker example for inference. +void PopulateTabFeaturesToRankerExample(const TabFeatures& tab, + assist_ranker::RankerExample* example); + +// Populates |tab| features to ukm |entry| for logging. +void PopulateTabFeaturesToUkmEntry(const TabFeatures& tab, + ukm::builders::TabManager_TabMetrics* entry); + } // namespace tab_ranker #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_RANKER_TAB_FEATURES_H_
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.cc new file mode 100644 index 0000000..040c181 --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.cc
@@ -0,0 +1,68 @@ +// 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/resource_coordinator/tab_ranker/tab_features_test_helper.h" + +#include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" + +namespace tab_ranker { + +// The following two functions are used in multiple tests to make sure the +// conversion, logging and inferencing use the same group of features. +// Returns a default tab features with some field unset. +TabFeatures GetPartialTabFeaturesForTesting() { + TabFeatures tab; + + tab.has_before_unload_handler = true; + tab.has_form_entry = true; + tab.is_pinned = true; + tab.key_event_count = 121; + tab.mouse_event_count = 122; + tab.mru_index = 13; + tab.navigation_entry_count = 124; + tab.num_reactivations = 125; + tab.page_transition_from_address_bar = true; + tab.page_transition_is_redirect = true; + tab.time_from_backgrounded = 110000; + tab.total_tab_count = 130; + tab.touch_event_count = 128; + tab.was_recently_audible = true; + tab.window_is_active = true; + tab.window_show_state = 3; + tab.window_tab_count = 127; + tab.window_type = 4; + + return tab; +} + +// Returns a tab features with all field set. +TabFeatures GetFullTabFeaturesForTesting() { + TabFeatures tab; + + tab.has_before_unload_handler = true; + tab.has_form_entry = true; + tab.is_pinned = true; + tab.key_event_count = 21; + tab.mouse_event_count = 22; + tab.mru_index = 27; + tab.navigation_entry_count = 24; + tab.num_reactivations = 25; + tab.page_transition_core_type = 2; + tab.page_transition_from_address_bar = true; + tab.page_transition_is_redirect = true; + tab.site_engagement_score = 26; + tab.time_from_backgrounded = 10000; + tab.total_tab_count = 30; + tab.touch_event_count = 28; + tab.was_recently_audible = true; + tab.window_is_active = true; + tab.window_show_state = 3; + tab.window_tab_count = 27; + tab.window_type = 4; + + tab.host = "www.google.com"; + return tab; +} + +} // namespace tab_ranker
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h b/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h new file mode 100644 index 0000000..4fb5174 --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h
@@ -0,0 +1,22 @@ +// 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_RESOURCE_COORDINATOR_TAB_RANKER_TAB_FEATURES_TEST_HELPER_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_RANKER_TAB_FEATURES_TEST_HELPER_H_ + +namespace tab_ranker { + +struct TabFeatures; + +// The following two functions are used in multiple tests to make sure the +// conversion, logging and inferencing use the same group of features. +// Returns a default tab features with some field unset. +TabFeatures GetPartialTabFeaturesForTesting(); + +// Returns a tab features with all field set. +TabFeatures GetFullTabFeaturesForTesting(); + +} // namespace tab_ranker + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_RANKER_TAB_FEATURES_TEST_HELPER_H_
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_features_unittest.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_features_unittest.cc new file mode 100644 index 0000000..da9c79fcd --- /dev/null +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_features_unittest.cc
@@ -0,0 +1,145 @@ +// 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/resource_coordinator/tab_ranker/tab_features.h" + +#include <map> +#include <string> + +#include "base/metrics/metrics_hashes.h" +#include "base/test/scoped_task_environment.h" +#include "chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h" +#include "components/assist_ranker/proto/ranker_example.pb.h" +#include "components/ukm/test_ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace tab_ranker { + +using assist_ranker::RankerExample; +using ukm::builders::TabManager_TabMetrics; +using ukm::TestUkmRecorder; + +// This ensures that all field in TabFeatures populates to RankerExample +// correctly. +TEST(TabFeaturesTest, PopulateTabFeaturesToRankerExample) { + const TabFeatures tab = GetFullTabFeaturesForTesting(); + + RankerExample example; + PopulateTabFeaturesToRankerExample(tab, &example); + + const auto& features = example.features(); + + // This ensures all tab features are populated into example. + EXPECT_EQ(features.size(), 26U); + + EXPECT_EQ(features.at(TabManager_TabMetrics::kHasBeforeUnloadHandlerName) + .bool_value(), + 1); + EXPECT_EQ(features.at(TabManager_TabMetrics::kHasFormEntryName).bool_value(), + 1); + EXPECT_EQ(features.at(TabManager_TabMetrics::kIsPinnedName).bool_value(), 1); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kKeyEventCountName).int32_value(), 21); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kMouseEventCountName).int32_value(), + 22); + EXPECT_EQ(features.at(TabManager_TabMetrics::kMRUIndexName).int32_value(), + 27); + EXPECT_EQ(features.at(TabManager_TabMetrics::kNavigationEntryCountName) + .int32_value(), + 24); + EXPECT_EQ(features.at(TabManager_TabMetrics::kNumReactivationBeforeName) + .int32_value(), + 25); + EXPECT_EQ(features.at(TabManager_TabMetrics::kPageTransitionCoreTypeName) + .int32_value(), + 2); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kPageTransitionFromAddressBarName) + .bool_value(), + 1); + EXPECT_EQ(features.at(TabManager_TabMetrics::kPageTransitionIsRedirectName) + .bool_value(), + 1); + EXPECT_EQ(features.at(TabManager_TabMetrics::kSiteEngagementScoreName) + .int32_value(), + 26); + EXPECT_EQ(features.at(TabManager_TabMetrics::kTimeFromBackgroundedName) + .int32_value(), + 10000); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kTotalTabCountName).int32_value(), 30); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kTouchEventCountName).int32_value(), + 28); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kWasRecentlyAudibleName).bool_value(), + 1); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kWindowIsActiveName).bool_value(), 1); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kWindowShowStateName).int32_value(), + 3); + EXPECT_EQ( + features.at(TabManager_TabMetrics::kWindowTabCountName).int32_value(), + 27); + EXPECT_EQ(features.at(TabManager_TabMetrics::kWindowTypeName).int32_value(), + 4); + + EXPECT_EQ(features.at("IsActive").bool_value(), 1); + EXPECT_EQ(features.at("ShowState").int32_value(), 3); + EXPECT_EQ(features.at("TabCount").int32_value(), 27); + EXPECT_EQ(features.at("Type").int32_value(), 4); + EXPECT_FLOAT_EQ(features.at("NormalizedMRUIndex").float_value(), 0.9f); + EXPECT_EQ(features.at("TopDomain").string_value(), "726059442646517786"); +} + +// This ensures that all field in TabFeatures populates to TabManager_TabMetrics +// correctly. +TEST(TabFeaturesTest, PopulateTabFeaturesToUkmEntry) { + // Sets up the task scheduling/task-runner environment for each test. + base::test::ScopedTaskEnvironment scoped_task_environment; + // Sets itself as the global UkmRecorder on construction. + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + + const TabFeatures tab = GetFullTabFeaturesForTesting(); + + ukm::builders::TabManager_TabMetrics tab_entry(0); + PopulateTabFeaturesToUkmEntry(tab, &tab_entry); + tab_entry.Record(ukm::UkmRecorder::Get()); + + const ukm::mojom::UkmEntry* entry = + test_ukm_recorder.GetEntriesByName(TabManager_TabMetrics::kEntryName)[0]; + + std::map<std::string, int64_t> expected_metrics = { + {"HasBeforeUnloadHandler", 1}, + {"HasFormEntry", 1}, + {"IsPinned", 1}, + {"KeyEventCount", 21}, + {"MouseEventCount", 22}, + {"MRUIndex", 27}, + {"NavigationEntryCount", 24}, + {"NumReactivationBefore", 25}, + {"PageTransitionCoreType", 2}, + {"PageTransitionFromAddressBar", 1}, + {"PageTransitionIsRedirect", 1}, + {"SiteEngagementScore", 26}, + {"TimeFromBackgrounded", 10000}, + {"TotalTabCount", 30}, + {"TouchEventCount", 28}, + {"WasRecentlyAudible", 1}, + {"WindowIsActive", 1}, + {"WindowShowState", 3}, + {"WindowTabCount", 27}, + {"WindowType", 4}, + }; + // Check all metrics are logged as expected. + EXPECT_EQ(entry->metrics.size(), expected_metrics.size()); + + for (const auto& pair : expected_metrics) { + test_ukm_recorder.ExpectEntryMetric(entry, pair.first, pair.second); + } +} + +} // namespace tab_ranker
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc index 9320f21..36f03b97 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc
@@ -4,17 +4,14 @@ #include "chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.h" +#include <memory> #include <string> #include "base/logging.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/scoped_refptr.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/metrics_hashes.h" -#include "chrome/browser/resource_coordinator/tab_ranker/mru_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/native_inference.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" -#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" #include "chrome/grit/browser_resources.h" #include "components/assist_ranker/example_preprocessing.h" #include "components/assist_ranker/proto/example_preprocessor.pb.h" @@ -47,58 +44,12 @@ return config; } -void PopulateRankerExample(assist_ranker::RankerExample* example, - const TabFeatures& tab, - const WindowFeatures& window, - const MRUFeatures& mru) { - auto& features = *example->mutable_features(); - - features["HasBeforeUnloadHandler"].set_bool_value( - tab.has_before_unload_handler); - features["HasFormEntry"].set_bool_value(tab.has_form_entry); - features["IsActive"].set_bool_value(window.is_active); - features["IsPinned"].set_bool_value(tab.is_pinned); - features["KeyEventCount"].set_int32_value(tab.key_event_count); - features["MRUIndex"].set_int32_value(mru.index); - features["MouseEventCount"].set_int32_value(tab.mouse_event_count); - features["NavigationEntryCount"].set_int32_value(tab.navigation_entry_count); - DCHECK_GT(mru.total, 0); - features["NormalizedMRUIndex"].set_float_value(float(mru.index) / mru.total); - features["NumReactivationBefore"].set_int32_value(tab.num_reactivations); - - // Nullable types indicate optional values; if not present, the corresponding - // feature should not be set. - if (tab.page_transition_core_type.has_value()) { - features["PageTransitionCoreType"].set_int32_value( - tab.page_transition_core_type.value()); - } - features["PageTransitionFromAddressBar"].set_bool_value( - tab.page_transition_from_address_bar); - features["PageTransitionIsRedirect"].set_bool_value( - tab.page_transition_is_redirect); - if (tab.site_engagement_score.has_value()) { - features["SiteEngagementScore"].set_int32_value( - tab.site_engagement_score.value()); - } - features["ShowState"].set_int32_value(window.show_state); - features["TabCount"].set_int32_value(window.tab_count); - features["TimeFromBackgrounded"].set_int32_value(tab.time_from_backgrounded); - features["TopDomain"].set_string_value( - std::to_string(base::HashMetricName(tab.host))); - features["TotalTabCount"].set_int32_value(mru.total); - features["TouchEventCount"].set_int32_value(tab.touch_event_count); - features["Type"].set_int32_value(window.type); - features["WasRecentlyAudible"].set_bool_value(tab.was_recently_audible); -} - } // namespace TabScorePredictor::TabScorePredictor() = default; TabScorePredictor::~TabScorePredictor() = default; TabRankerResult TabScorePredictor::ScoreTab(const TabFeatures& tab, - const WindowFeatures& window, - const MRUFeatures& mru, float* score) { DCHECK(score); @@ -110,7 +61,7 @@ if (preprocessor_config_) { // Build the RankerExample using the tab's features. assist_ranker::RankerExample example; - PopulateRankerExample(&example, tab, window, mru); + PopulateTabFeaturesToRankerExample(tab, &example); // Process the RankerExample with the tab ranker config to vectorize the // feature list for inference. @@ -147,7 +98,6 @@ result = TabRankerResult::kPreprocessorInitializationFailed; } - UMA_HISTOGRAM_ENUMERATION("TabManager.TabRanker.Result", result); return result; }
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.h b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.h index 9d56152a..4209061 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.h +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.h
@@ -21,9 +21,7 @@ struct FixedAllocations; } // namespace tfnative_model -struct MRUFeatures; struct TabFeatures; -struct WindowFeatures; // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. @@ -44,12 +42,7 @@ // Scores the tab using the tab reactivation model. A higher score indicates // the tab is more likely to be reactivated than a lower score. A lower score // indicates the tab is more likely to be closed. - // |mru_index|: Index of the tab in most-recently used order. - // |total_tab_count|: Number of tabs used when calculating mru_index, ie - // number of non-incognito tabs. TabRankerResult ScoreTab(const TabFeatures& tab, - const WindowFeatures& window, - const MRUFeatures& mru, float* score) WARN_UNUSED_RESULT; private:
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc index f9cce970..62ac12a 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc
@@ -6,28 +6,15 @@ #include <memory> -#include "chrome/browser/resource_coordinator/tab_ranker/mru_features.h" #include "chrome/browser/resource_coordinator/tab_ranker/tab_features.h" -#include "chrome/browser/resource_coordinator/tab_ranker/window_features.h" -#include "components/sessions/core/session_id.h" +#include "chrome/browser/resource_coordinator/tab_ranker/tab_features_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/page_transition_types.h" namespace tab_ranker { namespace { -// Returns a fairly typical set of window features. -WindowFeatures GetWindowFeatures() { - WindowFeatures window(SessionID::NewUnique(), - metrics::WindowMetricsEvent::TYPE_TABBED); - window.tab_count = 3; - window.is_active = true; - window.show_state = metrics::WindowMetricsEvent::SHOW_STATE_NORMAL; - return window; -} - -// These tests verify that the example_preprocessor_config.pb and -// native_inference.h code together generates correct scores. +// This tests that the TabRanker predictor returns a same score that is +// calcuated when the model is trained. class TabScorePredictorTest : public testing::Test { public: TabScorePredictorTest() = default; @@ -35,12 +22,10 @@ protected: // Returns a prediction for the tab example. - float ScoreTab(const TabFeatures& tab, - const WindowFeatures& window, - const MRUFeatures& mru) { + float ScoreTab(const TabFeatures& tab) { float score = 0; EXPECT_EQ(TabRankerResult::kSuccess, - tab_score_predictor_.ScoreTab(tab, window, mru, &score)); + tab_score_predictor_.ScoreTab(tab, &score)); return score; } @@ -55,61 +40,15 @@ // Checks the score for an example that we have calculated a known score for // outside of Chrome. TEST_F(TabScorePredictorTest, KnownScore) { - MRUFeatures mru; - mru.index = 27; - mru.total = 30; - - TabFeatures tab; - tab.has_before_unload_handler = true; - tab.has_form_entry = true; - tab.host = "www.google.com"; - tab.is_pinned = true; - tab.key_event_count = 21; - tab.mouse_event_count = 22; - tab.navigation_entry_count = 24; - tab.num_reactivations = 25; - tab.page_transition_core_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - tab.page_transition_from_address_bar = true; - tab.page_transition_is_redirect = true; - tab.site_engagement_score = 26; - tab.time_from_backgrounded = 10000; - tab.touch_event_count = 28; - tab.was_recently_audible = true; - - WindowFeatures window(GetWindowFeatures()); - window.tab_count = 27; - // Pre-calculated score using the generated model outside of Chrome. - EXPECT_FLOAT_EQ(1.8338085, ScoreTab(tab, window, mru)); + EXPECT_FLOAT_EQ(-19.446667, ScoreTab(GetFullTabFeaturesForTesting())); } // Checks the score for a different example that we have calculated a known // score for outside of Chrome. This example omits the optional features. TEST_F(TabScorePredictorTest, KnownScoreMissingOptionalFeatures) { - MRUFeatures mru; - mru.index = 13; - mru.total = 130; - - TabFeatures tab; - tab.has_before_unload_handler = true; - tab.has_form_entry = true; - tab.host = "www.example.com"; - tab.is_pinned = true; - tab.key_event_count = 121; - tab.mouse_event_count = 122; - tab.navigation_entry_count = 124; - tab.num_reactivations = 125; - tab.page_transition_from_address_bar = true; - tab.page_transition_is_redirect = true; - tab.time_from_backgrounded = 110000; - tab.touch_event_count = 128; - tab.was_recently_audible = true; - - WindowFeatures window(GetWindowFeatures()); - window.tab_count = 127; - // Pre-calculated score using the generated model outside of Chrome. - EXPECT_FLOAT_EQ(8.7163248, ScoreTab(tab, window, mru)); + EXPECT_FLOAT_EQ(5.7347188, ScoreTab(GetPartialTabFeaturesForTesting())); } } // namespace tab_ranker
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc index bebf223c..a7fb8264 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.cc
@@ -96,7 +96,7 @@ const std::string& passphrase) { base::AutoLock al(shared_state_lock_); // Signal VolumeReaderJavaScriptStream::Passphrase to continue execution. - available_passphrase_ = passphrase; + available_passphrase_ = base::make_optional(passphrase); available_passphrase_cond_.Signal(); } @@ -212,14 +212,12 @@ } base::Optional<std::string> VolumeReaderJavaScriptStream::Passphrase() { - // The error is not recoverable. Once passphrase fails to be provided, it is - // never asked again. Note, that still users are able to retry entering the - // password, unless they click Cancel. + // Reset the state and prompt the user for a passphrase. Assume a correct + // passphrase from a previous request has been saved by the requestor. { base::AutoLock al(shared_state_lock_); - if (passphrase_error_) { - return {}; - } + passphrase_error_ = false; + available_passphrase_.reset(); } // Request the passphrase outside of the lock. @@ -227,13 +225,10 @@ base::AutoLock al(shared_state_lock_); // Wait for the passphrase from JavaScript. - // TODO(amistry): Handle spurious wakeups. - available_passphrase_cond_.Wait(); + while (!passphrase_error_ && !available_passphrase_) + available_passphrase_cond_.Wait(); - if (passphrase_error_) - return {}; - - return base::make_optional<std::string>(available_passphrase_); + return available_passphrase_; } void VolumeReaderJavaScriptStream::RequestChunk(int64_t length) {
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h index db83d1f..19540b21 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader_javascript_stream.h
@@ -9,6 +9,7 @@ #include <memory> #include <string> +#include "base/optional.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader.h" @@ -92,7 +93,9 @@ bool available_data_; // Indicates whether any data is available. bool read_error_; // Marks an error in reading from JavaScript. - std::string available_passphrase_; // Stores a passphrase from JavaScript. + // Stores a passphrase from JavaScript. Stored as a base::Optional<> because + // the user could have entered an empty passphrase. + base::Optional<std::string> available_passphrase_; bool passphrase_error_; // Marks an error in getting the passphrase. // The shared_state_lock_ is used to protect members which are accessed by
diff --git a/chrome/browser/resources/chromeos/zip_archiver/js/app.js b/chrome/browser/resources/chromeos/zip_archiver/js/app.js index 9bf237b1..be90d73 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/js/app.js +++ b/chrome/browser/resources/chromeos/zip_archiver/js/app.js
@@ -188,13 +188,15 @@ if (chrome.extension.inIncognitoContext) return; - chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) { - if (result[unpacker.app.STORAGE_KEY]) { - chrome.storage.local.clear(function() { - console.info('Cleaned up archive mount info from older versions.'); - }); - } - }); + if (chrome.storage && chrome.storage.local) { + chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) { + if (result[unpacker.app.STORAGE_KEY]) { + chrome.storage.local.clear(function() { + console.info('Cleaned up archive mount info from older versions.'); + }); + } + }); + } }, /**
diff --git a/chrome/browser/resources/chromeos/zip_archiver/js/decompressor.js b/chrome/browser/resources/chromeos/zip_archiver/js/decompressor.js index 3aca206..71fd2326 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/js/decompressor.js +++ b/chrome/browser/resources/chromeos/zip_archiver/js/decompressor.js
@@ -307,9 +307,5 @@ this.naclModule_.postMessage( unpacker.request.createReadPassphraseErrorResponse( this.fileSystemId_, requestId)); - // TODO(mtomasz): Instead of unmounting just let the current operation - // fail and ask for password for another files. This is however - // impossible for now due to a bug in minizip. - unpacker.app.unmountVolume(this.fileSystemId_, true); }.bind(this)); };
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html index e4e9ba4..51923ca 100644 --- a/chrome/browser/resources/md_extensions/toolbar.html +++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -53,7 +53,8 @@ border-bottom: 1px solid var(--google-grey-300); box-sizing: border-box; height: 0; - overflow: hidden; + overflow-x: hidden; + overflow-y: auto; position: relative; transition: height var(--drawer-transition); }
diff --git a/chrome/browser/resources/print_preview/new/header.html b/chrome/browser/resources/print_preview/new/header.html index 4902440..596cd14 100644 --- a/chrome/browser/resources/print_preview/new/header.html +++ b/chrome/browser/resources/print_preview/new/header.html
@@ -35,6 +35,7 @@ .summary { display: block; + height: 1em; min-height: 20px; }
diff --git a/chrome/browser/resources/print_preview/new/number_settings_section.html b/chrome/browser/resources/print_preview/new/number_settings_section.html index a2c1bab..cf161d8d 100644 --- a/chrome/browser/resources/print_preview/new/number_settings_section.html +++ b/chrome/browser/resources/print_preview/new/number_settings_section.html
@@ -8,15 +8,15 @@ <dom-module id="print-preview-number-settings-section"> <template> <style include="print-preview-shared"> - :host(:not([input-valid])) #section-title { - margin-top: calc(-14px - 2 * .75rem); - } - :host { /* Width = 3 digits + space + cr-input-padding-end/start */ --cr-input-width: calc(4em + 16px); } + #sectionTitle { + align-self: baseline; + } + cr-input { margin-inline-end: 16px; min-height: 38px; @@ -41,7 +41,7 @@ } </style> <print-preview-settings-section> - <span slot="title" id="section-title">[[inputLabel]]</span> + <span slot="title" id="sectionTitle">[[inputLabel]]</span> <div slot="controls" id="controls"> <span class="input-wrapper"> <cr-input id="userValue" type="number"
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.html b/chrome/browser/resources/print_preview/new/pages_settings.html index f819d35..c7fcfb35 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.html +++ b/chrome/browser/resources/print_preview/new/pages_settings.html
@@ -37,8 +37,7 @@ } :host #title { - justify-content: flex-start; - padding-top: 9px; + align-self: baseline; } </style> <print-preview-settings-section>
diff --git a/chrome/browser/resources/print_preview/new/print_preview_shared_css.html b/chrome/browser/resources/print_preview/new/print_preview_shared_css.html index 7addbf58..665b046 100644 --- a/chrome/browser/resources/print_preview/new/print_preview_shared_css.html +++ b/chrome/browser/resources/print_preview/new/print_preview_shared_css.html
@@ -15,7 +15,7 @@ --md-select-width: calc(100% - 17px); --print-preview-settings-border: 1px solid rgb(232, 234, 237); --print-preview-dialog-margin: 34px; - --cr-form-field-label-height: 1.5rem; + --cr-form-field-label-height: initial; --cr-form-field-label-line-height: .75rem; --destination-item-height: 32px; }
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index f3085596..3a3dd3f 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -6,9 +6,11 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h" #include "chrome/browser/sync/test/integration/feature_toggler.h" +#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" @@ -536,6 +538,55 @@ ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; } +IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTest, + PRE_PersistProgressMarkerOnRestart) { + const std::string title = "Seattle Sounders FC"; + fake_server::EntityBuilderFactory entity_builder_factory; + fake_server::BookmarkEntityBuilder bookmark_builder = + entity_builder_factory.NewBookmarkEntityBuilder(title); + fake_server_->InjectEntity(bookmark_builder.BuildFolder()); + + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_EQ(1, GetBookmarkBarNode(kSingleProfileIndex)->child_count()); + + EXPECT_NE( + 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK", + /*REMOTE_INITIAL_UPDATE=*/5)); +} + +IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTest, + PersistProgressMarkerOnRestart) { + const std::string title = "Seattle Sounders FC"; + fake_server::EntityBuilderFactory entity_builder_factory; + fake_server::BookmarkEntityBuilder bookmark_builder = + entity_builder_factory.NewBookmarkEntityBuilder(title); + fake_server_->InjectEntity(bookmark_builder.BuildFolder()); + + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + ASSERT_EQ(1, GetBookmarkBarNode(kSingleProfileIndex)->child_count()); + +#if defined(CHROMEOS) + // identity::SetRefreshTokenForPrimaryAccount() is needed on ChromeOS in order + // to get a non-empty refresh token on startup. + GetClient(0)->SignInPrimaryAccount(); +#endif // defined(CHROMEOS) + ASSERT_TRUE(GetClient(kSingleProfileIndex)->AwaitEngineInitialization()); + + // After restart, the last sync cycle snapshot should be empty. + // Once a sync request happened (e.g. by a poll), that snapshot is populated. + // We use the following checker to simply wait for an non-empty snapshot. + EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); + + // TODO(mamir): The expectation below should pass but doesn't with USS. + // Investigate the cause and fix the underlying issue. + // EXPECT_EQ( + // 0, + // histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK", + // /*REMOTE_INITIAL_UPDATE=*/5)); +} + INSTANTIATE_TEST_CASE_P(USS, SingleClientBookmarksSyncTest, ::testing::Values(false, true));
diff --git a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc index 8ee3a22..8701d5d1 100644 --- a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
@@ -151,7 +151,7 @@ SyncPrefs remote_prefs(GetProfile(0)->GetPrefs()); ASSERT_FALSE(remote_prefs.GetLastPollTime().is_null()); - // After the start, the last sync cycle snapshot should be empty. + // After restart, the last sync cycle snapshot should be empty. // Once a sync request happened (e.g. by a poll), that snapshot is populated. // We use the following checker to simply wait for an non-empty snapshot. EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
diff --git a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc index bb73a30..d968d9f 100644 --- a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc
@@ -8,6 +8,7 @@ #include "base/values.h" #include "chrome/browser/sync/test/integration/feature_toggler.h" #include "chrome/browser/sync/test/integration/preferences_helper.h" +#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "chrome/common/pref_names.h" @@ -121,6 +122,50 @@ /*REMOTE_INITIAL_UPDATE=*/5)); } +IN_PROC_BROWSER_TEST_P(SingleClientPreferencesSyncTest, + PRE_PersistProgressMarkerOnRestart) { + sync_pb::EntitySpecifics specifics; + specifics.mutable_preference()->set_name("testing.my-test-preference"); + fake_server_->InjectEntity( + syncer::PersistentUniqueClientEntity::CreateFromEntitySpecifics( + specifics.preference().name(), specifics, /*creation_time=*/0, + /*last_modified_time=*/0)); + + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupSync()); + EXPECT_EQ(1, histogram_tester.GetBucketCount( + "Sync.ModelTypeEntityChange3.PREFERENCE", + /*REMOTE_INITIAL_UPDATE=*/5)); +} + +IN_PROC_BROWSER_TEST_P(SingleClientPreferencesSyncTest, + PersistProgressMarkerOnRestart) { + sync_pb::EntitySpecifics specifics; + specifics.mutable_preference()->set_name("testing.my-test-preference"); + fake_server_->InjectEntity( + syncer::PersistentUniqueClientEntity::CreateFromEntitySpecifics( + specifics.preference().name(), specifics, /*creation_time=*/0, + /*last_modified_time=*/0)); + + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; +#if defined(CHROMEOS) + // identity::SetRefreshTokenForPrimaryAccount() is needed on ChromeOS in order + // to get a non-empty refresh token on startup. + GetClient(0)->SignInPrimaryAccount(); +#endif // defined(CHROMEOS) + ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization()); + + // After restart, the last sync cycle snapshot should be empty. + // Once a sync request happened (e.g. by a poll), that snapshot is populated. + // We use the following checker to simply wait for an non-empty snapshot. + EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); + + EXPECT_EQ(0, histogram_tester.GetBucketCount( + "Sync.ModelTypeEntityChange3.PREFERENCE", + /*REMOTE_INITIAL_UPDATE=*/5)); +} + INSTANTIATE_TEST_CASE_P(USS, SingleClientPreferencesSyncTest, ::testing::Values(false, true));
diff --git a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc index ee9b588..b5022fc 100644 --- a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc +++ b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/sync/test/fake_server/fake_server_http_post_provider.h" #include "net/base/network_change_notifier.h" namespace { @@ -73,7 +74,7 @@ ASSERT_TRUE(AddFolder(0, 0, "folder1")); ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); - GetFakeServer()->DisableNetwork(); + fake_server::FakeServerHttpPostProvider::DisableNetwork(); // Add a new item to trigger another sync cycle. ASSERT_TRUE(AddFolder(0, 0, "folder2")); @@ -84,7 +85,7 @@ // Trigger network change notification and remember time when it happened. // Ensure that scheduler runs canary job immediately. - GetFakeServer()->EnableNetwork(); + fake_server::FakeServerHttpPostProvider::EnableNetwork(); net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::CONNECTION_ETHERNET);
diff --git a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc index 1e4297f0..dd86d3d 100644 --- a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
@@ -99,14 +99,8 @@ ASSERT_TRUE(SamePasswordFormsChecker().Wait()); } -// Disabled due to flakiness on Chrome OS: https://crbug.com/873494. -#if defined(OS_CHROMEOS) -#define MAYBE_SetPassphraseAndAddPassword DISABLED_SetPassphraseAndAddPassword -#else -#define MAYBE_SetPassphraseAndAddPassword SetPassphraseAndAddPassword -#endif IN_PROC_BROWSER_TEST_P(TwoClientPasswordsSyncTest, - E2E_ENABLED(MAYBE_SetPassphraseAndAddPassword)) { + E2E_ENABLED(SetPassphraseAndAddPassword)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; GetSyncService(0)->SetEncryptionPassphrase(kValidPassphrase);
diff --git a/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc b/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc index 24445d1..58137216 100644 --- a/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc
@@ -21,6 +21,7 @@ #include "components/sync/model/model_type_change_processor.h" #include "components/sync/model/model_type_controller_delegate.h" #include "components/sync/model_impl/client_tag_based_model_type_processor.h" +#include "components/sync/test/fake_server/fake_server_http_post_provider.h" #include "net/base/network_change_notifier.h" using browser_sync::ChromeSyncClient; @@ -347,14 +348,14 @@ // Disable network, write value on client 0 and wait for it to attempt // committing the value. This client now has conflicting change. - GetFakeServer()->DisableNetwork(); + fake_server::FakeServerHttpPostProvider::DisableNetwork(); model0->WriteItem(kKey1, kValue2); ASSERT_TRUE(SyncCycleFailedChecker(GetSyncService(0)).Wait()); // Enable network, write different value on client 1 and wait for it to arrive // on server. Server now has value different from client 0 which will cause // conflict when client 0 performs GetUpdates. - GetFakeServer()->EnableNetwork(); + fake_server::FakeServerHttpPostProvider::EnableNetwork(); model1->WriteItem(kKey1, kValue3); model1->WriteItem(kKey2, kValue1); ASSERT_TRUE(ServerCountMatchStatusChecker(syncer::PREFERENCES, 2).Wait());
diff --git a/chrome/browser/ui/startup/startup_tab_provider.cc b/chrome/browser/ui/startup/startup_tab_provider.cc index 8809d8b9..6c2ce8eb 100644 --- a/chrome/browser/ui/startup/startup_tab_provider.cc +++ b/chrome/browser/ui/startup/startup_tab_provider.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/profile_resetter/triggered_profile_resetter.h" #include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -18,8 +18,9 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_manager.h" #include "net/base/url_util.h" +#include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_mutator.h" #if defined(OS_WIN) #include "base/win/windows_version.h" @@ -73,11 +74,13 @@ standard_params.has_seen_welcome_page = prefs && prefs->GetBoolean(prefs::kHasSeenWelcomePage); standard_params.is_signin_allowed = profile->IsSyncAllowed(); - SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile); + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile); standard_params.is_signed_in = - signin_manager && signin_manager->IsAuthenticated(); + identity_manager && identity_manager->HasPrimaryAccount(); standard_params.is_signin_in_progress = - signin_manager && signin_manager->AuthInProgress(); + identity_manager && identity_manager->GetPrimaryAccountMutator() && + identity_manager->GetPrimaryAccountMutator() + ->LegacyIsPrimaryAccountAuthInProgress(); standard_params.is_supervised_user = profile->IsSupervised(); standard_params.is_force_signin_enabled = signin_util::IsForceSigninEnabled();
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index fbd208a4..084754c 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -103,8 +103,8 @@ DCHECK(!refresh_token.empty()); SigninManagerFactory::GetForProfile(profile_)->StartSignInWithRefreshToken( refresh_token, gaia_id, email, password, - base::Bind(&OneClickSigninSyncStarter::ConfirmSignin, - weak_pointer_factory_.GetWeakPtr(), profile_mode)); + base::BindOnce(&OneClickSigninSyncStarter::ConfirmSignin, + weak_pointer_factory_.GetWeakPtr(), profile_mode)); } void OneClickSigninSyncStarter::OnBrowserRemoved(Browser* browser) {
diff --git a/chrome/browser/web_applications/components/web_app_data_retriever.cc b/chrome/browser/web_applications/components/web_app_data_retriever.cc index 057c8c3..1bea07a 100644 --- a/chrome/browser/web_applications/components/web_app_data_retriever.cc +++ b/chrome/browser/web_applications/components/web_app_data_retriever.cc
@@ -95,8 +95,7 @@ // TODO(loyso): Refactor WebAppIconDownloader: crbug.com/907296. icon_downloader_ = std::make_unique<WebAppIconDownloader>( - web_contents, icon_urls, - "Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate", + web_contents, icon_urls, "WebApp.Icon.HttpStatusCodeClassOnCreate", base::BindOnce(&WebAppDataRetriever::OnIconsDownloaded, weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/chrome/common/apps/platform_apps/chrome_apps_message_generator.cc b/chrome/common/apps/platform_apps/chrome_apps_message_generator.cc index bbfda936..e22ff4b 100644 --- a/chrome/common/apps/platform_apps/chrome_apps_message_generator.cc +++ b/chrome/common/apps/platform_apps/chrome_apps_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "chrome/common/apps/platform_apps/chrome_apps_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "chrome/common/apps/platform_apps/chrome_apps_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/chrome/common/common_message_generator.cc b/chrome/common/common_message_generator.cc index eb1dda2..f2dd63b 100644 --- a/chrome/common/common_message_generator.cc +++ b/chrome/common/common_message_generator.cc
@@ -11,11 +11,6 @@ #include "chrome/common/safe_browsing/ipc_protobuf_message_null_macros.h" #include "chrome/common/common_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "chrome/common/safe_browsing/ipc_protobuf_message_null_macros.h" -#include "chrome/common/common_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" #include "chrome/common/safe_browsing/protobuf_message_write_macros.h"
diff --git a/chrome/common/importer/profile_import_process_param_traits.cc b/chrome/common/importer/profile_import_process_param_traits.cc index afb3963f..424a17f 100644 --- a/chrome/common/importer/profile_import_process_param_traits.cc +++ b/chrome/common/importer/profile_import_process_param_traits.cc
@@ -11,11 +11,6 @@ #undef CHROME_COMMON_IMPORTER_PROFILE_IMPORT_PROCESS_PARAM_TRAITS_MACROS_H_ #include "chrome/common/importer/profile_import_process_param_traits_macros.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef CHROME_COMMON_IMPORTER_PROFILE_IMPORT_PROCESS_PARAM_TRAITS_MACROS_H_ -#include "chrome/common/importer/profile_import_process_param_traits_macros.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 6f5f454..4350846 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -503,6 +503,7 @@ deps += [ "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", + "//components/module_installer/android:module_installer_stub_java", "//v8:v8_external_startup_data_assets", ] @@ -3035,6 +3036,7 @@ "//components/favicon/core/test:test_support", "//components/gcm_driver/instance_id/android:instance_id_driver_java", "//components/gcm_driver/instance_id/android:instance_id_driver_test_support_java", + "//components/module_installer/android:module_installer_stub_java", "//content/public/android:content_java", ] if (use_v8_context_snapshot) { @@ -3126,6 +3128,7 @@ "../browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc", "../browser/resource_coordinator/tab_memory_metrics_reporter_unittest.cc", "../browser/resource_coordinator/tab_metrics_logger_unittest.cc", + "../browser/resource_coordinator/tab_ranker/tab_features_unittest.cc", "../browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc", "../browser/resource_coordinator/test_lifecycle_unit.cc", "../browser/resource_coordinator/test_lifecycle_unit.h", @@ -3286,6 +3289,7 @@ deps += [ "//chrome/browser/resource_coordinator:tab_metrics_event_proto", + "//chrome/browser/resource_coordinator/tab_ranker:tab_features_test_helper", "//chrome/services/app_service:unit_tests", "//chrome/services/app_service/public/cpp/:unit_tests", "//components/signin/core/browser:signin_buildflags",
diff --git a/chrome/test/data/chromeos/file_manager/encrypted.zip b/chrome/test/data/chromeos/file_manager/encrypted.zip new file mode 100644 index 0000000..99f3cce --- /dev/null +++ b/chrome/test/data/chromeos/file_manager/encrypted.zip Binary files differ
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index e34a7a89..e274955 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2380,6 +2380,16 @@ ] }, + "CloudManagementEnrollmentMandatory": { + "os": ["win", "linux", "mac"], + "test_policy": {"CloudManagementEnrollmentMandatory": true}, + "pref_mappings": [ + { "pref": "policy.cloud_management_enrollment_mandatory", + "local_state": true + } + ] + }, + "SSLVersionMin": { "os": ["win", "linux", "mac", "chromeos"], "test_policy": { "SSLVersionMin": "tls1.1" },
diff --git a/chrome/test/data/webui/cr_elements/cr_slider_test.js b/chrome/test/data/webui/cr_elements/cr_slider_test.js index 7ba4a31..437a5a3b 100644 --- a/chrome/test/data/webui/cr_elements/cr_slider_test.js +++ b/chrome/test/data/webui/cr_elements/cr_slider_test.js
@@ -113,6 +113,22 @@ assertEquals(97, crSlider.value); }); + test('no-keybindings', () => { + crSlider.noKeybindings = true; + crSlider.value = 0; + pressArrowRight(); + assertEquals(0, crSlider.value); + crSlider.noKeybindings = false; + pressArrowRight(); + assertEquals(1, crSlider.value); + crSlider.noKeybindings = true; + pressArrowRight(); + assertEquals(1, crSlider.value); + crSlider.noKeybindings = false; + pressArrowRight(); + assertEquals(2, crSlider.value); + }); + test('mouse events', () => { crSlider.value = 0; pointerMove(.25); @@ -283,4 +299,21 @@ assertEquals(0, crSlider.min); assertEquals(1, crSlider.max); }); + + test('when drag ends, value updated before dragging-changed event', () => { + const wait = new Promise(resolve => { + crSlider.addEventListener('dragging-changed', e => { + if (!e.detail.value) { + assertEquals(50, crSlider.value); + resolve(); + } + }); + }); + pointerDown(0); + pointerMove(.5); + pointerUp(); + return wait.then(() => { + assertEquals(50, crSlider.value); + }); + }); });
diff --git a/chrome/test/data/webui/list_selection_model_test.html b/chrome/test/data/webui/list_selection_model_test.html index 58e7e70..153db73 100644 --- a/chrome/test/data/webui/list_selection_model_test.html +++ b/chrome/test/data/webui/list_selection_model_test.html
@@ -157,8 +157,8 @@ adjust(sm, 5, 20, 10); - assertEquals(-1, sm.leadIndex, 'lead'); - assertEquals(-1, sm.anchorIndex, 'anchor'); + assertEquals(0, sm.leadIndex, 'lead'); + assertEquals(0, sm.anchorIndex, 'anchor'); assertArrayEquals(range(0, 4), sm.selectedIndexes); } @@ -175,6 +175,64 @@ assertArrayEquals(range(0, 14), sm.selectedIndexes); } +function testAdjust14() { + var sm = createSelectionModel(5, true); + + sm.selectedIndexes = [2, 3]; + sm.leadIndex = sm.anchorIndex = 3; + + adjust(sm, 2, 2, 0); + + assertEquals(2, sm.leadIndex, 'lead'); + assertEquals(2, sm.anchorIndex, 'anchor'); + assertArrayEquals(range(2, 2), sm.selectedIndexes); +} + +function testAdjust15() { + var sm = createSelectionModel(7, true); + + sm.selectedIndexes = [1, 3, 5]; + sm.leadIndex = sm.anchorIndex = 1; + + adjust(sm, 1, 1, 0); + adjust(sm, 2, 1, 0); + adjust(sm, 3, 1, 0); + + assertEquals(3, sm.leadIndex, 'lead'); + assertEquals(3, sm.anchorIndex, 'anchor'); + assertArrayEquals(range(3, 3), sm.selectedIndexes); +} + +function testAdjust16() { + var sm = createSelectionModel(7, true); + + sm.selectedIndexes = [1, 3, 5]; + sm.leadIndex = sm.anchorIndex = 3; + + adjust(sm, 1, 1, 0); + adjust(sm, 2, 1, 0); + adjust(sm, 3, 1, 0); + + assertEquals(3, sm.leadIndex, 'lead'); + assertEquals(3, sm.anchorIndex, 'anchor'); + assertArrayEquals(range(3, 3), sm.selectedIndexes); +} + +function testAdjust17() { + var sm = createSelectionModel(7, true); + + sm.selectedIndexes = [1, 3, 5]; + sm.leadIndex = sm.anchorIndex = 5; + + adjust(sm, 1, 1, 0); + adjust(sm, 2, 1, 0); + adjust(sm, 3, 1, 0); + + assertEquals(3, sm.leadIndex, 'lead'); + assertEquals(3, sm.anchorIndex, 'anchor'); + assertArrayEquals(range(3, 3), sm.selectedIndexes); +} + function testLeadAndAnchor1() { var sm = createSelectionModel(20, true); @@ -191,8 +249,8 @@ sm.leadIndex = sm.anchorIndex = 10; sm.selectAll(); - assertEquals(-1, sm.leadIndex, 'lead'); - assertEquals(-1, sm.anchorIndex, 'anchor'); + assertEquals(0, sm.leadIndex, 'lead'); + assertEquals(0, sm.anchorIndex, 'anchor'); } function testSelectAll() {
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js index 5ee53d0..a8f19dc 100644 --- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -158,10 +158,16 @@ this.runMochaTest(settings_sections_tests.TestNames.PresetDuplex); }); +GEN('#if defined(OS_CHROMEOS)'); TEST_F('PrintPreviewSettingsSectionsTest', 'ColorManaged', function() { this.runMochaTest(settings_sections_tests.TestNames.ColorManaged); }); +TEST_F('PrintPreviewSettingsSectionsTest', 'DuplexManaged', function() { + this.runMochaTest(settings_sections_tests.TestNames.DuplexManaged); +}); +GEN('#endif'); + TEST_F( 'PrintPreviewSettingsSectionsTest', 'DisableMarginsByPagesPerSheet', function() {
diff --git a/chrome/test/data/webui/print_preview/settings_section_test.js b/chrome/test/data/webui/print_preview/settings_section_test.js index d7160ae..4175687 100644 --- a/chrome/test/data/webui/print_preview/settings_section_test.js +++ b/chrome/test/data/webui/print_preview/settings_section_test.js
@@ -29,7 +29,8 @@ PresetCopies: 'preset copies', PresetDuplex: 'preset duplex', DisableMarginsByPagesPerSheet: 'disable margins by pages per sheet', - ColorManaged: 'color selection disabled by policy', + ColorManaged: 'color managed', + DuplexManaged: 'duplex managed', }; const suiteName = 'SettingsSectionsTests'; @@ -416,6 +417,14 @@ return checkbox.parentNode.parentNode.hidden; } + /** + * @param {!CrCheckboxElement} checkbox The checkbox to check + * @return {boolean} Whether the checkbox's parent section is managed. + */ + function isSectionManaged(checkbox) { + return checkbox.parentNode.parentNode.managed; + } + test(assert(TestNames.Other), function() { const optionsElement = page.$$('print-preview-other-options-settings'); const headerFooter = optionsElement.$$('#headerFooter'); @@ -1126,13 +1135,15 @@ // Policy has no effect. colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]}, colorPolicy: print_preview.ColorMode.COLOR, + colorDefault: print_preview.ColorMode.COLOR, expectedValue: true, expectedHidden: true, }, { - // Policy contradicts actual capabilities and should be ignored. + // Policy contradicts actual capabilities and is ignored. colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]}, colorPolicy: print_preview.ColorMode.GRAY, + colorDefault: print_preview.ColorMode.GRAY, expectedValue: true, expectedHidden: true, }, @@ -1145,14 +1156,32 @@ ] }, colorPolicy: print_preview.ColorMode.COLOR, + // Default mismatches restriction and is ignored. + colorDefault: print_preview.ColorMode.GRAY, expectedValue: true, expectedHidden: false, expectedManaged: true, + }, + { + // Default defined by policy but setting is modifiable. + colorCap: { + option: [ + {type: 'STANDARD_MONOCHROME', is_default: true}, + {type: 'STANDARD_COLOR'} + ] + }, + colorDefault: print_preview.ColorMode.COLOR, + expectedValue: true, + expectedHidden: false, + expectedManaged: false, }].forEach(subtestParams => { capabilities = print_preview_test_utils.getCddTemplate('FooPrinter').capabilities; capabilities.printer.color = subtestParams.colorCap; - const policies = {allowedColorModes: subtestParams.colorPolicy}; + const policies = { + allowedColorModes: subtestParams.colorPolicy, + defaultColorMode: subtestParams.colorDefault, + }; // In practice |capabilities| are always set after |policies| and // observers only check for |capabilities|, so the order is important. page.set('destination_.policies', policies); @@ -1173,6 +1202,85 @@ } }); }); + + test(assert(TestNames.DuplexManaged), function() { + toggleMoreSettings(); + const optionsElement = page.$$('print-preview-other-options-settings'); + const duplexElement = optionsElement.$$('#duplex'); + + // Remove duplex capability. + let capabilities = + print_preview_test_utils.getCddTemplate('FooPrinter').capabilities; + delete capabilities.printer.duplex; + + [{ + // Policy has no effect. + duplexCap: {option: [{type: 'NO_DUPLEX', is_default: true}]}, + duplexPolicy: print_preview.DuplexModeRestriction.SIMPLEX, + duplexDefault: print_preview.DuplexModeRestriction.SIMPLEX, + expectedValue: false, + expectedHidden: true, + }, + { + // Policy contradicts actual capabilities and is ignored. + duplexCap: {option: [{type: 'NO_DUPLEX', is_default: true}]}, + duplexPolicy: print_preview.DuplexModeRestriction.DUPLEX, + duplexDefault: print_preview.DuplexModeRestriction.LONG_EDGE, + expectedValue: false, + expectedHidden: true, + }, + { + // Policy overrides default. + duplexCap: { + option: [ + {type: 'NO_DUPLEX', is_default: true}, {type: 'LONG_EDGE'}, + {type: 'SHORT_EDGE'} + ] + }, + duplexPolicy: print_preview.DuplexModeRestriction.DUPLEX, + // Default mismatches restriction and is ignored. + duplexDefault: print_preview.DuplexModeRestriction.SIMPLEX, + expectedValue: true, + expectedHidden: false, + expectedManaged: true, + }, + { + // Default defined by policy but setting is modifiable. + duplexCap: { + option: [ + {type: 'NO_DUPLEX', is_default: true}, {type: 'LONG_EDGE'}, + {type: 'SHORT_EDGE'} + ] + }, + duplexDefault: print_preview.DuplexModeRestriction.LONG_EDGE, + expectedValue: true, + expectedHidden: false, + expectedManaged: false, + }].forEach(subtestParams => { + capabilities = + print_preview_test_utils.getCddTemplate('FooPrinter').capabilities; + capabilities.printer.duplex = subtestParams.duplexCap; + const policies = { + allowedDuplexModes: subtestParams.duplexPolicy, + defaultDuplexMode: subtestParams.duplexDefault, + }; + // In practice |capabilities| are always set after |policies| and + // observers only check for |capabilities|, so the order is important. + page.set('destination_.policies', policies); + page.set('destination_.capabilities', capabilities); + page.$$('print-preview-model').applyDestinationSpecificPolicies(); + assertEquals( + subtestParams.expectedValue, page.getSettingValue('duplex')); + assertEquals( + subtestParams.expectedHidden, isSectionHidden(duplexElement)); + if (!subtestParams.expectedHidden) { + assertEquals(subtestParams.expectedValue, duplexElement.checked); + assertEquals( + subtestParams.expectedManaged, isSectionManaged(duplexElement)); + assertEquals(subtestParams.expectedManaged, duplexElement.disabled); + } + }); + }); }); return {
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 8cf25b4..82b757a 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -204,13 +204,6 @@ services->emplace(device::mojom::kVrIsolatedServiceName, service_info); #endif -#if BUILDFLAG(ENABLE_PRINTING) - service_manager::EmbeddedServiceInfo pdf_compositor_info; - pdf_compositor_info.factory = base::BindRepeating( - &printing::CreatePdfCompositorService, GetUserAgent()); - services->emplace(printing::mojom::kServiceName, pdf_compositor_info); -#endif - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) || \ (BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)) service_manager::EmbeddedServiceInfo printing_info; @@ -328,6 +321,13 @@ return std::make_unique<patch::PatchService>(std::move(request)); #endif +#if BUILDFLAG(ENABLE_PRINTING) + if (service_name == printing::mojom::kServiceName) { + return printing::CreatePdfCompositorService(GetUserAgent(), + std::move(request)); + } +#endif + #if defined(OS_CHROMEOS) if (service_name == chromeos::ime::mojom::kServiceName) return std::make_unique<chromeos::ime::ImeService>(std::move(request));
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 4ff8abb..e71a58c5 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -128,11 +128,12 @@ namespace { #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) -static std::unique_ptr<service_manager::Service> CreateMediaService( - CastContentBrowserClient* browser_client) { +static void CreateMediaService(CastContentBrowserClient* browser_client, + service_manager::mojom::ServiceRequest request) { + std::unique_ptr<::media::MediaService> service; #if defined(OS_ANDROID) - return std::make_unique<::media::MediaService>( - std::make_unique<::media::AndroidMojoMediaClient>()); + service = std::make_unique<::media::MediaService>( + std::make_unique<::media::AndroidMojoMediaClient>(), std::move(request)); #else auto mojo_media_client = std::make_unique<media::CastMojoMediaClient>( browser_client->GetCmaBackendFactory(), @@ -141,8 +142,11 @@ browser_client->GetVideoModeSwitcher(), browser_client->GetVideoResolutionPolicy(), browser_client->media_resource_tracker()); - return std::make_unique<::media::MediaService>(std::move(mojo_media_client)); + service = std::make_unique<::media::MediaService>( + std::move(mojo_media_client), std::move(request)); #endif // defined(OS_ANDROID) + + service_manager::Service::RunUntilTermination(std::move(service)); } #endif // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) @@ -737,14 +741,15 @@ std::move(application_session_id))); } -void CastContentBrowserClient::RegisterInProcessServices( - StaticServiceMap* services, - content::ServiceManagerConnection* connection) { +void CastContentBrowserClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) - service_manager::EmbeddedServiceInfo info; - info.factory = base::Bind(&CreateMediaService, base::Unretained(this)); - info.task_runner = GetMediaTaskRunner(); - services->insert(std::make_pair(::media::mojom::kMediaServiceName, info)); + if (service_name == ::media::mojom::kMediaServiceName) { + GetMediaTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&CreateMediaService, this, std::move(request))); + } #endif }
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index b4972ec06..dcdc3f6 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -182,9 +182,9 @@ void ExposeInterfacesToMediaService( service_manager::BinderRegistry* registry, content::RenderFrameHost* render_frame_host) override; - void RegisterInProcessServices( - StaticServiceMap* services, - content::ServiceManagerConnection* connection) override; + void HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( base::StringPiece service_name) override; void GetAdditionalMappedFilesForChildProcess(
diff --git a/chromecast/common/extensions_api/cast_extension_messages.cc b/chromecast/common/extensions_api/cast_extension_messages.cc index cbbc2cb..a696cb6 100644 --- a/chromecast/common/extensions_api/cast_extension_messages.cc +++ b/chromecast/common/extensions_api/cast_extension_messages.cc
@@ -23,16 +23,6 @@ "chrome_extension_messages.h" #endif -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_ -#include "chromecast/common/extensions_api/cast_extension_messages.h" -#include "content/public/common/common_param_traits.h" -#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_ -#error "Failed to include header chromecast/common/extensions_api/" - "chrome_extension_messages.h" -#endif - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/chromeos/components/drivefs/drivefs_host.cc b/chromeos/components/drivefs/drivefs_host.cc index 5db1ced..b241ce34 100644 --- a/chromeos/components/drivefs/drivefs_host.cc +++ b/chromeos/components/drivefs/drivefs_host.cc
@@ -67,16 +67,13 @@ explicit AccountTokenDelegate(DriveFsHost* host) : host_(host) {} void GetAccessToken(bool use_cached, - const std::string& client_id, - const std::string& app_id, mojom::DriveFsDelegate::GetAccessTokenCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); if (get_access_token_callback_) { std::move(callback).Run(mojom::AccessTokenStatus::kTransientError, ""); return; } - const std::string& token = - MaybeGetCachedToken(use_cached, client_id, app_id); + const std::string& token = MaybeGetCachedToken(use_cached); if (!token.empty()) { std::move(callback).Run(mojom::AccessTokenStatus::kSuccess, token); return; @@ -86,6 +83,14 @@ &AccountTokenDelegate::AccountReady, base::Unretained(this))); } + base::Optional<std::string> TakeCachedAccessToken() { + const auto& token = MaybeGetCachedToken(true); + if (token.empty()) { + return base::nullopt; + } + return token; + } + private: void AccountReady(const AccountInfo& info, const identity::AccountState& state) { @@ -113,9 +118,7 @@ .Run(mojom::AccessTokenStatus::kSuccess, *access_token); } - const std::string& MaybeGetCachedToken(bool use_cached, - const std::string& client_id, - const std::string& app_id) { + const std::string& MaybeGetCachedToken(bool use_cached) { // Return value from cache at most once per mount. if (!use_cached || host_->clock_->Now() >= last_token_expiry_) { last_token_.clear(); @@ -176,8 +179,12 @@ binding_.Bind(mojo::MakeRequest(&delegate)); binding_.set_connection_error_handler( base::BindOnce(&MountState::OnConnectionError, base::Unretained(this))); + + auto access_token = host_->account_token_delegate_->TakeCachedAccessToken(); + token_fetch_attempted_ = bool{access_token}; bootstrap->Init( - {base::in_place, host_->delegate_->GetAccountId().GetUserEmail()}, + {base::in_place, host_->delegate_->GetAccountId().GetUserEmail(), + std::move(access_token)}, mojo::MakeRequest(&drivefs_), std::move(delegate)); drivefs_.set_connection_error_handler( base::BindOnce(&MountState::OnConnectionError, base::Unretained(this))); @@ -270,8 +277,8 @@ const std::vector<std::string>& scopes, GetAccessTokenCallback callback) override { DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); - host_->account_token_delegate_->GetAccessToken( - !token_fetch_attempted_, client_id, app_id, std::move(callback)); + host_->account_token_delegate_->GetAccessToken(!token_fetch_attempted_, + std::move(callback)); token_fetch_attempted_ = true; }
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc index 8dbb56f..15e55b7d7 100644 --- a/chromeos/components/drivefs/drivefs_host_unittest.cc +++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -404,6 +404,7 @@ mojom::DriveFsRequest drive_fs_request, mojom::DriveFsDelegatePtr delegate) override { EXPECT_EQ("test@example.com", config->user_email); + init_access_token_ = std::move(config->access_token); binding_.Bind(std::move(drive_fs_request)); mojo::FuseInterface(std::move(pending_delegate_request_), delegate.PassInterface()); @@ -427,6 +428,7 @@ mojom::DriveFsDelegatePtr delegate_ptr_; mojom::DriveFsDelegateRequest pending_delegate_request_; std::string token_; + base::Optional<std::string> init_access_token_; private: DISALLOW_COPY_AND_ASSIGN(DriveFsHostTest); @@ -439,6 +441,7 @@ host_->GetDataPath()); ASSERT_NO_FATAL_FAILURE(DoMount()); + EXPECT_FALSE(init_access_token_); EXPECT_EQ(base::FilePath("/media/drivefsroot/salt-g-ID"), host_->GetMountPath()); @@ -966,7 +969,7 @@ // Second mount attempt should reuse already available token. ASSERT_NO_FATAL_FAILURE(DoMount()); - ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); + EXPECT_EQ("auth token", init_access_token_.value_or("")); } TEST_F(DriveFsHostTest, Remount_CachedOnceOnly) { @@ -989,9 +992,9 @@ // Second mount attempt should reuse already available token. ASSERT_NO_FATAL_FAILURE(DoMount()); - ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); + EXPECT_EQ("auth token", init_access_token_.value_or("")); - // But if it asks for token more than once it goes straight to identity. + // But if it asks for token it goes straight to identity. ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token 2"); } @@ -1040,10 +1043,40 @@ std::move(mock_identity_manager_.callbacks().front()) .Run("auth token", clock_.Now() + base::TimeDelta::FromHours(1), GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + mock_identity_manager_.bindings_->FlushForTesting(); // Second mount will reuse previous token. ASSERT_NO_FATAL_FAILURE(DoMount()); + EXPECT_EQ("auth token", init_access_token_.value_or("")); +} +TEST_F(DriveFsHostTest, Remount_RequestInflightCompleteAfterMount) { + ASSERT_NO_FATAL_FAILURE(DoMount()); + mock_identity_manager_.set_pause_requests(true); + + delegate_ptr_->GetAccessToken( + "client ID", "app ID", {"scope1", "scope2"}, + base::BindLambdaForTesting([&](mojom::AccessTokenStatus status, + const std::string& token) { FAIL(); })); + + base::Optional<base::TimeDelta> delay = base::TimeDelta::FromSeconds(5); + EXPECT_CALL(*host_delegate_, OnUnmounted(delay)); + SendOnUnmounted(delay); + base::RunLoop().RunUntilIdle(); + ASSERT_NO_FATAL_FAILURE(DoUnmount()); + + // Second mount will reuse previous token. + ASSERT_NO_FATAL_FAILURE(DoMount()); + EXPECT_FALSE(init_access_token_); + + // Now the response is ready. + ASSERT_EQ(1u, mock_identity_manager_.callbacks().size()); + std::move(mock_identity_manager_.callbacks().front()) + .Run("auth token", clock_.Now() + base::TimeDelta::FromHours(1), + GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + mock_identity_manager_.bindings_->FlushForTesting(); + + // A new request will reuse the cached token. ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); }
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom index a49aebd..063f71a 100644 --- a/chromeos/components/drivefs/mojom/drivefs.mojom +++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -100,8 +100,12 @@ OnHeartbeat(); }; +// Next MinVersion: 2 struct DriveFsConfiguration { string user_email; + + [MinVersion=1] + string? access_token; }; enum AccessTokenStatus {
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index b8862f9..7c90eb3 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -91,6 +91,8 @@ "//components/timers", "//components/url_formatter", "//components/user_manager", + "//components/user_prefs:user_prefs", + "//content/public/browser:browser", "//content/public/common", "//device/base", "//device/bluetooth", @@ -315,6 +317,7 @@ "//components/account_id", "//components/keyed_service/content", "//components/prefs:test_support", + "//components/session_manager/core:core", "//components/user_manager", "//components/user_manager:test_support", "//content/public/common",
diff --git a/components/arc/arc_prefs.cc b/components/arc/arc_prefs.cc index 8b16ce62..d957a9d 100644 --- a/components/arc/arc_prefs.cc +++ b/components/arc/arc_prefs.cc
@@ -93,6 +93,25 @@ // Integer pref indicating the ecryptfs to ext4 migration strategy. One of // options: forbidden = 0, migrate = 1, wipe = 2 or ask the user = 3. const char kEcryptfsMigrationStrategy[] = "ecryptfs_migration_strategy"; +// A preference that persists total engagement time across sessions, which is +// accumulated and sent to UMA once a day. +const char kEngagementTimeTotal[] = "arc.metrics.engagement_time.total"; +// A preference that persists foreground engagement time across sessions, which +// is accumulated and sent to UMA once a day. +const char kEngagementTimeForeground[] = + "arc.metrics.engagement_time.foreground"; +// A preference that persists background engagement time across sessions, which +// is accumulated and sent to UMA once a day. +const char kEngagementTimeBackground[] = + "arc.metrics.engagement_time.background"; +// A preference that saves the OS version when engagement time was last +// recorded. Old results will be discarded if a version change is detected. +const char kEngagementTimeOsVersion[] = + "arc.metrics.engagement_time.os_version"; +// A preference that saves the day ID (number of days since origin of Time) when +// engagement time was last recorded. Accumulated results are sent to UMA if day +// ID has changed. +const char kEngagementTimeDayId[] = "arc.metrics.engagement_time.day_id"; // A preference that indicates the user has accepted voice interaction activity // control settings. const char kVoiceInteractionActivityControlAccepted[] = @@ -157,6 +176,11 @@ registry->RegisterBooleanPref(kArcTermsAccepted, false); registry->RegisterBooleanPref(kArcTermsShownInOobe, false); registry->RegisterBooleanPref(kArcVoiceInteractionValuePropAccepted, false); + registry->RegisterTimeDeltaPref(kEngagementTimeBackground, base::TimeDelta()); + registry->RegisterIntegerPref(kEngagementTimeDayId, 0); + registry->RegisterTimeDeltaPref(kEngagementTimeForeground, base::TimeDelta()); + registry->RegisterStringPref(kEngagementTimeOsVersion, ""); + registry->RegisterTimeDeltaPref(kEngagementTimeTotal, base::TimeDelta()); registry->RegisterBooleanPref(kVoiceInteractionContextEnabled, false); registry->RegisterBooleanPref(kVoiceInteractionEnabled, false); registry->RegisterBooleanPref(kVoiceInteractionHotwordEnabled, false);
diff --git a/components/arc/arc_prefs.h b/components/arc/arc_prefs.h index 00f728b..caefac0e7 100644 --- a/components/arc/arc_prefs.h +++ b/components/arc/arc_prefs.h
@@ -39,6 +39,11 @@ ARC_EXPORT extern const char kArcCompatibleFilesystemChosen[]; ARC_EXPORT extern const char kArcVoiceInteractionValuePropAccepted[]; ARC_EXPORT extern const char kEcryptfsMigrationStrategy[]; +ARC_EXPORT extern const char kEngagementTimeBackground[]; +ARC_EXPORT extern const char kEngagementTimeDayId[]; +ARC_EXPORT extern const char kEngagementTimeForeground[]; +ARC_EXPORT extern const char kEngagementTimeOsVersion[]; +ARC_EXPORT extern const char kEngagementTimeTotal[]; // TODO(b/110211045): Move Assistant related prefs to ash. ARC_EXPORT extern const char kVoiceInteractionActivityControlAccepted[];
diff --git a/components/arc/metrics/DEPS b/components/arc/metrics/DEPS index ce83197d..83bdfd1e 100644 --- a/components/arc/metrics/DEPS +++ b/components/arc/metrics/DEPS
@@ -1,4 +1,6 @@ include_rules = [ + "+components/user_prefs", + "+content/public/browser", "+ui/aura", "+ui/wm/public", ]
diff --git a/components/arc/metrics/arc_metrics_service.cc b/components/arc/metrics/arc_metrics_service.cc index 75f5e4b1..d835eaa 100644 --- a/components/arc/metrics/arc_metrics_service.cc +++ b/components/arc/metrics/arc_metrics_service.cc
@@ -12,13 +12,22 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" +#include "base/system/sys_info.h" +#include "base/time/default_clock.h" +#include "base/time/default_tick_clock.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/power_manager/idle.pb.h" #include "chromeos/dbus/session_manager_client.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/arc/arc_prefs.h" #include "components/arc/arc_util.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "components/exo/wm_helper.h" +#include "components/prefs/pref_service.h" +#include "components/session_manager/core/session_manager.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" namespace arc { @@ -34,6 +43,11 @@ constexpr char kGmsProcessNamePrefix[] = "com.google.android.gms"; constexpr char kBootProgressEnableScreen[] = "boot_progress_enable_screen"; +constexpr base::TimeDelta kUpdateEngagementTimePeriod = + base::TimeDelta::FromMinutes(1); +constexpr base::TimeDelta kSaveEngagementTimeToPrefsPeriod = + base::TimeDelta::FromMinutes(30); + std::string BootTypeToString(mojom::BootType boot_type) { switch (boot_type) { case mojom::BootType::UNKNOWN: @@ -49,6 +63,10 @@ return ""; } +inline int GetDayId(const base::Clock* clock) { + return clock->Now().LocalMidnight().since_origin().InDays(); +} + class ArcWindowDelegateImpl : public ArcMetricsService::ArcWindowDelegate { public: explicit ArcWindowDelegateImpl(ArcMetricsService* service) @@ -112,23 +130,52 @@ return ArcMetricsServiceFactory::GetForBrowserContextForTesting(context); } +// static +BrowserContextKeyedServiceFactory* ArcMetricsService::GetFactory() { + return ArcMetricsServiceFactory::GetInstance(); +} + ArcMetricsService::ArcMetricsService(content::BrowserContext* context, ArcBridgeService* bridge_service) : arc_bridge_service_(bridge_service), arc_window_delegate_(std::make_unique<ArcWindowDelegateImpl>(this)), process_observer_(this), native_bridge_type_(NativeBridgeType::UNKNOWN), + pref_service_(user_prefs::UserPrefs::Get(context)), + clock_(base::DefaultClock::GetInstance()), + tick_clock_(base::DefaultTickClock::GetInstance()), + last_update_ticks_(tick_clock_->NowTicks()), weak_ptr_factory_(this) { arc_bridge_service_->metrics()->SetHost(this); arc_bridge_service_->process()->AddObserver(&process_observer_); arc_window_delegate_->RegisterActivationChangeObserver(); + session_manager::SessionManager::Get()->AddObserver(this); + chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( + this); + + DCHECK(pref_service_); + RestoreEngagementTimeFromPrefs(); + update_engagement_time_timer_.Start(FROM_HERE, kUpdateEngagementTimePeriod, + this, + &ArcMetricsService::UpdateEngagementTime); + save_engagement_time_to_prefs_timer_.Start( + FROM_HERE, kSaveEngagementTimeToPrefsPeriod, this, + &ArcMetricsService::SaveEngagementTimeToPrefs); } ArcMetricsService::~ArcMetricsService() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + save_engagement_time_to_prefs_timer_.Stop(); + update_engagement_time_timer_.Stop(); + UpdateEngagementTime(); + SaveEngagementTimeToPrefs(); + + chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( + this); + session_manager::SessionManager::Get()->RemoveObserver(this); + arc_window_delegate_->UnregisterActivationChangeObserver(); arc_bridge_service_->process()->RemoveObserver(&process_observer_); arc_bridge_service_->metrics()->SetHost(nullptr); - arc_window_delegate_->UnregisterActivationChangeObserver(); } void ArcMetricsService::SetArcWindowDelegateForTesting( @@ -136,15 +183,23 @@ arc_window_delegate_ = std::move(delegate); } +void ArcMetricsService::SetClockForTesting(base::Clock* clock) { + clock_ = clock; +} + +void ArcMetricsService::SetTickClockForTesting(base::TickClock* tick_clock) { + tick_clock_ = tick_clock; +} + void ArcMetricsService::OnProcessConnectionReady() { VLOG(2) << "Start updating process list."; - timer_.Start(FROM_HERE, kRequestProcessListPeriod, this, - &ArcMetricsService::RequestProcessList); + request_process_list_timer_.Start(FROM_HERE, kRequestProcessListPeriod, this, + &ArcMetricsService::RequestProcessList); } void ArcMetricsService::OnProcessConnectionClosed() { VLOG(2) << "Stop updating process list."; - timer_.Stop(); + request_process_list_timer_.Stop(); } void ArcMetricsService::RequestProcessList() { @@ -261,13 +316,145 @@ wm::ActivationChangeObserver::ActivationReason reason, aura::Window* gained_active, aura::Window* lost_active) { - if (!arc_window_delegate_->IsArcAppWindow(gained_active)) + UpdateEngagementTime(); + was_arc_window_active_ = arc_window_delegate_->IsArcAppWindow(gained_active); + if (!was_arc_window_active_) return; UMA_HISTOGRAM_ENUMERATION( "Arc.UserInteraction", UserInteractionType::APP_CONTENT_WINDOW_INTERACTION); } +void ArcMetricsService::OnSessionStateChanged() { + UpdateEngagementTime(); + was_session_active_ = + session_manager::SessionManager::Get()->session_state() == + session_manager::SessionState::ACTIVE; +} + +void ArcMetricsService::ScreenIdleStateChanged( + const power_manager::ScreenIdleState& proto) { + UpdateEngagementTime(); + was_screen_dimmed_ = proto.dimmed(); +} + +void ArcMetricsService::OnTaskCreated(int32_t task_id, + const std::string& package_name, + const std::string& activity, + const std::string& intent) { + UpdateEngagementTime(); + task_ids_.push_back(task_id); +} + +void ArcMetricsService::OnTaskDestroyed(int32_t task_id) { + UpdateEngagementTime(); + auto it = std::find(task_ids_.begin(), task_ids_.end(), task_id); + DCHECK(it != task_ids_.end()); + task_ids_.erase(it); +} + +void ArcMetricsService::RestoreEngagementTimeFromPrefs() { + // Restore accumulated results only if they were recorded on the same OS + // version. + if (pref_service_->GetString(prefs::kEngagementTimeOsVersion) == + base::SysInfo::OperatingSystemVersion()) { + day_id_ = pref_service_->GetInteger(prefs::kEngagementTimeDayId); + engagement_time_total_ = + pref_service_->GetTimeDelta(prefs::kEngagementTimeTotal); + engagement_time_foreground_ = + pref_service_->GetTimeDelta(prefs::kEngagementTimeForeground); + engagement_time_background_ = + pref_service_->GetTimeDelta(prefs::kEngagementTimeBackground); + } else { + ResetEngagementTimePrefs(); + } + + RecordEngagementTimeToUmaIfNeeded(); +} + +void ArcMetricsService::SaveEngagementTimeToPrefs() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(pref_service_); + + pref_service_->SetString(prefs::kEngagementTimeOsVersion, + base::SysInfo::OperatingSystemVersion()); + pref_service_->SetInteger(prefs::kEngagementTimeDayId, day_id_); + pref_service_->SetTimeDelta(prefs::kEngagementTimeTotal, + engagement_time_total_); + pref_service_->SetTimeDelta(prefs::kEngagementTimeForeground, + engagement_time_foreground_); + pref_service_->SetTimeDelta(prefs::kEngagementTimeBackground, + engagement_time_background_); +} + +void ArcMetricsService::UpdateEngagementTime() { + VLOG(2) << "last state: dimmed=" << was_screen_dimmed_ + << " active=" << was_session_active_ + << " focus=" << was_arc_window_active_ + << " #tasks=" << task_ids_.size(); + + base::TimeTicks now = tick_clock_->NowTicks(); + base::TimeDelta elapsed = now - last_update_ticks_; + + if (ShouldAccumulateEngagementTotalTime()) { + VLOG(2) << "accumulate to total time " << elapsed; + engagement_time_total_ += elapsed; + if (ShouldAccumulateEngagementForegroundTime()) { + VLOG(2) << "accumulate to foreground time " << elapsed; + engagement_time_foreground_ += elapsed; + } else if (ShouldAccumulateEngagementBackgroundTime()) { + VLOG(2) << "accumulate to background time " << elapsed; + engagement_time_background_ += elapsed; + } + } + + last_update_ticks_ = now; + RecordEngagementTimeToUmaIfNeeded(); +} + +void ArcMetricsService::RecordEngagementTimeToUmaIfNeeded() { + if (!ShouldRecordEngagementTimeToUma()) + return; + VLOG(2) << "day changed, recording engagement time to UMA"; + UMA_HISTOGRAM_CUSTOM_TIMES( + "Arc.EngagementTime.Total", engagement_time_total_, + base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(1) + kUpdateEngagementTimePeriod, 50); + UMA_HISTOGRAM_CUSTOM_TIMES( + "Arc.EngagementTime.Foreground", engagement_time_foreground_, + base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(1) + kUpdateEngagementTimePeriod, 50); + UMA_HISTOGRAM_CUSTOM_TIMES( + "Arc.EngagementTime.Background", engagement_time_background_, + base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(1) + kUpdateEngagementTimePeriod, 50); + ResetEngagementTimePrefs(); +} + +void ArcMetricsService::ResetEngagementTimePrefs() { + day_id_ = GetDayId(clock_); + engagement_time_total_ = base::TimeDelta(); + engagement_time_foreground_ = base::TimeDelta(); + engagement_time_background_ = base::TimeDelta(); + SaveEngagementTimeToPrefs(); +} + +bool ArcMetricsService::ShouldAccumulateEngagementTotalTime() const { + return was_session_active_ && !was_screen_dimmed_; +} + +bool ArcMetricsService::ShouldAccumulateEngagementForegroundTime() const { + return was_arc_window_active_; +} + +bool ArcMetricsService::ShouldAccumulateEngagementBackgroundTime() const { + return task_ids_.size() > 0; +} + +bool ArcMetricsService::ShouldRecordEngagementTimeToUma() const { + return day_id_ != GetDayId(clock_); +} + ArcMetricsService::ProcessObserver::ProcessObserver( ArcMetricsService* arc_metrics_service) : arc_metrics_service_(arc_metrics_service) {}
diff --git a/components/arc/metrics/arc_metrics_service.h b/components/arc/metrics/arc_metrics_service.h index 1d7de00..faffff74 100644 --- a/components/arc/metrics/arc_metrics_service.h +++ b/components/arc/metrics/arc_metrics_service.h
@@ -12,17 +12,28 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "base/timer/timer.h" +#include "chromeos/dbus/power_manager_client.h" #include "components/arc/common/metrics.mojom.h" #include "components/arc/common/process.mojom.h" #include "components/arc/connection_observer.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/session_manager/core/session_manager_observer.h" #include "ui/wm/public/activation_change_observer.h" +class BrowserContextKeyedServiceFactory; +class PrefService; + namespace aura { class Window; } // namespace aura +namespace base { +class Clock; +class TickClock; +} // namespace base + namespace content { class BrowserContext; } // namespace content @@ -34,6 +45,8 @@ // Collects information from other ArcServices and send UMA metrics. class ArcMetricsService : public KeyedService, public wm::ActivationChangeObserver, + public session_manager::SessionManagerObserver, + public chromeos::PowerManagerClient::Observer, public mojom::MetricsHost { public: // These values are persisted to logs, and should therefore never be @@ -65,6 +78,12 @@ void SetArcWindowDelegateForTesting( std::unique_ptr<ArcWindowDelegate> delegate); + // Sets Clock for testing. + void SetClockForTesting(base::Clock* clock); + + // Sets TickClock for testing. + void SetTickClockForTesting(base::TickClock* tick_clock); + // Returns singleton instance for the given BrowserContext, // or nullptr if the browser |context| is not allowed to use ARC. static ArcMetricsService* GetForBrowserContext( @@ -72,6 +91,9 @@ static ArcMetricsService* GetForBrowserContextForTesting( content::BrowserContext* context); + // Returns factory instance for this class. + static BrowserContextKeyedServiceFactory* GetFactory(); + ArcMetricsService(content::BrowserContext* context, ArcBridgeService* bridge_service); ~ArcMetricsService() override; @@ -95,6 +117,21 @@ aura::Window* gained_active, aura::Window* lost_active) override; + // session_manager::SessionManagerObserver overrides. + void OnSessionStateChanged() override; + + // chromeos::PowerManagerClient::Observer overrides. + void ScreenIdleStateChanged( + const power_manager::ScreenIdleState& proto) override; + + // ArcAppListPrefs::Observer callbacks which are called through + // ArcMetricsServiceProxy. + void OnTaskCreated(int32_t task_id, + const std::string& package_name, + const std::string& activity, + const std::string& intent); + void OnTaskDestroyed(int32_t task_id); + NativeBridgeType native_bridge_type_for_testing() const { return native_bridge_type_; } @@ -124,16 +161,60 @@ mojom::BootType boot_type, base::Optional<base::TimeTicks> arc_start_time); + // Restores accumulated ARC++ engagement time in previous sessions from + // profile preferences. + void RestoreEngagementTimeFromPrefs(); + + // Called periodically to save accumulated results to profile preferences. + void SaveEngagementTimeToPrefs(); + + // Called whenever engagement state is changed. Time spent in last state is + // accumulated to corresponding metrics. + void UpdateEngagementTime(); + + // Records accumulated engagement time metrics to UMA if necessary (i.e. day + // has changed). + void RecordEngagementTimeToUmaIfNeeded(); + + // Resets accumulated engagement times to zero, and updates both OS version + // and day ID. + void ResetEngagementTimePrefs(); + + bool ShouldAccumulateEngagementTotalTime() const; + bool ShouldAccumulateEngagementForegroundTime() const; + bool ShouldAccumulateEngagementBackgroundTime() const; + bool ShouldRecordEngagementTimeToUma() const; + THREAD_CHECKER(thread_checker_); ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. std::unique_ptr<ArcWindowDelegate> arc_window_delegate_; ProcessObserver process_observer_; - base::RepeatingTimer timer_; + base::RepeatingTimer request_process_list_timer_; NativeBridgeType native_bridge_type_; + PrefService* const pref_service_; + const base::Clock* clock_; + const base::TickClock* tick_clock_; + base::RepeatingTimer update_engagement_time_timer_; + base::RepeatingTimer save_engagement_time_to_prefs_timer_; + base::TimeTicks last_update_ticks_; + + // States for determining which engagement metrics should we accumulate to. + bool was_session_active_ = false; + bool was_screen_dimmed_ = false; + bool was_arc_window_active_ = false; + std::vector<int32_t> task_ids_; + + // Accumulated results and associated state which are saved to profile + // preferences at fixed interval. + int day_id_ = 0; + base::TimeDelta engagement_time_total_; + base::TimeDelta engagement_time_foreground_; + base::TimeDelta engagement_time_background_; + // Always keep this the last member of this class to make sure it's the // first thing to be destructed. base::WeakPtrFactory<ArcMetricsService> weak_ptr_factory_;
diff --git a/components/arc/metrics/arc_metrics_service_unittest.cc b/components/arc/metrics/arc_metrics_service_unittest.cc index 6116f758..95bb316 100644 --- a/components/arc/metrics/arc_metrics_service_unittest.cc +++ b/components/arc/metrics/arc_metrics_service_unittest.cc
@@ -14,11 +14,17 @@ #include "base/metrics/histogram_samples.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" +#include "base/time/clock.h" +#include "base/time/tick_clock.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/power_manager/idle.pb.h" +#include "components/arc/arc_prefs.h" #include "components/arc/arc_service_manager.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "components/arc/test/test_browser_context.h" +#include "components/session_manager/core/session_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" @@ -73,6 +79,73 @@ DISALLOW_COPY_AND_ASSIGN(FakeArcWindowDelegate); }; +// Fake base::Clock to simulate wall clock time changes, which ArcMetricsService +// uses to determine if cumulative metrics should be recorded to UMA. +class FakeClock : public base::Clock { + public: + FakeClock() : now_(base::Time::Now()) {} + + ~FakeClock() override = default; + + base::Time Now() const override { return now_; } + + void TimeElapsed(base::TimeDelta delta) { now_ += delta; } + + private: + base::Time now_; + + DISALLOW_COPY_AND_ASSIGN(FakeClock); +}; + +// Fake base::TickClock to simulate time changes which are being recorded by +// metrics. +class FakeTickClock : public base::TickClock { + public: + FakeTickClock() = default; + ~FakeTickClock() override = default; + + base::TimeTicks NowTicks() const override { return now_ticks_; } + + void TimeElapsed(base::TimeDelta delta) { now_ticks_ += delta; } + + private: + base::TimeTicks now_ticks_; + + DISALLOW_COPY_AND_ASSIGN(FakeTickClock); +}; + +// Helper class that initializes DBusThreadManager for testing, and ensures the +// lifetime of DBusThreadManager. +class DBusThreadManagerLifetimeHelper { + public: + DBusThreadManagerLifetimeHelper() { + // Get DBusThreadManagerSetter for setting fake DBusThreadManager clients. + // This also initializes the global DBusThreadManager instance. + std::unique_ptr<chromeos::DBusThreadManagerSetter> + dbus_thread_manager_setter = + chromeos::DBusThreadManager::GetSetterForTesting(); + + // Set fake clients for testing. + dbus_thread_manager_setter->SetSessionManagerClient( + std::make_unique<chromeos::FakeSessionManagerClient>()); + dbus_thread_manager_setter->SetPowerManagerClient( + std::make_unique<chromeos::FakePowerManagerClient>()); + } + + ~DBusThreadManagerLifetimeHelper() { + // Destroy the global DBusThreadManager instance. + chromeos::DBusThreadManager::Shutdown(); + } +}; + +// Initializes dependencies before creating ArcMetricsService instance. +ArcMetricsService* CreateArcMetricsService(TestBrowserContext* context) { + // Register preferences for ARC++ engagement time metrics. + prefs::RegisterProfilePrefs(context->pref_registry()); + + return ArcMetricsService::GetForBrowserContextForTesting(context); +} + // The event names the container sends to Chrome. constexpr std::array<const char*, 11> kBootEvents{ "boot_progress_start", @@ -92,17 +165,21 @@ ArcMetricsServiceTest() : arc_service_manager_(std::make_unique<ArcServiceManager>()), context_(std::make_unique<TestBrowserContext>()), - service_( - ArcMetricsService::GetForBrowserContextForTesting(context_.get())) { - chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( - std::make_unique<chromeos::FakeSessionManagerClient>()); + service_(CreateArcMetricsService(context_.get())) { GetSessionManagerClient()->set_arc_available(true); + + auto fake_arc_window_delegate = std::make_unique<FakeArcWindowDelegate>(); + fake_arc_window_delegate_ = fake_arc_window_delegate.get(); + service_->SetArcWindowDelegateForTesting( + std::move(fake_arc_window_delegate)); + fake_arc_window_ = fake_arc_window_delegate_->CreateFakeArcWindow(); + fake_non_arc_window_ = fake_arc_window_delegate_->CreateFakeNonArcWindow(); + + service_->SetClockForTesting(&fake_clock_); + service_->SetTickClockForTesting(&fake_tick_clock_); } - ~ArcMetricsServiceTest() override { - service_->Shutdown(); - chromeos::DBusThreadManager::Shutdown(); - } + ~ArcMetricsServiceTest() override {} ArcMetricsService* service() { return service_; } @@ -124,32 +201,55 @@ return events; } + void SetSessionState(session_manager::SessionState state) { + session_manager_.SetSessionState(state); + } + + void SetScreenDimmed(bool is_screen_dimmed) { + power_manager::ScreenIdleState screen_idle_state; + screen_idle_state.set_dimmed(is_screen_dimmed); + GetPowerManagerClient()->SendScreenIdleStateChanged(screen_idle_state); + } + + void TriggerRecordEngagementTimeToUma() { + // Trigger UMA record by changing to next day. + fake_clock_.TimeElapsed(base::TimeDelta::FromDays(1)); + service_->OnSessionStateChanged(); + } + FakeArcWindowDelegate* fake_arc_window_delegate() { return fake_arc_window_delegate_; } aura::Window* fake_arc_window() { return fake_arc_window_.get(); } aura::Window* fake_non_arc_window() { return fake_non_arc_window_.get(); } - private: - void SetUp() override { - auto delegate = std::make_unique<FakeArcWindowDelegate>(); - fake_arc_window_delegate_ = delegate.get(); - service_->SetArcWindowDelegateForTesting(std::move(delegate)); - fake_arc_window_ = fake_arc_window_delegate_->CreateFakeArcWindow(); - fake_non_arc_window_ = fake_arc_window_delegate_->CreateFakeNonArcWindow(); - } + FakeTickClock* fake_tick_clock() { return &fake_tick_clock_; } + private: chromeos::FakeSessionManagerClient* GetSessionManagerClient() { return static_cast<chromeos::FakeSessionManagerClient*>( chromeos::DBusThreadManager::Get()->GetSessionManagerClient()); } + chromeos::FakePowerManagerClient* GetPowerManagerClient() { + return static_cast<chromeos::FakePowerManagerClient*>( + chromeos::DBusThreadManager::Get()->GetPowerManagerClient()); + } + content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<ArcServiceManager> arc_service_manager_; + + // DBusThreadManager and SessionManager should outlive TestBrowserContext + // which destructs ArcMetricsService in dtor. + DBusThreadManagerLifetimeHelper dbus_thread_manager_lifetime_helper_; + session_manager::SessionManager session_manager_; std::unique_ptr<TestBrowserContext> context_; + std::unique_ptr<aura::Window> fake_arc_window_; std::unique_ptr<aura::Window> fake_non_arc_window_; FakeArcWindowDelegate* fake_arc_window_delegate_; // Owned by |service_| + FakeClock fake_clock_; + FakeTickClock fake_tick_clock_; ArcMetricsService* const service_; @@ -354,5 +454,136 @@ static_cast<int>(UserInteractionType::APP_CONTENT_WINDOW_INTERACTION), 1); } +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeSessionLocked) { + base::HistogramTester tester; + + // Make session inactive for 1 sec. Nothing should be recorded. + SetSessionState(session_manager::SessionState::LOCKED); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeSessionActive) { + base::HistogramTester tester; + + // Make session active for 1 sec. Should be recorded as total time. + SetSessionState(session_manager::SessionState::ACTIVE); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeScreenDimmed) { + base::HistogramTester tester; + SetSessionState(session_manager::SessionState::ACTIVE); + + // Dim screen off for 1 sec. Nothing should be recorded. + SetScreenDimmed(true); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeArcWindowFocused) { + base::HistogramTester tester; + SetSessionState(session_manager::SessionState::ACTIVE); + + // Focus an ARC++ window for 1 sec. Should be recorded as total time and + // foreground time. + fake_arc_window_delegate()->FocusWindow(fake_arc_window()); + service()->OnWindowActivated( + wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT, + fake_arc_window(), nullptr); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeNonArcWindowFocused) { + base::HistogramTester tester; + SetSessionState(session_manager::SessionState::ACTIVE); + + // Focus an non-ARC++ window for 1 sec. Should be recorded as total time. + fake_arc_window_delegate()->FocusWindow(fake_non_arc_window()); + service()->OnWindowActivated( + wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT, + fake_arc_window(), nullptr); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + +TEST_F(ArcMetricsServiceTest, RecordEngagementTimeAppInBackground) { + base::HistogramTester tester; + SetSessionState(session_manager::SessionState::ACTIVE); + + // Open an ARC++ app in the background and wait for 1 sec. Should be recorded + // as total time and background time. + service()->OnTaskCreated(1, "", "", ""); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(0), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(1), 1); +} + +TEST_F(ArcMetricsServiceTest, + RecordEngagementTimeAppInBackgroundAndArcWindowFocused) { + base::HistogramTester tester; + SetSessionState(session_manager::SessionState::ACTIVE); + + // With an ARC++ app in the background, focus an ARC++ window for 1 sec. + // Should be recorded as total time and foreground time. + service()->OnTaskCreated(1, "", "", ""); + fake_arc_window_delegate()->FocusWindow(fake_arc_window()); + service()->OnWindowActivated( + wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT, + fake_arc_window(), nullptr); + fake_tick_clock()->TimeElapsed(base::TimeDelta::FromSeconds(1)); + + TriggerRecordEngagementTimeToUma(); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Total", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Foreground", + base::TimeDelta::FromSeconds(1), 1); + tester.ExpectTimeBucketCount("Arc.EngagementTime.Background", + base::TimeDelta::FromSeconds(0), 1); +} + } // namespace } // namespace arc
diff --git a/components/arc/test/test_browser_context.h b/components/arc/test/test_browser_context.h index 89051d8..66fc548 100644 --- a/components/arc/test/test_browser_context.h +++ b/components/arc/test/test_browser_context.h
@@ -20,6 +20,8 @@ TestBrowserContext(); ~TestBrowserContext() override; + inline PrefRegistrySimple* pref_registry() { return prefs_.registry(); } + private: BrowserContextDependencyManager* const browser_context_dependency_manager_; TestingPrefServiceSimple prefs_;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 732f94c6..f5cb2169 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -52,8 +52,20 @@ // // TODO(crbug.com/806868): Consider embedding that wait right into // WebController and eliminate double-lookup. - virtual void WaitForElement(const std::vector<std::string>& selectors, - base::OnceCallback<void(bool)> callback) = 0; + virtual void ShortWaitForElementExist( + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) = 0; + + // Wait for up to |max_wait_time| for the element |selectors| to be visible on + // the page, then call |callback| with true if the element was visible, false + // otherwise. + // + // If |allow_interrupt| interrupts can run while waiting. + virtual void WaitForElementVisible( + base::TimeDelta max_wait_time, + bool allow_interrupt, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) = 0; // Click or tap the element given by |selectors| on the web page. virtual void ClickOrTapElement(const std::vector<std::string>& selectors,
diff --git a/components/autofill_assistant/browser/actions/autofill_action.cc b/components/autofill_assistant/browser/actions/autofill_action.cc index c486bd91..03227da 100644 --- a/components/autofill_assistant/browser/actions/autofill_action.cc +++ b/components/autofill_assistant/browser/actions/autofill_action.cc
@@ -212,10 +212,10 @@ } void AutofillAction::FillFormWithData(ActionDelegate* delegate) { - delegate->WaitForElement(selectors_, - base::BindOnce(&AutofillAction::OnWaitForElement, - weak_ptr_factory_.GetWeakPtr(), - base::Unretained(delegate))); + delegate->ShortWaitForElementExist( + selectors_, base::BindOnce(&AutofillAction::OnWaitForElement, + weak_ptr_factory_.GetWeakPtr(), + base::Unretained(delegate))); } void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
diff --git a/components/autofill_assistant/browser/actions/autofill_action_unittest.cc b/components/autofill_assistant/browser/actions/autofill_action_unittest.cc index 8d9b66fe..bfe319f 100644 --- a/components/autofill_assistant/browser/actions/autofill_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/autofill_action_unittest.cc
@@ -114,7 +114,7 @@ .WillByDefault(Invoke([this]() { return std::make_unique<BatchElementChecker>(&mock_web_controller_); })); - ON_CALL(mock_action_delegate_, OnWaitForElement(_, _)) + ON_CALL(mock_action_delegate_, OnShortWaitForElementExist(_, _)) .WillByDefault(RunOnceCallback<1>(true)); }
diff --git a/components/autofill_assistant/browser/actions/click_action.cc b/components/autofill_assistant/browser/actions/click_action.cc index d9de7a5..7ca50d4 100644 --- a/components/autofill_assistant/browser/actions/click_action.cc +++ b/components/autofill_assistant/browser/actions/click_action.cc
@@ -22,7 +22,7 @@ void ClickAction::InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) { DCHECK_GT(proto_.click().element_to_click().selectors_size(), 0); - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(proto_.click().element_to_click().selectors()), base::BindOnce(&ClickAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/focus_element_action.cc b/components/autofill_assistant/browser/actions/focus_element_action.cc index 39a78f4f..7796a65 100644 --- a/components/autofill_assistant/browser/actions/focus_element_action.cc +++ b/components/autofill_assistant/browser/actions/focus_element_action.cc
@@ -28,7 +28,7 @@ if (!focus_element.title().empty()) { delegate->ShowStatusMessage(focus_element.title()); } - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(focus_element.element().selectors()), base::BindOnce(&FocusElementAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/highlight_element_action.cc b/components/autofill_assistant/browser/actions/highlight_element_action.cc index d63a097..a455e3c 100644 --- a/components/autofill_assistant/browser/actions/highlight_element_action.cc +++ b/components/autofill_assistant/browser/actions/highlight_element_action.cc
@@ -23,7 +23,7 @@ ActionDelegate* delegate, ProcessActionCallback callback) { DCHECK_GT(proto_.highlight_element().element().selectors_size(), 0); - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(proto_.highlight_element().element().selectors()), base::BindOnce(&HighlightElementAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 3350d10..41dbb12 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -24,15 +24,30 @@ MOCK_METHOD0(CreateBatchElementChecker, std::unique_ptr<BatchElementChecker>()); - void WaitForElement(const std::vector<std::string>& selectors, - base::OnceCallback<void(bool)> callback) { - OnWaitForElement(selectors, callback); + void ShortWaitForElementExist( + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) override { + OnShortWaitForElementExist(selectors, callback); } - MOCK_METHOD2(OnWaitForElement, + MOCK_METHOD2(OnShortWaitForElementExist, void(const std::vector<std::string>&, base::OnceCallback<void(bool)>&)); + void WaitForElementVisible(base::TimeDelta max_wait_time, + bool allow_interrupt, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) override { + OnWaitForElementVisible(max_wait_time, allow_interrupt, selectors, + callback); + } + + MOCK_METHOD4(OnWaitForElementVisible, + void(base::TimeDelta, + bool, + const std::vector<std::string>&, + base::OnceCallback<void(bool)>&)); + MOCK_METHOD1(ShowStatusMessage, void(const std::string& message)); MOCK_METHOD2(ClickOrTapElement, void(const std::vector<std::string>& selectors,
diff --git a/components/autofill_assistant/browser/actions/select_option_action.cc b/components/autofill_assistant/browser/actions/select_option_action.cc index b59e8f7..6a905456 100644 --- a/components/autofill_assistant/browser/actions/select_option_action.cc +++ b/components/autofill_assistant/browser/actions/select_option_action.cc
@@ -27,7 +27,7 @@ DCHECK(select_option.has_selected_option()); DCHECK_GT(select_option.element().selectors_size(), 0); - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(select_option.element().selectors()), base::BindOnce(&SelectOptionAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/set_attribute_action.cc b/components/autofill_assistant/browser/actions/set_attribute_action.cc index 5806b5ce..f413831 100644 --- a/components/autofill_assistant/browser/actions/set_attribute_action.cc +++ b/components/autofill_assistant/browser/actions/set_attribute_action.cc
@@ -22,7 +22,7 @@ void SetAttributeAction::InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) { - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(proto_.set_attribute().element().selectors()), base::BindOnce(&SetAttributeAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc index d52b2ca..b34432b 100644 --- a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc +++ b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
@@ -25,7 +25,7 @@ void SetFormFieldValueAction::InternalProcessAction( ActionDelegate* delegate, ProcessActionCallback callback) { - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(proto_.set_form_value().element().selectors()), base::BindOnce(&SetFormFieldValueAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate), @@ -43,18 +43,41 @@ // TODO(crbug.com/806868): Add flag to allow simulating key presses to set // field value. - delegate->SetFieldValue( - ExtractVector(proto_.set_form_value().element().selectors()), - proto_.set_form_value().value(0).text(), - /* simulate_key_presses= */ false, - base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + + // Start with first value, then call OnSetFieldValue() recursively until done. + OnSetFieldValue(delegate, std::move(callback), /* next = */ 0, true); } -void SetFormFieldValueAction::OnSetFieldValue(ProcessActionCallback callback, +void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, + ProcessActionCallback callback, + int next, bool status) { - UpdateProcessedAction(status ? ACTION_APPLIED : OTHER_ACTION_STATUS); - std::move(callback).Run(std::move(processed_action_proto_)); + // If something went wrong or we are out of values: finish + if (!status || next >= proto_.set_form_value().value_size()) { + UpdateProcessedAction(status ? ACTION_APPLIED : OTHER_ACTION_STATUS); + std::move(callback).Run(std::move(processed_action_proto_)); + return; + } + + const auto& key_field = proto_.set_form_value().value(next); + const auto& selectors = + ExtractVector(proto_.set_form_value().element().selectors()); + switch (key_field.keypress_case()) { + case SetFormFieldValueProto_KeyPress::kText: + delegate->SetFieldValue( + selectors, key_field.text(), + /* simulate_key_presses = */ false, + base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, + weak_ptr_factory_.GetWeakPtr(), delegate, + std::move(callback), /* next = */ next + 1)); + break; + case SetFormFieldValueProto_KeyPress::kKeycode: + // TODO(arbesser): handle keyboard presses + default: + DLOG(ERROR) << "Unrecognized field for SetFormFieldValueProto_KeyPress"; + OnSetFieldValue(delegate, std::move(callback), next, false); + break; + } } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action.h b/components/autofill_assistant/browser/actions/set_form_field_value_action.h index be0aec9f..e1620ccc 100644 --- a/components/autofill_assistant/browser/actions/set_form_field_value_action.h +++ b/components/autofill_assistant/browser/actions/set_form_field_value_action.h
@@ -27,7 +27,10 @@ void OnWaitForElement(ActionDelegate* delegate, ProcessActionCallback callback, bool element_found); - void OnSetFieldValue(ProcessActionCallback callback, bool status); + void OnSetFieldValue(ActionDelegate* delegate, + ProcessActionCallback callback, + int next, + bool status); base::WeakPtrFactory<SetFormFieldValueAction> weak_ptr_factory_;
diff --git a/components/autofill_assistant/browser/actions/upload_dom_action.cc b/components/autofill_assistant/browser/actions/upload_dom_action.cc index c893c37..76baae1 100644 --- a/components/autofill_assistant/browser/actions/upload_dom_action.cc +++ b/components/autofill_assistant/browser/actions/upload_dom_action.cc
@@ -22,7 +22,7 @@ void UploadDomAction::InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) { DCHECK_GT(proto_.upload_dom().tree_root().selectors_size(), 0); - delegate->WaitForElement( + delegate->ShortWaitForElementExist( ExtractVector(proto_.upload_dom().tree_root().selectors()), base::BindOnce(&UploadDomAction::OnWaitForElement, weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
diff --git a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc index 3e36cf3..ed28027 100644 --- a/components/autofill_assistant/browser/actions/wait_for_dom_action.cc +++ b/components/autofill_assistant/browser/actions/wait_for_dom_action.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/callback.h" #include "base/time/time.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" @@ -21,36 +20,30 @@ namespace autofill_assistant { -WaitForDomAction::WaitForDomAction(const ActionProto& proto) : Action(proto) {} +WaitForDomAction::WaitForDomAction(const ActionProto& proto) + : Action(proto), weak_ptr_factory_(this) {} WaitForDomAction::~WaitForDomAction() {} void WaitForDomAction::InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) { DCHECK_GT(proto_.wait_for_dom().selectors_size(), 0); - batch_element_checker_ = delegate->CreateBatchElementChecker(); - batch_element_checker_->AddElementCheck( - kVisibilityCheck, ExtractVector(proto_.wait_for_dom().selectors()), - base::DoNothing()); - - base::TimeDelta duration = kDefaultCheckDuration; + base::TimeDelta max_wait_time = kDefaultCheckDuration; int timeout_ms = proto_.wait_for_dom().timeout_ms(); if (timeout_ms > 0) - duration = base::TimeDelta::FromMilliseconds(timeout_ms); + max_wait_time = base::TimeDelta::FromMilliseconds(timeout_ms); - batch_element_checker_->Run( - duration, - /* try_done= */ base::DoNothing(), - /* all_done= */ + delegate->WaitForElementVisible( + max_wait_time, proto_.wait_for_dom().allow_interrupt(), + ExtractVector(proto_.wait_for_dom().selectors()), base::BindOnce(&WaitForDomAction::OnCheckDone, - // batch_element_checker_ is owned by this - base::Unretained(this), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } -void WaitForDomAction::OnCheckDone(ProcessActionCallback callback) { - UpdateProcessedAction(batch_element_checker_->all_found() - ? ACTION_APPLIED - : ELEMENT_RESOLUTION_FAILED); +void WaitForDomAction::OnCheckDone(ProcessActionCallback callback, + bool element_found) { + UpdateProcessedAction(element_found ? ACTION_APPLIED + : ELEMENT_RESOLUTION_FAILED); std::move(callback).Run(std::move(processed_action_proto_)); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/wait_for_dom_action.h b/components/autofill_assistant/browser/actions/wait_for_dom_action.h index 7a5dd0e..4f58ba5 100644 --- a/components/autofill_assistant/browser/actions/wait_for_dom_action.h +++ b/components/autofill_assistant/browser/actions/wait_for_dom_action.h
@@ -10,8 +10,8 @@ #include <vector> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "components/autofill_assistant/browser/actions/action.h" -#include "components/autofill_assistant/browser/batch_element_checker.h" #include "components/autofill_assistant/browser/service.pb.h" namespace autofill_assistant { @@ -26,9 +26,10 @@ void InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) override; - void OnCheckDone(ProcessActionCallback callback); + void OnCheckDone(ProcessActionCallback callback, bool element_found); - std::unique_ptr<BatchElementChecker> batch_element_checker_; + base::WeakPtrFactory<WaitForDomAction> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(WaitForDomAction); };
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index f1a5cde..1223c99c 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -242,9 +242,29 @@ StartPeriodicScriptChecks(); } +void Controller::ExecuteScript(const std::string& script_path) { + DCHECK(!script_tracker_->running()); + + GetUiController()->ShowOverlay(); + touchable_element_area_.ClearElements(); + + StopPeriodicScriptChecks(); + // Runnable scripts will be checked and reported if necessary after executing + // the script. + script_tracker_->ClearRunnableScripts(); + GetUiController()->UpdateScripts({}); // Clear scripts. + // TODO(crbug.com/806868): Consider making ClearRunnableScripts part of + // ExecuteScripts to simplify the controller. + script_tracker_->ExecuteScript( + script_path, base::BindOnce(&Controller::OnScriptExecuted, + // script_tracker_ is owned by Controller. + base::Unretained(this), script_path)); +} + void Controller::OnScriptExecuted(const std::string& script_path, - ScriptExecutor::Result result) { - GetUiController()->HideOverlay(); + const ScriptExecutor::Result& result) { + if (!allow_autostart_) + GetUiController()->HideOverlay(); if (!result.success) { LOG(ERROR) << "Failed to execute script " << script_path; GetUiController()->ShowStatusMessage( @@ -289,6 +309,44 @@ GetUiController()->ShutdownGracefully(); } +bool Controller::MaybeAutostartScript( + const std::vector<ScriptHandle>& runnable_scripts) { + // We want to g through all runnable autostart interrupts first, one at a + // time. To do that, always run highest priority autostartable interrupt from + // runnable_script, which is ordered by priority. + for (const auto& script : runnable_scripts) { + if (script.autostart && script.interrupt) { + std::string script_path = script.path; + ExecuteScript(script_path); + // making a copy of script.path is necessary, as ExecuteScript clears + // runnable_scripts, so script.path will not survive until the end of + // ExecuteScript. + return true; + } + } + + // Under specific conditions, we can directly run a non-interrupt script + // without first displaying it. This is meant to work only at the very + // beginning, when no non-interrupt scripts have run, and only if there's + // exactly one autostartable script. + if (allow_autostart_) { + int autostart_count = 0; + std::string autostart_path; + for (const auto& script : runnable_scripts) { + if (script.autostart && !script.interrupt) { + autostart_count++; + autostart_path = script.path; + } + } + if (autostart_count == 1) { + allow_autostart_ = false; + ExecuteScript(autostart_path); + return true; + } + } + return false; +} + void Controller::OnClickOverlay() { GetUiController()->HideOverlay(); // TODO(crbug.com/806868): Stop executing scripts. @@ -296,21 +354,11 @@ void Controller::OnScriptSelected(const std::string& script_path) { DCHECK(!script_path.empty()); - DCHECK(!script_tracker_->running()); - GetUiController()->ShowOverlay(); - touchable_element_area_.ClearElements(); + // This is a script selected from the UI, so it should disable autostart. + allow_autostart_ = false; - StopPeriodicScriptChecks(); - // Runnable scripts will be checked and reported if necessary after executing - // the script. - script_tracker_->ClearRunnableScripts(); - GetUiController()->UpdateScripts({}); // Clear scripts. - allow_autostart_ = false; // Only ever autostart the very first script. - script_tracker_->ExecuteScript( - script_path, base::BindOnce(&Controller::OnScriptExecuted, - // script_tracker_ is owned by Controller. - base::Unretained(this), script_path)); + ExecuteScript(script_path); } std::string Controller::GetDebugContext() { @@ -351,9 +399,6 @@ switch (type) { case blink::WebInputEvent::kTouchStart: case blink::WebInputEvent::kGestureTapDown: - // Disable autostart after interaction with the web page. - allow_autostart_ = false; - if (!script_tracker_->running()) { script_tracker_->CheckScripts(kPeriodicScriptCheckInterval); StartPeriodicScriptChecks(); @@ -387,23 +432,8 @@ GetUiController()->HideOverlay(); } - // Under specific conditions, we can directly run a script without first - // displaying it. This is meant to work only at the very beginning, when no - // scripts have run, there has been no interaction with the webpage and only - // if there's exactly one runnable autostartable script. - if (allow_autostart_) { - int autostart_count = 0; - std::string autostart_path; - for (const auto& script : runnable_scripts) { - if (script.autostart) { - autostart_count++; - autostart_path = script.path; - } - } - if (autostart_count == 1) { - OnScriptSelected(autostart_path); - return; - } + if (MaybeAutostartScript(runnable_scripts)) { + return; } // Show the initial prompt if available. @@ -415,11 +445,10 @@ } } - // Update the set of scripts. Only scripts that are not marked as autostart - // should be shown. + // Update the set of scripts in the UI. std::vector<ScriptHandle> scripts_to_update; for (const auto& script : runnable_scripts) { - if (!script.autostart) { + if (!script.autostart && !script.name.empty()) { scripts_to_update.emplace_back(script); } }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index b18a2d0..e48fc14c 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -70,9 +70,9 @@ void GetOrCheckScripts(const GURL& url); void OnGetScripts(const GURL& url, bool result, const std::string& response); - void OnScriptChosen(const std::string& script_path); + void ExecuteScript(const std::string& script_path); void OnScriptExecuted(const std::string& script_path, - ScriptExecutor::Result result); + const ScriptExecutor::Result& result); // Check script preconditions every few seconds for a certain number of times. // If checks are already running, StartPeriodicScriptChecks resets the count. @@ -84,6 +84,10 @@ void OnPeriodicScriptCheck(); void GiveUp(); + // Runs autostart scripts from |runnable_scripts|, if the conditions are + // right. Returns true if a script was auto-started. + bool MaybeAutostartScript(const std::vector<ScriptHandle>& runnable_scripts); + // Overrides content::UiDelegate: void Start(const GURL& initialUrl) override; void OnClickOverlay() override;
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 5e0c419..ca08811 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -20,11 +20,13 @@ namespace autofill_assistant { using ::testing::_; +using ::testing::AtLeast; using ::testing::Contains; using ::testing::ElementsAre; using ::testing::Eq; using ::testing::InSequence; using ::testing::NiceMock; +using ::testing::Not; using ::testing::Pair; using ::testing::ReturnRef; using ::testing::Sequence; @@ -98,8 +100,8 @@ .WillByDefault(RunOnceCallback<2>(true, "")); // Scripts run, but have no actions. - ON_CALL(*mock_service_, OnGetActions(_, _, _)) - .WillByDefault(RunOnceCallback<2>(true, "")); + ON_CALL(*mock_service_, OnGetActions(_, _, _, _, _)) + .WillByDefault(RunOnceCallback<4>(true, "")); // Make WebController::GetUrl accessible. ON_CALL(*mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_)); @@ -122,6 +124,14 @@ return script; } + static void RunOnce(SupportedScriptProto* proto) { + auto* run_once = proto->mutable_presentation() + ->mutable_precondition() + ->add_script_status_match(); + run_once->set_script(proto->path()); + run_once->set_status(SCRIPT_STATUS_NOT_RUN); + } + void SetLastCommittedUrl(const GURL& url) { url_ = url; tester_->SetLastCommittedURL(url); @@ -138,10 +148,6 @@ controller_->LoadProgressChanged(web_contents(), progress); } - void SimulateUserInteraction(const blink::WebInputEvent::Type type) { - controller_->DidGetUserInteraction(type); - } - // Sets up the next call to the service for scripts to return |response|. void SetNextScriptResponse(const SupportsScriptResponseProto& response) { std::string response_str; @@ -151,6 +157,15 @@ .WillOnce(RunOnceCallback<2>(true, response_str)); } + // Sets up all calls to the service for scripts to return |response|. + void SetRepeatedScriptResponse(const SupportsScriptResponseProto& response) { + std::string response_str; + response.SerializeToString(&response_str); + + EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) + .WillRepeatedly(RunOnceCallback<2>(true, response_str)); + } + UiDelegate* GetUiDelegate() { return controller_; } GURL url_; @@ -197,8 +212,8 @@ }); // 5. script1 run successfully (no actions). - EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script1"), _, _)) - .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script1"), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, "")); // 6. As nothing is selected the flow terminates. @@ -240,8 +255,8 @@ actions_response.add_actions()->mutable_stop(); std::string actions_response_str; actions_response.SerializeToString(&actions_response_str); - EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _)) - .WillOnce(RunOnceCallback<2>(true, actions_response_str)); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, actions_response_str)); EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(true, "")); @@ -272,8 +287,8 @@ actions_response.add_actions()->mutable_reset(); std::string actions_response_str; actions_response.SerializeToString(&actions_response_str); - EXPECT_CALL(*mock_service_, OnGetActions(StrEq("reset"), _, _)) - .WillOnce(RunOnceCallback<2>(true, actions_response_str)); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("reset"), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, actions_response_str)); // 3. Report the result of running that action. EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _)) @@ -330,23 +345,72 @@ AddRunnableScript(&script_response, "alsorunnable"); SetNextScriptResponse(script_response); - EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _)) - .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, "")); + + SimulateNavigateToUrl(GURL("http://a.example.com/path")); +} + +TEST_F(ControllerTest, AutostartFirstInterrupt) { + SupportsScriptResponseProto script_response; + AddRunnableScript(&script_response, "runnable"); + + auto* interrupt1 = + AddRunnableScript(&script_response, "autostart interrupt 1"); + interrupt1->mutable_presentation()->set_interrupt(true); + interrupt1->mutable_presentation()->set_priority(1); + interrupt1->mutable_presentation()->set_autostart(true); + + auto* interrupt2 = + AddRunnableScript(&script_response, "autostart interrupt 2"); + interrupt2->mutable_presentation()->set_interrupt(true); + interrupt2->mutable_presentation()->set_priority(2); + interrupt2->mutable_presentation()->set_autostart(true); + + SetNextScriptResponse(script_response); + + EXPECT_CALL(*mock_service_, + OnGetActions(StrEq("autostart interrupt 1"), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(false, "")); + // The script fails, ending the flow. What matters is that the correct + // expectation is met. + + SimulateNavigateToUrl(GURL("http://a.example.com/path")); +} + +TEST_F(ControllerTest, InterruptThenAutostart) { + SupportsScriptResponseProto script_response; + AddRunnableScript(&script_response, "runnable"); + + auto* interrupt = AddRunnableScript(&script_response, "autostart interrupt"); + interrupt->mutable_presentation()->set_interrupt(true); + interrupt->mutable_presentation()->set_autostart(true); + RunOnce(interrupt); + + auto* autostart = AddRunnableScript(&script_response, "autostart"); + autostart->mutable_presentation()->set_autostart(true); + RunOnce(autostart); + + SetRepeatedScriptResponse(script_response); + + { + testing::InSequence seq; + EXPECT_CALL(*mock_service_, + OnGetActions(StrEq("autostart interrupt"), _, _, _, _)); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _, _, _)); + } SimulateNavigateToUrl(GURL("http://a.example.com/path")); } TEST_F(ControllerTest, AutostartIsNotPassedToTheUi) { SupportsScriptResponseProto script_response; - AddRunnableScript(&script_response, "runnable") - ->mutable_presentation() - ->set_autostart(true); - SetNextScriptResponse(script_response); + auto* autostart = AddRunnableScript(&script_response, "runnable"); + autostart->mutable_presentation()->set_autostart(true); + RunOnce(autostart); + SetRepeatedScriptResponse(script_response); - EXPECT_CALL(*mock_ui_controller_, UpdateScripts(SizeIs(0))); - EXPECT_CALL(*mock_service_, OnGetActions(StrEq("runnable"), _, _)).Times(0); - - SimulateUserInteraction(blink::WebInputEvent::kTouchStart); + EXPECT_CALL(*mock_ui_controller_, UpdateScripts(SizeIs(0))).Times(AtLeast(1)); SimulateNavigateToUrl(GURL("http://a.example.com/path")); }
diff --git a/components/autofill_assistant/browser/mock_service.h b/components/autofill_assistant/browser/mock_service.h index b9754e54..02ae803 100644 --- a/components/autofill_assistant/browser/mock_service.h +++ b/components/autofill_assistant/browser/mock_service.h
@@ -32,15 +32,17 @@ ResponseCallback& callback)); void GetActions(const std::string& script_path, - const GURL& ignored_url, + const GURL& url, const std::map<std::string, std::string>& parameters, const std::string& server_payload, ResponseCallback callback) override { - OnGetActions(script_path, parameters, callback); + OnGetActions(script_path, url, parameters, server_payload, callback); } - MOCK_METHOD3(OnGetActions, + MOCK_METHOD5(OnGetActions, void(const std::string& script_path, + const GURL& url, const std::map<std::string, std::string>& parameters, + const std::string& server_payload, ResponseCallback& callback)); void GetNextActions(
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h index 383029f..cf0e9964 100644 --- a/components/autofill_assistant/browser/mock_ui_controller.h +++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -23,6 +23,7 @@ MOCK_METHOD1(SetUiDelegate, void(UiDelegate* ui_delegate)); MOCK_METHOD1(ShowStatusMessage, void(const std::string& message)); + MOCK_METHOD0(GetStatusMessage, std::string()); MOCK_METHOD0(ShowOverlay, void()); MOCK_METHOD0(HideOverlay, void()); MOCK_METHOD0(Shutdown, void());
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index 5793efe..1b9439d9 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -85,14 +85,15 @@ const auto& presentation = script_proto.presentation(); script->handle.name = presentation.name(); script->handle.autostart = presentation.autostart(); + script->handle.interrupt = presentation.interrupt(); script->handle.initial_prompt = presentation.initial_prompt(); script->handle.highlight = presentation.highlight(); script->precondition = ScriptPrecondition::FromProto( script_proto.path(), presentation.precondition()); script->priority = presentation.priority(); - if (script->handle.name.empty() || script->handle.path.empty() || - !script->precondition) { + if (script->handle.path.empty() || !script->precondition || + (script->handle.name.empty() && !script->handle.interrupt)) { LOG(ERROR) << "Ignored invalid or incomplete script '" << script->handle.path << "'"; continue;
diff --git a/components/autofill_assistant/browser/protocol_utils_unittest.cc b/components/autofill_assistant/browser/protocol_utils_unittest.cc index 7b065fc..93a6f0d 100644 --- a/components/autofill_assistant/browser/protocol_utils_unittest.cc +++ b/components/autofill_assistant/browser/protocol_utils_unittest.cc
@@ -77,6 +77,27 @@ EXPECT_NE(nullptr, scripts[0]->precondition); } +TEST(ProtocolUtilsTest, AllowInterruptsWithNoName) { + SupportsScriptResponseProto proto; + + SupportedScriptProto* script = proto.add_scripts(); + script->set_path("path"); + auto* presentation = script->mutable_presentation(); + presentation->set_autostart(true); + presentation->set_initial_prompt("prompt"); + presentation->set_interrupt(true); + presentation->mutable_precondition()->add_domain("www.example.com"); + + std::vector<std::unique_ptr<Script>> scripts; + std::string proto_str; + proto.SerializeToString(&proto_str); + EXPECT_TRUE(ProtocolUtils::ParseScripts(proto_str, &scripts)); + ASSERT_THAT(scripts, SizeIs(1)); + EXPECT_EQ("path", scripts[0]->handle.path); + EXPECT_EQ("", scripts[0]->handle.name); + EXPECT_TRUE(scripts[0]->handle.interrupt); +} + TEST(ProtocolUtilsTest, CreateInitialScriptActionsRequest) { std::map<std::string, std::string> parameters; parameters["a"] = "b";
diff --git a/components/autofill_assistant/browser/script.h b/components/autofill_assistant/browser/script.h index 7ac3f42..320aa60 100644 --- a/components/autofill_assistant/browser/script.h +++ b/components/autofill_assistant/browser/script.h
@@ -26,6 +26,10 @@ // be shown. bool autostart; bool highlight; + + // If set, the script might be run during WaitForDom actions with + // allow_interrupt=true. + bool interrupt; }; // Script represents a sequence of actions.
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index eff8ec3..051e1af 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -27,15 +27,19 @@ // Maximum amount of time normal actions should implicitly wait for a selector // to show up. -constexpr base::TimeDelta kWaitForSelectorDeadline = +constexpr base::TimeDelta kShortWaitForElementDeadline = base::TimeDelta::FromSeconds(2); } // namespace -ScriptExecutor::ScriptExecutor(const std::string& script_path, - const std::string& server_payload, - ScriptExecutor::Listener* listener, - ScriptExecutorDelegate* delegate) +ScriptExecutor::ScriptExecutor( + const std::string& script_path, + const std::string& server_payload, + ScriptExecutor::Listener* listener, + std::map<std::string, ScriptStatusProto>* scripts_state, + const std::vector<Script*>* ordered_interrupts, + ScriptExecutorDelegate* delegate) : script_path_(script_path), + initial_server_payload_(server_payload), last_server_payload_(server_payload), listener_(listener), delegate_(delegate), @@ -43,8 +47,11 @@ should_stop_script_(false), should_clean_contextual_ui_on_finish_(false), previous_action_type_(ActionProto::ACTION_INFO_NOT_SET), + scripts_state_(scripts_state), + ordered_interrupts_(ordered_interrupts), weak_ptr_factory_(this) { DCHECK(delegate_); + DCHECK(ordered_interrupts_); } ScriptExecutor::~ScriptExecutor() {} @@ -53,6 +60,8 @@ ScriptExecutor::Result::~Result() = default; void ScriptExecutor::Run(RunScriptCallback callback) { + (*scripts_state_)[script_path_] = SCRIPT_STATUS_RUNNING; + callback_ = std::move(callback); DCHECK(delegate_->GetService()); @@ -68,19 +77,29 @@ return delegate_->GetWebController()->CreateBatchElementChecker(); } -void ScriptExecutor::WaitForElement(const std::vector<std::string>& selectors, - base::OnceCallback<void(bool)> callback) { - std::unique_ptr<BatchElementChecker> checker = CreateBatchElementChecker(); - checker->AddElementCheck(kVisibilityCheck, selectors, base::DoNothing()); - checker->Run(kWaitForSelectorDeadline, - /* try_done= */ base::DoNothing(), - /* all_done= */ - base::BindOnce( - [](std::unique_ptr<BatchElementChecker> checker_to_delete, - base::OnceCallback<void(bool)> callback) { - std::move(callback).Run(checker_to_delete->all_found()); - }, - std::move(checker), std::move(callback))); +void ScriptExecutor::ShortWaitForElementExist( + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) { + WaitForElement(kShortWaitForElementDeadline, kExistenceCheck, selectors, + std::move(callback)); +} + +void ScriptExecutor::WaitForElementVisible( + base::TimeDelta max_wait_time, + bool allow_interrupt, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) { + if (!allow_interrupt || ordered_interrupts_->empty()) { + // No interrupts to worry about. Just run normal wait. + WaitForElement(max_wait_time, kVisibilityCheck, selectors, + std::move(callback)); + return; + } + wait_with_interrupts_ = std::make_unique<WaitWithInterrupts>( + this, max_wait_time, kVisibilityCheck, selectors, + base::BindOnce(&ScriptExecutor::OnWaitForElementVisible, + base::Unretained(this), std::move(callback))); + wait_with_interrupts_->Run(); } void ScriptExecutor::ShowStatusMessage(const std::string& message) { @@ -171,6 +190,7 @@ void ScriptExecutor::FocusElement(const std::vector<std::string>& selectors, base::OnceCallback<void(bool)> callback) { + last_focused_element_selector_ = selectors; delegate_->GetWebController()->FocusElement(selectors, std::move(callback)); } @@ -306,10 +326,17 @@ should_clean_contextual_ui_on_finish_ = false; } - ScriptExecutor::Result result; + Result result; result.success = success; result.at_end = at_end_; result.touchable_elements = touchable_elements_; + + RunCallbackWithResult(result); +} + +void ScriptExecutor::RunCallbackWithResult(const Result& result) { + (*scripts_state_)[script_path_] = + result.success ? SCRIPT_STATUS_SUCCESS : SCRIPT_STATUS_FAILURE; std::move(callback_).Run(result); } @@ -371,6 +398,195 @@ ProcessNextAction(); } +void ScriptExecutor::WaitForElement(base::TimeDelta max_wait_time, + ElementCheckType check_type, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) { + std::unique_ptr<BatchElementChecker> checker = CreateBatchElementChecker(); + checker->AddElementCheck(check_type, selectors, base::DoNothing()); + checker->Run(max_wait_time, + /* try_done= */ base::DoNothing(), + /* all_done= */ + base::BindOnce( + [](std::unique_ptr<BatchElementChecker> checker_to_delete, + base::OnceCallback<void(bool)> callback) { + std::move(callback).Run(checker_to_delete->all_found()); + }, + std::move(checker), std::move(callback))); +} + +void ScriptExecutor::OnWaitForElementVisible( + base::OnceCallback<void(bool)> element_found_callback, + bool element_found, + const Result* interrupt_result) { + if (interrupt_result) { + RunCallbackWithResult(*interrupt_result); + + // TODO(crbug.com/806868): Let the server know that the original script was + // interrupted and that the interrupting script failed. This implementation + // just drops the current action flow on the floor by deleting + // element_found_callback without calling it. + return; + } + + // Continue the original script. + std::move(element_found_callback).Run(element_found); +} + +ScriptExecutor::WaitWithInterrupts::WaitWithInterrupts( + const ScriptExecutor* main_script, + base::TimeDelta max_wait_time, + ElementCheckType check_type, + const std::vector<std::string>& selectors, + WaitWithInterrupts::Callback callback) + : main_script_(main_script), + max_wait_time_(max_wait_time), + check_type_(check_type), + selectors_(selectors), + callback_(std::move(callback)), + element_found_(false) {} + +ScriptExecutor::WaitWithInterrupts::~WaitWithInterrupts() = default; + +void ScriptExecutor::WaitWithInterrupts::Run() { + // Reset state possibly left over from previous runs. + element_found_ = false; + runnable_interrupts_.clear(); + batch_element_checker_ = + main_script_->delegate_->GetWebController()->CreateBatchElementChecker(); + + batch_element_checker_->AddElementCheck( + check_type_, selectors_, + base::BindOnce(&WaitWithInterrupts::OnElementCheckDone, + base::Unretained(this))); + for (const auto* interrupt : *main_script_->ordered_interrupts_) { + interrupt->precondition->Check( + main_script_->delegate_->GetWebController()->GetUrl(), + batch_element_checker_.get(), main_script_->delegate_->GetParameters(), + *main_script_->scripts_state_, + base::BindOnce(&WaitWithInterrupts::OnPreconditionCheckDone, + base::Unretained(this), base::Unretained(interrupt))); + } + + batch_element_checker_->Run( + max_wait_time_, + base::BindRepeating(&WaitWithInterrupts::OnTryDone, + base::Unretained(this)), + base::BindOnce(&WaitWithInterrupts::OnAllDone, base::Unretained(this))); + + // base::Unretained(this) above is safe because batch_element_checker_ belongs + // to this. +} + +void ScriptExecutor::WaitWithInterrupts::OnPreconditionCheckDone( + const Script* interrupt, + bool precondition_match) { + if (precondition_match) + runnable_interrupts_.insert(interrupt); +} + +void ScriptExecutor::WaitWithInterrupts::OnElementCheckDone(bool found) { + element_found_ = found; + // Wait for all checks to run before reporting that the element was found to + // the caller, so interrupts have a chance to run. +} + +void ScriptExecutor::WaitWithInterrupts::OnTryDone() { + if (!runnable_interrupts_.empty()) { + // We must go through runnable_interrupts_ to make sure priority order is + // respected in case more than one interrupt is ready to run. + for (const auto* interrupt : *main_script_->ordered_interrupts_) { + if (runnable_interrupts_.find(interrupt) != runnable_interrupts_.end()) { + RunInterrupt(interrupt); + return; + } + } + } + + if (element_found_) + RunCallback(true, nullptr); +} + +void ScriptExecutor::WaitWithInterrupts::OnAllDone() { + // This means that we've reached the end of the timeout. Report whether we + // found the element unless an interrupt has just been started by OnTryDone. + if (!interrupt_executor_) + RunCallback(element_found_, nullptr); +} + +void ScriptExecutor::WaitWithInterrupts::RunInterrupt(const Script* interrupt) { + batch_element_checker_.reset(); + SavePreInterruptState(); + interrupt_executor_ = std::make_unique<ScriptExecutor>( + interrupt->handle.path, main_script_->initial_server_payload_, + /* listener= */ nullptr, main_script_->scripts_state_, &no_interrupts_, + main_script_->delegate_); + interrupt_executor_->Run( + base::BindOnce(&ScriptExecutor::WaitWithInterrupts::OnInterruptDone, + base::Unretained(this))); + // base::Unretained(this) is safe because interrupt_executor_ belongs to this +} + +void ScriptExecutor::WaitWithInterrupts::OnInterruptDone( + const ScriptExecutor::Result& result) { + interrupt_executor_.reset(); + if (!result.success || result.at_end != ScriptExecutor::CONTINUE) { + RunCallback(false, &result); + return; + } + RestorePreInterruptUiState(); + // TODO(crbug.com/806868): Forward global state change from the server_payload + // of a successfully run interrupt to the main script. + + // Restart. We use the original wait time since the interruption could have + // triggered any kind of actions, including actions that wait on the user. We + // don't trust a previous element_found_ result, since it could have changed. + Run(); +} + +void ScriptExecutor::WaitWithInterrupts::RunCallback( + bool found, + const ScriptExecutor::Result* result) { + // stop element checking if one is still in progress + batch_element_checker_.reset(); + if (!callback_) + return; + + RestorePreInterruptScroll(found); + std::move(callback_).Run(found, result); +} + +void ScriptExecutor::WaitWithInterrupts::SavePreInterruptState() { + if (saved_pre_interrupt_state_) + return; + + pre_interrupt_status_ = + main_script_->delegate_->GetUiController()->GetStatusMessage(); + saved_pre_interrupt_state_ = true; +} + +void ScriptExecutor::WaitWithInterrupts::RestorePreInterruptUiState() { + if (!saved_pre_interrupt_state_) + return; + + main_script_->delegate_->GetUiController()->ShowStatusMessage( + pre_interrupt_status_); +} + +void ScriptExecutor::WaitWithInterrupts::RestorePreInterruptScroll( + bool element_found) { + if (!saved_pre_interrupt_state_) + return; + + auto* delegate = main_script_->delegate_; + if (element_found) { + delegate->GetWebController()->FocusElement(selectors_, base::DoNothing()); + } else if (!main_script_->last_focused_element_selector_.empty()) { + delegate->GetWebController()->FocusElement( + main_script_->last_focused_element_selector_, base::DoNothing()); + } +} + void ScriptExecutor::OnChosen( base::OnceCallback<void(const std::string&)> callback, const std::string& choice) {
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 62c36ff..dc3c353 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -6,7 +6,9 @@ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SCRIPT_EXECUTOR_H_ #include <deque> +#include <map> #include <memory> +#include <set> #include <string> #include <vector> @@ -33,11 +35,13 @@ virtual void OnServerPayloadChanged(const std::string& server_payload) = 0; }; - // |delegate| and |listener| should outlive this object and should not be - // nullptr. + // |delegate|, |listener|, |script_state| and |ordered_interrupts| should + // outlive this object and should not be nullptr. ScriptExecutor(const std::string& script_path, const std::string& server_payload, ScriptExecutor::Listener* listener, + std::map<std::string, ScriptStatusProto>* scripts_state, + const std::vector<Script*>* ordered_interrupts, ScriptExecutorDelegate* delegate); ~ScriptExecutor() override; @@ -70,13 +74,18 @@ ~Result(); }; - using RunScriptCallback = base::OnceCallback<void(Result)>; + using RunScriptCallback = base::OnceCallback<void(const Result&)>; void Run(RunScriptCallback callback); // Override ActionDelegate: std::unique_ptr<BatchElementChecker> CreateBatchElementChecker() override; - void WaitForElement(const std::vector<std::string>& selectors, - base::OnceCallback<void(bool)> callback) override; + void ShortWaitForElementExist( + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) override; + void WaitForElementVisible(base::TimeDelta max_wait_time, + bool allow_interrupt, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback) override; void ShowStatusMessage(const std::string& message) override; void ClickOrTapElement(const std::vector<std::string>& selectors, base::OnceCallback<void(bool)> callback) override; @@ -136,16 +145,96 @@ void HideOverlay() override; private: + // Helper for WaitForElementVisible that keeps track of the state required to + // run interrupts while waiting for a specific element. + class WaitWithInterrupts { + public: + // Let the caller know about either the result of looking for the element or + // of an abnormal result from an interrupt. + // + // If the given result is non-null, it should be forwarded as the result of + // the main script. + using Callback = + base::OnceCallback<void(bool, const ScriptExecutor::Result*)>; + + // |main_script_| must not be null and outlive this instance. + WaitWithInterrupts(const ScriptExecutor* main_script, + base::TimeDelta max_wait_time, + ElementCheckType check_type, + const std::vector<std::string>& selectors, + WaitWithInterrupts::Callback callback); + ~WaitWithInterrupts(); + + void Run(); + + private: + void OnPreconditionCheckDone(const Script* interrupt, + bool precondition_match); + void OnElementCheckDone(bool found); + void OnTryDone(); + void OnAllDone(); + void RunInterrupt(const Script* interrupt); + void OnInterruptDone(const ScriptExecutor::Result& result); + void RunCallback(bool found, const ScriptExecutor::Result* result); + + // Saves the current state and sets save_pre_interrupt_state_. + void SavePreInterruptState(); + + // Restores the UI states as found by SavePreInterruptState. + void RestorePreInterruptUiState(); + + // if save_pre_interrupt_state_ is set, attempt to scroll the page back to + // the original area. + void RestorePreInterruptScroll(bool element_found); + + const ScriptExecutor* main_script_; + const base::TimeDelta max_wait_time_; + const ElementCheckType check_type_; + const std::vector<std::string> selectors_; + WaitWithInterrupts::Callback callback_; + + std::unique_ptr<BatchElementChecker> batch_element_checker_; + std::set<const Script*> runnable_interrupts_; + bool element_found_; + + // An empty vector of interrupts that can be passed to interrupt_executor_ + // and outlives it. Interrupts must not run interrupts. + const std::vector<Script*> no_interrupts_; + + // The interrupt that's currently running. + std::unique_ptr<ScriptExecutor> interrupt_executor_; + + // If true, pre-interrupt state was saved already. This happens just before + // the first interrupt. + bool saved_pre_interrupt_state_; + + // The status message that was displayed when the interrupt started. + std::string pre_interrupt_status_; + + DISALLOW_COPY_AND_ASSIGN(WaitWithInterrupts); + }; + friend class WaitWithInterrupts; + void OnGetActions(bool result, const std::string& response); void RunCallback(bool success); + void RunCallbackWithResult(const Result& result); void ProcessNextAction(); void ProcessAction(Action* action); void GetNextActions(); void OnProcessedAction(std::unique_ptr<ProcessedActionProto> action); + void WaitForElement(base::TimeDelta max_wait_time, + ElementCheckType check_type, + const std::vector<std::string>& selectors, + base::OnceCallback<void(bool)> callback); + void OnWaitForElementVisible( + base::OnceCallback<void(bool)> element_found_callback, + bool element_found, + const Result* interrupt_result); void OnChosen(base::OnceCallback<void(const std::string&)> callback, const std::string& chosen); std::string script_path_; + const std::string initial_server_payload_; std::string last_server_payload_; ScriptExecutor::Listener* const listener_; ScriptExecutorDelegate* delegate_; @@ -157,7 +246,16 @@ bool should_stop_script_; bool should_clean_contextual_ui_on_finish_; ActionProto::ActionInfoCase previous_action_type_; + std::vector<std::string> last_focused_element_selector_; std::vector<std::vector<std::string>> touchable_elements_; + std::map<std::string, ScriptStatusProto>* scripts_state_; + + // Set of interrupts that might run during wait for dom actions with + // allow_interrupt. Sorted by priority; an interrupt that appears on the + // vector first should run first. + const std::vector<Script*>* ordered_interrupts_; + + std::unique_ptr<WaitWithInterrupts> wait_with_interrupts_; base::WeakPtrFactory<ScriptExecutor> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ScriptExecutor);
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc index f7068969..5c7d134b 100644 --- a/components/autofill_assistant/browser/script_executor_unittest.cc +++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -5,7 +5,9 @@ #include "components/autofill_assistant/browser/script_executor.h" #include <map> +#include <utility> +#include "base/strings/strcat.h" #include "base/test/mock_callback.h" #include "base/test/scoped_task_environment.h" #include "components/autofill_assistant/browser/client_memory.h" @@ -20,33 +22,43 @@ namespace { +using ::testing::_; using ::testing::AllOf; using ::testing::Contains; using ::testing::DoAll; +using ::testing::ElementsAre; using ::testing::Field; using ::testing::Invoke; +using ::testing::IsEmpty; using ::testing::NiceMock; +using ::testing::Not; using ::testing::Pair; using ::testing::ReturnRef; using ::testing::SaveArg; using ::testing::StrEq; using ::testing::StrictMock; -using ::testing::_; + +const char* kScriptPath = "script_path"; class ScriptExecutorTest : public testing::Test, public ScriptExecutorDelegate, public ScriptExecutor::Listener { public: void SetUp() override { - executor_ = std::make_unique<ScriptExecutor>("script path", "", this, this); + executor_ = std::make_unique<ScriptExecutor>( + kScriptPath, + /* server_payload= */ "initial payload", + /* listener= */ this, &scripts_state_, &ordered_interrupts_, + /* delegate= */ this); url_ = GURL("http://example.com/"); // In this test, "tell" actions always succeed and "click" actions always // fail. The following makes a click action fail immediately - ON_CALL(mock_web_controller_, OnElementCheck(_, _, _)) - .WillByDefault(RunOnceCallback<2>(true)); ON_CALL(mock_web_controller_, OnClickOrTapElement(_, _)) .WillByDefault(RunOnceCallback<1>(false)); + + ON_CALL(mock_web_controller_, OnElementCheck(_, _, _)) + .WillByDefault(RunOnceCallback<2>(true)); ON_CALL(mock_web_controller_, OnFocusElement(_, _)) .WillByDefault(RunOnceCallback<1>(true)); ON_CALL(mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_)); @@ -64,6 +76,7 @@ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), overlay_(false) {} + // Implements ScriptExecutorDelegate Service* GetService() override { return &mock_service_; } UiController* GetUiController() override { return &mock_ui_controller_; } @@ -83,16 +96,60 @@ return nullptr; } - void OnServerPayloadChanged(const std::string& server_payload) override {} - content::WebContents* GetWebContents() override { return nullptr; } + // Implements ScriptExecutor::Listener + void OnServerPayloadChanged(const std::string& server_payload) override { + last_server_payload_ = server_payload; + } + std::string Serialize(const google::protobuf::MessageLite& message) { std::string output; message.SerializeToString(&output); return output; } + // Creates a script that contains a wait_for_dom allow_interrupt=true followed + // by a tell. It will succeed if |element| eventually becomes visible. + void SetupInterruptibleScript(const std::string& path, + const std::string& element) { + ActionsResponseProto interruptible; + interruptible.set_server_payload("main script payload"); + auto* wait_action = interruptible.add_actions()->mutable_wait_for_dom(); + wait_action->add_selectors(element); + wait_action->set_allow_interrupt(true); + interruptible.add_actions()->mutable_tell()->set_message(path); + EXPECT_CALL(mock_service_, OnGetActions(StrEq(path), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(interruptible))); + } + + // Creates an interrupt that contains a tell. It will always succeed. + void SetupInterrupt(const std::string& path, const std::string& trigger) { + RegisterInterrupt(path, trigger); + + ActionsResponseProto interrupt_actions; + interrupt_actions.set_server_payload(base::StrCat({"payload for ", path})); + interrupt_actions.add_actions()->mutable_tell()->set_message(path); + EXPECT_CALL(mock_service_, OnGetActions(StrEq(path), _, _, _, _)) + .WillRepeatedly(RunOnceCallback<4>(true, Serialize(interrupt_actions))); + } + + // Registers an interrupt, but do not define actions for it. + void RegisterInterrupt(const std::string& path, const std::string& trigger) { + auto interrupt = std::make_unique<Script>(); + interrupt->handle.path = path; + ScriptPreconditionProto interrupt_preconditions; + interrupt_preconditions.add_elements_exist()->add_selectors(trigger); + auto* run_once = interrupt_preconditions.add_script_status_match(); + run_once->set_script(path); + run_once->set_status(SCRIPT_STATUS_NOT_RUN); + interrupt->precondition = + ScriptPrecondition::FromProto(path, interrupt_preconditions); + + ordered_interrupts_.push_back(interrupt.get()); + interrupts_.emplace_back(std::move(interrupt)); + } + // scoped_task_environment_ must be first to guarantee other field // creation run in that environment. base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -101,6 +158,12 @@ StrictMock<MockService> mock_service_; NiceMock<MockWebController> mock_web_controller_; NiceMock<MockUiController> mock_ui_controller_; + std::map<std::string, ScriptStatusProto> scripts_state_; + + // An owner for the pointers in |ordered_interrupts_| + std::vector<std::unique_ptr<Script>> interrupts_; + std::vector<Script*> ordered_interrupts_; + std::string last_server_payload_; std::unique_ptr<ScriptExecutor> executor_; std::map<std::string, std::string> parameters_; StrictMock<base::MockCallback<ScriptExecutor::RunScriptCallback>> @@ -110,8 +173,8 @@ }; TEST_F(ScriptExecutorTest, GetActionsFails) { - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(false, "")); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(false, "")); EXPECT_CALL(executor_callback_, Run(AllOf(Field(&ScriptExecutor::Result::success, false), Field(&ScriptExecutor::Result::at_end, @@ -123,11 +186,11 @@ parameters_["param1"] = "value1"; parameters_["param2"] = "value2"; EXPECT_CALL(mock_service_, - OnGetActions(StrEq("script path"), + OnGetActions(StrEq(kScriptPath), _, AllOf(Contains(Pair("param1", "value1")), Contains(Pair("param2", "value2"))), - _)) - .WillOnce(RunOnceCallback<2>(true, "")); + _, _)) + .WillOnce(RunOnceCallback<4>(true, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -142,8 +205,8 @@ ->mutable_element_to_click() ->add_selectors("will fail"); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) @@ -164,8 +227,8 @@ initial_actions_response.set_server_payload("payload1"); initial_actions_response.add_actions()->mutable_tell()->set_message("1"); initial_actions_response.add_actions()->mutable_tell()->set_message("2"); - EXPECT_CALL(mock_service_, OnGetActions(StrEq("script path"), _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(initial_actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(initial_actions_response))); ActionsResponseProto next_actions_response; next_actions_response.set_server_payload("payload2"); @@ -191,8 +254,8 @@ actions_response.set_server_payload("payload"); actions_response.add_actions(); // action definition missing - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) @@ -211,8 +274,8 @@ actions_response.set_server_payload("payload"); actions_response.add_actions()->mutable_stop(); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(true, "")); @@ -228,8 +291,8 @@ actions_response.set_server_payload("payload"); actions_response.add_actions()->mutable_reset(); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(true, "")); @@ -252,8 +315,8 @@ initial_actions_response.add_actions()->mutable_tell()->set_message( "never run"); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(initial_actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(initial_actions_response))); ActionsResponseProto next_actions_response; next_actions_response.set_server_payload("payload2"); @@ -289,8 +352,8 @@ action->mutable_tell()->set_message("delayed"); action->set_action_delay_ms(1000); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) @@ -319,8 +382,8 @@ *actions_response.add_actions() = click_with_clean_contextual_ui; - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(true, "")); EXPECT_CALL(executor_callback_, @@ -338,8 +401,8 @@ *actions_response.add_actions() = click_with_clean_contextual_ui; actions_response.add_actions()->mutable_tell()->set_message("Wait no!"); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(true, "")); EXPECT_CALL(executor_callback_, @@ -354,8 +417,8 @@ ActionsResponseProto actions_response; actions_response.set_server_payload("payload"); actions_response.add_actions()->mutable_tell()->set_message("Hello"); - EXPECT_CALL(mock_service_, OnGetActions(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response))); + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) .WillOnce(RunOnceCallback<2>(false, "")); EXPECT_CALL(executor_callback_, @@ -366,5 +429,282 @@ executor_->Run(executor_callback_.Get()); } +TEST_F(ScriptExecutorTest, UpdateScriptStateWhileRunning) { + // OnGetNextActions never calls the callback, so Run() returns immediately + // without doing anything. + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)); + + EXPECT_THAT(scripts_state_, IsEmpty()); + executor_->Run(executor_callback_.Get()); + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_RUNNING))); +} + +TEST_F(ScriptExecutorTest, UpdateScriptStateOnError) { + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillOnce(RunOnceCallback<4>(false, "")); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, false))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_FAILURE))); +} + +TEST_F(ScriptExecutorTest, UpdateScriptStateOnSuccess) { + ActionsResponseProto initial_actions_response; + initial_actions_response.set_server_payload("payload1"); + initial_actions_response.add_actions()->mutable_tell()->set_message("ok"); + EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(initial_actions_response))); + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); +} + +TEST_F(ScriptExecutorTest, ForwardLastPayloadOnSuccess) { + ActionsResponseProto actions_response; + actions_response.set_server_payload("actions payload"); + actions_response.add_actions()->mutable_tell()->set_message("ok"); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, "initial payload", _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); + + ActionsResponseProto next_actions_response; + next_actions_response.set_server_payload("last payload"); + EXPECT_CALL(mock_service_, OnGetNextActions("actions payload", _, _)) + .WillOnce(RunOnceCallback<2>(true, Serialize(next_actions_response))); + + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + EXPECT_EQ("last payload", last_server_payload_); +} + +TEST_F(ScriptExecutorTest, ForwardLastPayloadOnError) { + ActionsResponseProto actions_response; + actions_response.set_server_payload("actions payload"); + actions_response.add_actions()->mutable_tell()->set_message("ok"); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, "initial payload", _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(actions_response))); + + EXPECT_CALL(mock_service_, OnGetNextActions("actions payload", _, _)) + .WillOnce(RunOnceCallback<2>(false, "")); + + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + EXPECT_EQ("actions payload", last_server_payload_); +} + +TEST_F(ScriptExecutorTest, RunInterrupt) { + // All elements exist, so first the interrupt should be run, then the element + // should be reported as found. + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt", "interrupt_trigger"); + + // Both scripts ends after the first set of actions. Capture the results. + std::vector<ProcessedActionProto> processed_actions1_capture; + std::vector<ProcessedActionProto> processed_actions2_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(DoAll(SaveArg<1>(&processed_actions1_capture), + RunOnceCallback<2>(true, ""))) + .WillOnce(DoAll(SaveArg<1>(&processed_actions2_capture), + RunOnceCallback<2>(true, ""))); + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, + Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS))); + + // The first script to call OnGetNextActions is the interrupt, which starts + // with a tell. + ASSERT_THAT(processed_actions1_capture, Not(IsEmpty())); + EXPECT_EQ(ActionProto::ActionInfoCase::kTell, + processed_actions1_capture[0].action().action_info_case()); + EXPECT_EQ(ACTION_APPLIED, processed_actions1_capture[0].status()); + + // The second script to call OnGetNextActions is the main script, with starts + // with a wait_for_dom + ASSERT_THAT(processed_actions2_capture, Not(IsEmpty())); + EXPECT_EQ(ActionProto::ActionInfoCase::kWaitForDom, + processed_actions2_capture[0].action().action_info_case()); + EXPECT_EQ(ACTION_APPLIED, processed_actions2_capture[0].status()); +} + +TEST_F(ScriptExecutorTest, RunMultipleInterruptInOrder) { + // All elements exist. The two interrupts should run, in order, then the + // element should be reported as found. + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt1", "interrupt_trigger1"); + SetupInterrupt("interrupt2", "interrupt_trigger2"); + + { + testing::InSequence seq; + EXPECT_CALL(mock_service_, OnGetNextActions("payload for interrupt1", _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(mock_service_, OnGetNextActions("payload for interrupt2", _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + EXPECT_CALL(mock_service_, OnGetNextActions("main script payload", _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + } + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, + Contains(Pair("interrupt1", SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, + Contains(Pair("interrupt2", SCRIPT_STATUS_SUCCESS))); +} + +TEST_F(ScriptExecutorTest, ForwardMainScriptPayloadWhenInterruptRuns) { + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt", "interrupt_trigger"); + + ActionsResponseProto next_interrupt_actions_response; + next_interrupt_actions_response.set_server_payload( + "last payload from interrupt"); + EXPECT_CALL(mock_service_, OnGetNextActions("payload for interrupt", _, _)) + .WillOnce( + RunOnceCallback<2>(true, Serialize(next_interrupt_actions_response))); + + ActionsResponseProto next_main_actions_response; + next_main_actions_response.set_server_payload("last payload from main"); + EXPECT_CALL(mock_service_, OnGetNextActions("main script payload", _, _)) + .WillOnce( + RunOnceCallback<2>(true, Serialize(next_main_actions_response))); + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_EQ("last payload from main", last_server_payload_); +} + +TEST_F(ScriptExecutorTest, ForwardMainScriptPayloadWhenInterruptFails) { + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt", "interrupt_trigger"); + + ActionsResponseProto next_interrupt_actions_response; + next_interrupt_actions_response.set_server_payload( + "last payload from interrupt"); + EXPECT_CALL(mock_service_, OnGetNextActions("payload for interrupt", _, _)) + .WillOnce(RunOnceCallback<2>(false, "")); + + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + EXPECT_EQ("main script payload", last_server_payload_); +} + +TEST_F(ScriptExecutorTest, DoNotRunInterruptIfPreconditionsDontMatch) { + // interrupt_trigger does not exist, but element does, so wait_for_dom will + // succeed without calling the interrupt. + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt", "interrupt_trigger"); + + EXPECT_CALL(mock_web_controller_, + OnElementCheck(_, ElementsAre("element"), _)) + .WillRepeatedly(RunOnceCallback<2>(true)); + EXPECT_CALL(mock_web_controller_, + OnElementCheck(_, ElementsAre("interrupt_trigger"), _)) + .WillRepeatedly(RunOnceCallback<2>(false)); + + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillRepeatedly(RunOnceCallback<2>(true, "")); + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, Not(Contains(Pair(StrEq("interrupt"), _)))); +} + +TEST_F(ScriptExecutorTest, DoNotRunInterruptIfNotInterruptible) { + // The main script has a wait_for_dom, but it is not interruptible. + ActionsResponseProto interruptible; + auto* wait_action = interruptible.add_actions()->mutable_wait_for_dom(); + wait_action->add_selectors("element"); + // allow_interrupt is not set + EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _)) + .WillOnce(RunOnceCallback<4>(true, Serialize(interruptible))); + + // The interrupt would trigger, since interrupt_trigger exits, but it's not + // given an opportunity to. + SetupInterrupt("interrupt", "interrupt_trigger"); + + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillRepeatedly(RunOnceCallback<2>(true, "")); + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, true))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, Not(Contains(Pair(StrEq("interrupt"), _)))); +} + +TEST_F(ScriptExecutorTest, InterruptFailsMainScript) { + // The interrupt is run and fails. Failure should cascade. + SetupInterruptibleScript(kScriptPath, "element"); + SetupInterrupt("interrupt", "interrupt_trigger"); + + EXPECT_CALL(mock_service_, OnGetNextActions("payload for interrupt", _, _)) + .WillOnce(RunOnceCallback<2>(false, "")); + + EXPECT_CALL(executor_callback_, + Run(Field(&ScriptExecutor::Result::success, false))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_FAILURE))); + EXPECT_THAT(scripts_state_, + Contains(Pair("interrupt", SCRIPT_STATUS_FAILURE))); +} + +TEST_F(ScriptExecutorTest, InterruptReturnsShutdown) { + // The interrupt succeeds, but executes the stop action. This should stop the + // execution of the main script and make it return result.at_end=SHUTDOWN + SetupInterruptibleScript(kScriptPath, "element"); + + RegisterInterrupt("interrupt", "interrupt_trigger"); + ActionsResponseProto interrupt_actions; + interrupt_actions.add_actions()->mutable_stop(); + + EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _)) + .WillRepeatedly(RunOnceCallback<4>(true, Serialize(interrupt_actions))); + + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _)) + .WillOnce(RunOnceCallback<2>(true, "")); + + EXPECT_CALL(executor_callback_, + Run(AllOf(Field(&ScriptExecutor::Result::success, true), + Field(&ScriptExecutor::Result::at_end, + ScriptExecutor::SHUTDOWN)))); + executor_->Run(executor_callback_.Get()); + + EXPECT_THAT(scripts_state_, + Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS))); + EXPECT_THAT(scripts_state_, + Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS))); +} + } // namespace } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_tracker.cc b/components/autofill_assistant/browser/script_tracker.cc index d7570bf..b29ac77e 100644 --- a/components/autofill_assistant/browser/script_tracker.cc +++ b/components/autofill_assistant/browser/script_tracker.cc
@@ -14,6 +14,24 @@ namespace autofill_assistant { +namespace { + +// Sort scripts by priority. +void SortScripts(std::vector<Script*>* scripts) { + std::sort(scripts->begin(), scripts->end(), + [](const Script* a, const Script* b) { + // Runnable scripts with lowest priority value are displayed + // first, Interrupts with lowest priority values are run first. + // Order of scripts with the same priority is arbitrary. Fallback + // to ordering by name and path, arbitrarily, for the behavior to + // be consistent across runs. + return std::tie(a->priority, a->handle.name, a->handle.path) < + std::tie(b->priority, b->handle.name, a->handle.path); + }); +} + +} // namespace + ScriptTracker::ScriptTracker(ScriptExecutorDelegate* delegate, ScriptTracker::Listener* listener) : delegate_(delegate), @@ -27,10 +45,26 @@ ScriptTracker::~ScriptTracker() = default; void ScriptTracker::SetScripts(std::vector<std::unique_ptr<Script>> scripts) { - ClearAvailableScripts(); + // The set of interrupts must not change while a script is running, as they're + // passed to ScriptExecutor. + if (running()) + return; + + TerminatePendingChecks(); + + available_scripts_.clear(); for (auto& script : scripts) { available_scripts_[script.get()] = std::move(script); } + + interrupts_.clear(); + for (auto& entry : available_scripts_) { + Script* script = entry.first; + if (script->handle.interrupt) { + interrupts_.push_back(script); + } + } + SortScripts(&interrupts_); } void ScriptTracker::CheckScripts(const base::TimeDelta& max_duration) { @@ -43,9 +77,12 @@ delegate_->GetWebController()->CreateBatchElementChecker(); for (const auto& entry : available_scripts_) { Script* script = entry.first; + if (script->handle.name.empty() && !script->handle.autostart) + continue; + script->precondition->Check( delegate_->GetWebController()->GetUrl(), batch_element_checker_.get(), - delegate_->GetParameters(), executed_scripts_, + delegate_->GetParameters(), scripts_state_, base::BindOnce(&ScriptTracker::OnPreconditionCheck, weak_ptr_factory_.GetWeakPtr(), script)); } @@ -80,9 +117,9 @@ return; } - executed_scripts_[script_path] = SCRIPT_STATUS_RUNNING; executor_ = std::make_unique<ScriptExecutor>( - script_path, last_server_payload_, this, delegate_); + script_path, last_server_payload_, /* listener= */ this, &scripts_state_, + &interrupts_, delegate_); ScriptExecutor::RunScriptCallback run_script_callback = base::BindOnce( &ScriptTracker::OnScriptRun, weak_ptr_factory_.GetWeakPtr(), script_path, std::move(callback)); @@ -100,13 +137,13 @@ base::Base64Encode(last_server_payload_js, &last_server_payload_js); dict.SetKey("last-payload", base::Value(last_server_payload_js)); - std::vector<base::Value> executed_scripts_js; - for (const auto& entry : executed_scripts_) { + std::vector<base::Value> scripts_state_js; + for (const auto& entry : scripts_state_) { base::Value script_js = base::Value(base::Value::Type::DICTIONARY); script_js.SetKey(entry.first, base::Value(entry.second)); - executed_scripts_js.push_back(std::move(script_js)); + scripts_state_js.push_back(std::move(script_js)); } - dict.SetKey("executed-scripts", base::Value(executed_scripts_js)); + dict.SetKey("executed-scripts", base::Value(scripts_state_js)); std::vector<base::Value> available_scripts_js; for (const auto& entry : available_scripts_) @@ -131,10 +168,8 @@ void ScriptTracker::OnScriptRun( const std::string& script_path, ScriptExecutor::RunScriptCallback original_callback, - ScriptExecutor::Result result) { + const ScriptExecutor::Result& result) { executor_.reset(); - executed_scripts_[script_path] = - result.success ? SCRIPT_STATUS_SUCCESS : SCRIPT_STATUS_FAILURE; std::move(original_callback).Run(result); } @@ -143,15 +178,7 @@ return; runnable_scripts_.clear(); - std::sort(pending_runnable_scripts_.begin(), pending_runnable_scripts_.end(), - [](const Script* a, const Script* b) { - // Runnable scripts with lowest priority value are displayed - // first. The display order of scripts with the same priority is - // arbitrary. Fallback to ordering by name, arbitrarily, for the - // behavior to be consistent. - return std::tie(a->priority, a->handle.name) < - std::tie(b->priority, b->handle.name); - }); + SortScripts(&pending_runnable_scripts_); for (Script* script : pending_runnable_scripts_) { runnable_scripts_.push_back(script->handle); } @@ -194,13 +221,6 @@ pending_runnable_scripts_.push_back(script); } -void ScriptTracker::ClearAvailableScripts() { - available_scripts_.clear(); - // Clearing available_scripts_ has cancelled any pending precondition checks, - // ending them. - TerminatePendingChecks(); -} - void ScriptTracker::OnServerPayloadChanged(const std::string& server_payload) { last_server_payload_ = server_payload; }
diff --git a/components/autofill_assistant/browser/script_tracker.h b/components/autofill_assistant/browser/script_tracker.h index 5280b0d..d2bab288 100644 --- a/components/autofill_assistant/browser/script_tracker.h +++ b/components/autofill_assistant/browser/script_tracker.h
@@ -21,6 +21,7 @@ namespace autofill_assistant { class ScriptExecutorDelegate; +class ScriptTrackerTest; // The script tracker keeps track of which scripts are available, which are // running, which have run, which are runnable whose preconditions are met. @@ -93,9 +94,11 @@ private: typedef std::map<Script*, std::unique_ptr<Script>> AvailableScriptMap; + friend class ScriptTrackerTest; + void OnScriptRun(const std::string& script_path, ScriptExecutor::RunScriptCallback original_callback, - ScriptExecutor::Result result); + const ScriptExecutor::Result& result); void UpdateRunnableScriptsIfNecessary(); void OnCheckDone(); @@ -110,7 +113,6 @@ // Returns true if |runnable_| should be updated. bool RunnablesHaveChanged(); void OnPreconditionCheck(Script* script, bool met_preconditions); - void ClearAvailableScripts(); ScriptExecutorDelegate* const delegate_; ScriptTracker::Listener* const listener_; @@ -134,8 +136,12 @@ // any pending check. AvailableScriptMap available_scripts_; + // A subset of available_scripts that are interrupts. + std::vector<Script*> interrupts_; + // List of scripts that have been executed and their corresponding statuses. - std::map<std::string, ScriptStatusProto> executed_scripts_; + std::map<std::string, ScriptStatusProto> scripts_state_; + std::unique_ptr<BatchElementChecker> batch_element_checker_; // Scripts found to be runnable so far, in the current check, represented by
diff --git a/components/autofill_assistant/browser/script_tracker_unittest.cc b/components/autofill_assistant/browser/script_tracker_unittest.cc index a6f0b52..a0eccb8 100644 --- a/components/autofill_assistant/browser/script_tracker_unittest.cc +++ b/components/autofill_assistant/browser/script_tracker_unittest.cc
@@ -41,8 +41,8 @@ ON_CALL(mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_)); // Scripts run, but have no actions. - ON_CALL(mock_service_, OnGetActions(_, _, _)) - .WillByDefault(RunOnceCallback<2>(true, "")); + ON_CALL(mock_service_, OnGetActions(_, _, _, _, _)) + .WillByDefault(RunOnceCallback<4>(true, "")); } protected: @@ -168,6 +168,40 @@ EXPECT_EQ("runnable path", runnable_scripts()[0].path); } +TEST_F(ScriptTrackerTest, DoNotCheckInterruptWithNoName) { + SupportsScriptResponseProto scripts; + + // The interrupt's preconditions would all be met, but it won't be reported + // since it doesn't have a name. + auto* no_name = AddScript(&scripts, "", "path1", "exists"); + no_name->mutable_presentation()->set_interrupt(true); + + // The interrupt's preconditions are met and it will be reported as a normal + // script. + auto* with_name = AddScript(&scripts, "with name", "path2", "exists"); + with_name->mutable_presentation()->set_interrupt(true); + + SetAndCheckScripts(scripts); + + EXPECT_EQ(1, runnable_scripts_changed_); + ASSERT_THAT(runnable_scripts(), SizeIs(1)); + EXPECT_EQ("with name", runnable_scripts()[0].name); +} + +TEST_F(ScriptTrackerTest, ReportInterruptToAutostart) { + SupportsScriptResponseProto scripts; + + // The interrupt's preconditions are met and it will be reported as runnable + // for autostart. + auto* autostart = AddScript(&scripts, "", "path2", "exists"); + autostart->mutable_presentation()->set_interrupt(true); + autostart->mutable_presentation()->set_autostart(true); + SetAndCheckScripts(scripts); + + EXPECT_EQ(1, runnable_scripts_changed_); + ASSERT_THAT(runnable_scripts(), SizeIs(1)); +} + TEST_F(ScriptTrackerTest, OrderScriptsByPriority) { SupportsScriptResponseProto scripts;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index f5ad6d6..c321953 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -84,6 +84,10 @@ // When set to true this script can be run in 'autostart mode'. Script won't // be shown. optional bool autostart = 8; + + // When set to true this script will be run from WaitForDom actions with + // allow_interrupt=true. + optional bool interrupt = 9; } optional PresentationProto presentation = 2; } @@ -391,6 +395,10 @@ // The element to wait for. repeated string selectors = 2; + + // If true, run scripts flagged with 'interrupt=true' as soon as their + // preconditions match. + optional bool allow_interrupt = 3; } // Volatile upload of a portion of the dom for backend analysis, does not store @@ -532,7 +540,12 @@ // Set the value of an form element. message SetFormFieldValueProto { message KeyPress { - oneof keypress { string text = 1; } + oneof keypress { + string text = 1; + // A single key with this exact keycode (KeyboardEvent.keyCode) e.g. 8 for + // Backspace. + int32 keycode = 2; + } } // A reference to the form element whose value should be set.
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h index c65745b0..1a9c092 100644 --- a/components/autofill_assistant/browser/ui_controller.h +++ b/components/autofill_assistant/browser/ui_controller.h
@@ -30,6 +30,10 @@ // Show status message on the bottom bar. virtual void ShowStatusMessage(const std::string& message) = 0; + // Returns the current status message. The purpose of this call is to allow + // restoring a previous status message. + virtual std::string GetStatusMessage(); + // Show the overlay. virtual void ShowOverlay() = 0;
diff --git a/components/browser_sync/test_http_bridge_factory.cc b/components/browser_sync/test_http_bridge_factory.cc index 73f65eb..f327207 100644 --- a/components/browser_sync/test_http_bridge_factory.cc +++ b/components/browser_sync/test_http_bridge_factory.cc
@@ -6,7 +6,8 @@ namespace browser_sync { -bool TestHttpBridge::MakeSynchronousPost(int* error_code, int* response_code) { +bool TestHttpBridge::MakeSynchronousPost(int* net_error_code, + int* http_response_code) { return false; }
diff --git a/components/browser_sync/test_http_bridge_factory.h b/components/browser_sync/test_http_bridge_factory.h index e786f6a..9ebd735 100644 --- a/components/browser_sync/test_http_bridge_factory.h +++ b/components/browser_sync/test_http_bridge_factory.h
@@ -24,7 +24,8 @@ int content_length, const char* content) override {} - bool MakeSynchronousPost(int* error_code, int* response_code) override; + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override; int GetResponseContentLength() const override;
diff --git a/components/cdm/common/cdm_message_generator.cc b/components/cdm/common/cdm_message_generator.cc index 2aabce7..d87ee8c 100644 --- a/components/cdm/common/cdm_message_generator.cc +++ b/components/cdm/common/cdm_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/cdm/common/cdm_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/cdm/common/cdm_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/guest_view/common/guest_view_message_generator.cc b/components/guest_view/common/guest_view_message_generator.cc index 6a0bca1..363c62a 100644 --- a/components/guest_view/common/guest_view_message_generator.cc +++ b/components/guest_view/common/guest_view_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/guest_view/common/guest_view_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/guest_view/common/guest_view_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.cc b/components/history/core/browser/sync/typed_url_sync_bridge.cc index de78373..8902ec8 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge.cc
@@ -165,7 +165,8 @@ GetStorageKeyInternal(entity_change.data().specifics.typed_url().url()); if (storage_key.empty()) { // ignore entity change - change_processor()->UntrackEntity(entity_change.data()); + change_processor()->UntrackEntityForClientTagHash( + entity_change.data().client_tag_hash); } else { change_processor()->UpdateStorageKey(entity_change.data(), storage_key, metadata_change_list.get()); @@ -245,7 +246,8 @@ entity_change.data().specifics.typed_url().url()); if (storage_key.empty()) { // ignore entity change - change_processor()->UntrackEntity(entity_change.data()); + change_processor()->UntrackEntityForClientTagHash( + entity_change.data().client_tag_hash); } else { change_processor()->UpdateStorageKey(entity_change.data(), storage_key, metadata_change_list.get());
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc index 360f58a..148aacc 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
@@ -1188,7 +1188,7 @@ ASSERT_EQ(0U, processor().put_multimap().size()); ASSERT_EQ(1U, processor().update_multimap().size()); - ASSERT_EQ(0U, processor().untrack_set().size()); + ASSERT_EQ(0U, processor().untrack_for_client_tag_hash_set().size()); // Verify processor receive correct upate storage key. const auto& it = processor().update_multimap().begin(); @@ -1222,7 +1222,7 @@ ASSERT_EQ(0U, processor().put_multimap().size()); ASSERT_EQ(0U, processor().update_multimap().size()); - ASSERT_EQ(1U, processor().untrack_set().size()); + ASSERT_EQ(1U, processor().untrack_for_client_tag_hash_set().size()); URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL)); ASSERT_EQ(0, url_id);
diff --git a/components/metrics/call_stack_profile_builder.cc b/components/metrics/call_stack_profile_builder.cc index 0d691aa..1d503d9 100644 --- a/components/metrics/call_stack_profile_builder.cc +++ b/components/metrics/call_stack_profile_builder.cc
@@ -65,7 +65,7 @@ OnSampleCompleted(std::move(frames), 1); } -// TODO(chengx): record |count| as per-Stacksample metadata in the new proto +// TODO(wittman): record |count| as per-Stacksample metadata in the new proto // format. void CallStackProfileBuilder::OnSampleCompleted( std::vector<base::StackSamplingProfiler::Frame> frames,
diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc index 27905b6bb..519556e 100644 --- a/components/metrics/call_stack_profile_metrics_provider.cc +++ b/components/metrics/call_stack_profile_metrics_provider.cc
@@ -23,7 +23,8 @@ // due to profile deserialization when profile uploads are delayed (e.g. due to // being offline). Capping at this threshold loses approximately 0.5% of // profiles on canary and dev. -// TODO(chengx): Remove this threshold after crbug.com/903972 is fixed. +// +// TODO(wittman): Remove this threshold after crbug.com/903972 is fixed. const size_t kMaxPendingProfiles = 1250; // PendingProfiles ------------------------------------------------------------
diff --git a/components/module_installer/android/BUILD.gn b/components/module_installer/android/BUILD.gn index 1a3f7a0..84040c7 100644 --- a/components/module_installer/android/BUILD.gn +++ b/components/module_installer/android/BUILD.gn
@@ -4,14 +4,38 @@ import("//build/config/android/rules.gni") +# Contains code necessary to compile the rest of Chrome. Doesn't contain actual +# implementations. To get implementations either depend on +# |module_installer_impl_java| or |module_installer_stub_java| depending on your +# build. android_library("module_installer_java") { java_files = [ - "java/src/org/chromium/components/module_installer/ModuleInstaller.java", - "java/src/org/chromium/components/module_installer/ModuleInstallerBackend.java", - "java/src/org/chromium/components/module_installer/FakeModuleInstallerBackend.java", - "java/src/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java", + "java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java", + "java/src-common/org/chromium/components/module_installer/OnModuleInstallFinishedListener.java", + ] + jar_excluded_patterns = [ "*/ModuleInstaller.class" ] +} + +# Contains stub implementation to be used for builds not supporting modules +# (e.g. APKs). +android_library("module_installer_stub_java") { + java_files = [ "java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java" ] + deps = [ + ":module_installer_java", + ] +} + +# Contains real implementation to be used for builds supporting modules (e.g. +# bundles). +android_library("module_installer_impl_java") { + java_files = [ + "java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java", + "java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java", + "java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java", + "java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java", ] deps = [ + ":module_installer_java", "//base:base_java", "//third_party/google_android_play_core:com_google_android_play_core_java", ]
diff --git a/components/module_installer/android/java/src-common/org/chromium/components/module_installer/OnModuleInstallFinishedListener.java b/components/module_installer/android/java/src-common/org/chromium/components/module_installer/OnModuleInstallFinishedListener.java new file mode 100644 index 0000000..e6d8d0e --- /dev/null +++ b/components/module_installer/android/java/src-common/org/chromium/components/module_installer/OnModuleInstallFinishedListener.java
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.module_installer; + +/** Listener for when a module install has finished. */ +public interface OnModuleInstallFinishedListener { + /** + * Called when the install has finished. + * + * @param success True if the module was installed successfully. + */ + void onFinished(boolean success); +}
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/FakeModuleInstallerBackend.java b/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java similarity index 100% rename from components/module_installer/android/java/src/org/chromium/components/module_installer/FakeModuleInstallerBackend.java rename to components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/ModuleInstaller.java b/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java similarity index 76% rename from components/module_installer/android/java/src/org/chromium/components/module_installer/ModuleInstaller.java rename to components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java index 93d0900..1e9978db 100644 --- a/components/module_installer/android/java/src/org/chromium/components/module_installer/ModuleInstaller.java +++ b/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java
@@ -19,21 +19,11 @@ /** Installs dynamic feature modules (DFMs). */ public class ModuleInstaller { /** Command line switch for activating the fake backend. */ - public static final String FAKE_FEATURE_MODULE_INSTALL = "fake-feature-module-install"; - private static final Map<String, List<OnFinishedListener>> sModuleNameListenerMap = + private static final String FAKE_FEATURE_MODULE_INSTALL = "fake-feature-module-install"; + private static final Map<String, List<OnModuleInstallFinishedListener>> sModuleNameListenerMap = new HashMap<>(); private static ModuleInstallerBackend sBackend; - /** Listener for when a module install has finished. */ - public interface OnFinishedListener { - /** - * Called when the install has finished. - * - * @param success True if the module was installed successfully. - */ - void onFinished(boolean success); - } - /** Needs to be called before trying to access a module. */ public static void init() { // SplitCompat.install may copy modules into Chrome's internal folder or clean them up. @@ -48,13 +38,15 @@ * @param moduleName Name of the module as defined in GN. * @param onFinishedListener Listener to be called once installation is finished. */ - public static void install(String moduleName, OnFinishedListener onFinishedListener) { + public static void install( + String moduleName, OnModuleInstallFinishedListener onFinishedListener) { ThreadUtils.assertOnUiThread(); if (!sModuleNameListenerMap.containsKey(moduleName)) { sModuleNameListenerMap.put(moduleName, new LinkedList<>()); } - List<OnFinishedListener> onFinishedListeners = sModuleNameListenerMap.get(moduleName); + List<OnModuleInstallFinishedListener> onFinishedListeners = + sModuleNameListenerMap.get(moduleName); onFinishedListeners.add(onFinishedListener); if (onFinishedListeners.size() > 1) { // Request is already running. @@ -67,10 +59,11 @@ ThreadUtils.assertOnUiThread(); for (String moduleName : moduleNames) { - List<OnFinishedListener> onFinishedListeners = sModuleNameListenerMap.get(moduleName); + List<OnModuleInstallFinishedListener> onFinishedListeners = + sModuleNameListenerMap.get(moduleName); if (onFinishedListeners == null) continue; - for (OnFinishedListener listener : onFinishedListeners) { + for (OnModuleInstallFinishedListener listener : onFinishedListeners) { listener.onFinished(success); } sModuleNameListenerMap.remove(moduleName);
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/ModuleInstallerBackend.java b/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java similarity index 100% rename from components/module_installer/android/java/src/org/chromium/components/module_installer/ModuleInstallerBackend.java rename to components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstallerBackend.java
diff --git a/components/module_installer/android/java/src/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java b/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java similarity index 100% rename from components/module_installer/android/java/src/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java rename to components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java
diff --git a/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java b/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java new file mode 100644 index 0000000..05fc9ebe --- /dev/null +++ b/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java
@@ -0,0 +1,17 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.module_installer; + +/** Dummy fallback of ModuleInstaller for APK builds. */ +public class ModuleInstaller { + public static void init() {} + /** Should never be called for APK builds. */ + public static void install( + String moduleName, OnModuleInstallFinishedListener onFinishedListener) { + throw new UnsupportedOperationException("Cannot install module if APK"); + } + + private ModuleInstaller() {} +}
diff --git a/components/nacl/common/nacl_host_messages.cc b/components/nacl/common/nacl_host_messages.cc index 1b47272..cefe525 100644 --- a/components/nacl/common/nacl_host_messages.cc +++ b/components/nacl/common/nacl_host_messages.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/nacl/common/nacl_host_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/nacl/common/nacl_host_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/nacl/common/nacl_messages.cc b/components/nacl/common/nacl_messages.cc index 21407368..0161bf51 100644 --- a/components/nacl/common/nacl_messages.cc +++ b/components/nacl/common/nacl_messages.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/nacl/common/nacl_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/nacl/common/nacl_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/nacl/common/nacl_types_param_traits.cc b/components/nacl/common/nacl_types_param_traits.cc index a295163..b6894ee 100644 --- a/components/nacl/common/nacl_types_param_traits.cc +++ b/components/nacl/common/nacl_types_param_traits.cc
@@ -11,11 +11,6 @@ #undef COMPONENTS_NACL_COMMON_NACL_TYPES_PARAM_TRAITS_H_ #include "components/nacl/common/nacl_types_param_traits.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef COMPONENTS_NACL_COMMON_NACL_TYPES_PARAM_TRAITS_H_ -#include "components/nacl/common/nacl_types_param_traits.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/network_hints/common/network_hints_message_generator.cc b/components/network_hints/common/network_hints_message_generator.cc index f315e98..8dee360 100644 --- a/components/network_hints/common/network_hints_message_generator.cc +++ b/components/network_hints/common/network_hints_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/network_hints/common/network_hints_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/network_hints/common/network_hints_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc index 03352db..d98d61c 100644 --- a/components/network_session_configurator/browser/network_session_configurator.cc +++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -30,6 +30,10 @@ #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/spdy/core/spdy_protocol.h" +#if defined(OS_MACOSX) && !defined(OS_IOS) +#include "base/mac/mac_util.h" +#endif + namespace { // Map from name to value for all parameters associate with a field trial. @@ -652,12 +656,25 @@ if (opt_value.empty() || base::LowerCaseEqualsASCII(opt_value, "on")) return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE; } + const std::string experiment_name = base::FieldTrialList::FindFullName("SimpleCacheTrial"); if (base::StartsWith(experiment_name, "Disable", base::CompareCase::INSENSITIVE_ASCII)) { return net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE; } + + // Blockfile breaks on OSX 10.14 (see https://crbug.com/899874); so use + // SimpleCache even when we don't enable it via experiment, as long as we + // don't force it off (not used at this time). This unfortunately + // muddles the experiment data, but as this was written to be considered for + // backport, having it behave differently than in stable would be a bigger + // problem. +#if defined(OS_MACOSX) && !defined(OS_IOS) + if (base::mac::IsAtLeastOS10_14()) + return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE; +#endif // defined(OS_MACOSX) && !defined(OS_IOS) + if (base::StartsWith(experiment_name, "ExperimentYes", base::CompareCase::INSENSITIVE_ASCII)) { return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE;
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc index 73566f3..6857ad1 100644 --- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -25,6 +25,10 @@ #include "net/url_request/url_request_context_builder.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_MACOSX) && !defined(OS_IOS) +#include "base/mac/mac_util.h" +#endif + namespace network_session_configurator { class NetworkSessionConfiguratorTest : public testing::Test { @@ -739,6 +743,12 @@ #if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE, ChooseCacheType(command_line)); +#elif defined(OS_MACOSX) && !defined(OS_IOS) + EXPECT_EQ( + base::mac::IsAtLeastOS10_14() + ? net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE + : net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE, + ChooseCacheType(command_line)); #else EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE, ChooseCacheType(command_line));
diff --git a/components/os_crypt/BUILD.gn b/components/os_crypt/BUILD.gn index 9356926e..a881af5f 100644 --- a/components/os_crypt/BUILD.gn +++ b/components/os_crypt/BUILD.gn
@@ -39,8 +39,6 @@ "keychain_password_mac.h", "keychain_password_mac.mm", "os_crypt.h", - "os_crypt_features_mac.cc", - "os_crypt_features_mac.h", "os_crypt_mac.mm", "os_crypt_pref_names_mac.cc", "os_crypt_pref_names_mac.h",
diff --git a/components/os_crypt/encryption_key_creation_util.h b/components/os_crypt/encryption_key_creation_util.h index ef5ce3f475..53e38fb48 100644 --- a/components/os_crypt/encryption_key_creation_util.h +++ b/components/os_crypt/encryption_key_creation_util.h
@@ -9,61 +9,47 @@ namespace os_crypt { -// An interface for the utility that prevents overwriting the encryption key on +// An interface for the utility that logs statistics on the encryption key on // Mac. -// This class is used on Mac and iOS, but does nothing on iOS as the feature -// for preventing key overwrites is available only on Mac. The object for +// This class is used on Mac and iOS, but does nothing on iOS. The object for // the Mac class has to be created on the main thread. class EncryptionKeyCreationUtil { public: - // The action that is taken by GetPassword method. + // The action that is taken by KeychainPassword::GetPassword method. // This enum is used for reporting metrics. enum class GetKeyAction { // Key was found in the Keychain and the preference that it was created in // the past is set. kKeyFound = 0, // Key was found in the Keychain, but the preference that it was created in - // the past was not set. This should happen when Chrome is updated to the - // version supporting the feature for preventing encryption key overwrites. + // the past was not set. kKeyFoundFirstTime = 1, - // Key couldn't be found in the Keychain, but the preference suggests it - // was created in the past. - kOverwritingPrevented = 2, + kOverwritingPrevented_OBSOLETE = 2, // Key was added to the Keychain and the preference is set. kNewKeyAddedToKeychain = 3, - // Some other error occurred. + // Some other error occurred during lookup. kKeychainLookupFailed = 4, - kMaxValue = kKeychainLookupFailed, + // The preference was set but a new key was added to the Keychain. + kKeyPotentiallyOverwritten = 5, + // The preference was set but a new key was not created due to an error. + kKeyOverwriteFailed = 6, + // A new key should be created but an error occured. + kNewKeyAddError = 7, + kMaxValue = kNewKeyAddError, }; virtual ~EncryptionKeyCreationUtil() = default; - // Returns true iff the key should already exists on Mac and false on iOS. - // This method doesn't need to be called from the main thread. - virtual bool KeyAlreadyCreated() = 0; - - // Returns true iff the feature for preventing key overwrites is enabled on - // Mac and false on iOS. This method doesn't need to be called from the main - // thread. - virtual bool ShouldPreventOverwriting() = 0; - // This method is called when the encryption key is successfully retrieved - // from the Keychain. It resets the counter of how many times Chrome prevented - // overwriting the key to zero asynchronously on the main thread. If this is - // called for the very first time, it asynchronously updates the preference - // on the main thread that the key was created. This method doesn't need to be - // called on the main thread. - virtual void OnKeyWasFound() = 0; - - // This method is called when encryption key is added to the Keychain. It + // from the Keychain. If this is called for the very first time, it // asynchronously updates the preference on the main thread that the key was // created. This method doesn't need to be called on the main thread. - virtual void OnKeyWasStored() = 0; + virtual void OnKeyWasFound() = 0; - // Asynchronously increases the number of times overwriting the encryption key - // was prevented on the main thread. This method doesn't need to be called on - // the main thread. - virtual void OnOverwritingPrevented() = 0; + // Called when the encryption key was not in the Keychain. |new_key_stored| + // is true iff a new key was stored successfully. This method doesn't need to + // be called on the main thread. + virtual void OnKeyNotFound(bool new_key_stored) = 0; // This method is called when the Keychain returns error other than // errSecItemNotFound (e.g., user is not authorized to use Keychain, or
diff --git a/components/os_crypt/encryption_key_creation_util_ios.cc b/components/os_crypt/encryption_key_creation_util_ios.cc index 9941bddc..34ef1751 100644 --- a/components/os_crypt/encryption_key_creation_util_ios.cc +++ b/components/os_crypt/encryption_key_creation_util_ios.cc
@@ -10,19 +10,9 @@ EncryptionKeyCreationUtilIOS::~EncryptionKeyCreationUtilIOS() = default; -bool EncryptionKeyCreationUtilIOS::KeyAlreadyCreated() { - return false; -} - -bool EncryptionKeyCreationUtilIOS::ShouldPreventOverwriting() { - return false; -} - void EncryptionKeyCreationUtilIOS::OnKeyWasFound() {} -void EncryptionKeyCreationUtilIOS::OnKeyWasStored() {} - -void EncryptionKeyCreationUtilIOS::OnOverwritingPrevented() {} +void EncryptionKeyCreationUtilIOS::OnKeyNotFound(bool new_key_stored) {} void EncryptionKeyCreationUtilIOS::OnKeychainLookupFailed() {}
diff --git a/components/os_crypt/encryption_key_creation_util_ios.h b/components/os_crypt/encryption_key_creation_util_ios.h index e666dba..e9d8a24 100644 --- a/components/os_crypt/encryption_key_creation_util_ios.h +++ b/components/os_crypt/encryption_key_creation_util_ios.h
@@ -11,20 +11,15 @@ namespace os_crypt { -// A key creation utility for iOS which does nothing as there is no feature -// for preventing key overwrites for iOS. This class is a stub. +// A key creation utility for iOS which does nothing. This class is a stub. class COMPONENT_EXPORT(OS_CRYPT) EncryptionKeyCreationUtilIOS : public EncryptionKeyCreationUtil { public: EncryptionKeyCreationUtilIOS(); ~EncryptionKeyCreationUtilIOS() override; - // os_crypt::EncryptionKeyCreationUtil - bool KeyAlreadyCreated() override; - bool ShouldPreventOverwriting() override; void OnKeyWasFound() override; - void OnKeyWasStored() override; - void OnOverwritingPrevented() override; + void OnKeyNotFound(bool new_key_stored) override; void OnKeychainLookupFailed() override; private:
diff --git a/components/os_crypt/encryption_key_creation_util_mac.cc b/components/os_crypt/encryption_key_creation_util_mac.cc index 017f3e6d..98d393ddd 100644 --- a/components/os_crypt/encryption_key_creation_util_mac.cc +++ b/components/os_crypt/encryption_key_creation_util_mac.cc
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/single_thread_task_runner.h" -#include "components/os_crypt/os_crypt_features_mac.h" #include "components/os_crypt/os_crypt_pref_names_mac.h" #include "components/prefs/pref_service.h" @@ -20,11 +19,6 @@ namespace { -void LogKeyOverwritingPreventionsMetric(int preventions) { - UMA_HISTOGRAM_COUNTS_100("OSCrypt.EncryptionKeyOverwritingPreventions", - preventions); -} - void LogGetEncryptionKeyActionMetric( EncryptionKeyCreationUtil::GetKeyAction action) { UMA_HISTOGRAM_ENUMERATION("OSCrypt.GetEncryptionKeyAction", action); @@ -41,60 +35,30 @@ EncryptionKeyCreationUtilMac::~EncryptionKeyCreationUtilMac() = default; -bool EncryptionKeyCreationUtilMac::KeyAlreadyCreated() { - return key_already_created_; -} - -bool EncryptionKeyCreationUtilMac::ShouldPreventOverwriting() { - return base::FeatureList::IsEnabled( - os_crypt::features::kPreventEncryptionKeyOverwrites); -} - void EncryptionKeyCreationUtilMac::OnKeyWasFound() { - DCHECK(ShouldPreventOverwriting()); if (key_already_created_) { LogGetEncryptionKeyActionMetric(GetKeyAction::kKeyFound); } else { LogGetEncryptionKeyActionMetric(GetKeyAction::kKeyFoundFirstTime); } - LogKeyOverwritingPreventionsMetric(0); UpdateKeyCreationPreference(); - - // Reset the counter of preventions. - main_thread_task_runner_->PostTask( - FROM_HERE, base::BindOnce( - [](PrefService* local_state) { - local_state->SetInteger( - prefs::kKeyOverwritingPreventions, 0); - }, - local_state_)); } -void EncryptionKeyCreationUtilMac::OnKeyWasStored() { - DCHECK(ShouldPreventOverwriting()); - DCHECK(!key_already_created_); - UpdateKeyCreationPreference(); - LogGetEncryptionKeyActionMetric(GetKeyAction::kNewKeyAddedToKeychain); - LogKeyOverwritingPreventionsMetric(0); -} - -void EncryptionKeyCreationUtilMac::OnOverwritingPrevented() { - DCHECK(ShouldPreventOverwriting()); - main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - [](PrefService* local_state) { - int preventions = - local_state->GetInteger(prefs::kKeyOverwritingPreventions) + 1; - local_state->SetInteger(prefs::kKeyOverwritingPreventions, - preventions); - LogKeyOverwritingPreventionsMetric(preventions); - }, - local_state_)); - - LogGetEncryptionKeyActionMetric(GetKeyAction::kOverwritingPrevented); - LOG(ERROR) << "Prevented overwriting the encryption key in the Keychain"; +void EncryptionKeyCreationUtilMac::OnKeyNotFound(bool new_key_stored) { + if (key_already_created_) { + if (new_key_stored) + LogGetEncryptionKeyActionMetric(GetKeyAction::kKeyPotentiallyOverwritten); + else + LogGetEncryptionKeyActionMetric(GetKeyAction::kKeyOverwriteFailed); + } else { + if (new_key_stored) { + LogGetEncryptionKeyActionMetric(GetKeyAction::kNewKeyAddedToKeychain); + UpdateKeyCreationPreference(); + } else { + LogGetEncryptionKeyActionMetric(GetKeyAction::kNewKeyAddError); + } + } } void EncryptionKeyCreationUtilMac::OnKeychainLookupFailed() {
diff --git a/components/os_crypt/encryption_key_creation_util_mac.h b/components/os_crypt/encryption_key_creation_util_mac.h index 4cf7c21..827b7705 100644 --- a/components/os_crypt/encryption_key_creation_util_mac.h +++ b/components/os_crypt/encryption_key_creation_util_mac.h
@@ -29,12 +29,9 @@ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); ~EncryptionKeyCreationUtilMac() override; - // os_crypt::EncryptionKeyCreationUtil - bool KeyAlreadyCreated() override; - bool ShouldPreventOverwriting() override; + // os_crypt::EncryptionKeyCreationUtil: void OnKeyWasFound() override; - void OnKeyWasStored() override; - void OnOverwritingPrevented() override; + void OnKeyNotFound(bool new_key_stored) override; void OnKeychainLookupFailed() override; private:
diff --git a/components/os_crypt/keychain_password_mac.mm b/components/os_crypt/keychain_password_mac.mm index 2a55469..00fe840 100644 --- a/components/os_crypt/keychain_password_mac.mm +++ b/components/os_crypt/keychain_password_mac.mm
@@ -63,8 +63,6 @@ std::string KeychainPassword::GetPassword() const { DCHECK(key_creation_util_); - bool prevent_overwriting_enabled = - key_creation_util_->ShouldPreventOverwriting(); UInt32 password_length = 0; void* password_data = NULL; @@ -76,23 +74,14 @@ std::string password = std::string(static_cast<char*>(password_data), password_length); keychain_.ItemFreeContent(password_data); - if (prevent_overwriting_enabled) { - key_creation_util_->OnKeyWasFound(); - } + key_creation_util_->OnKeyWasFound(); return password; } if (error == errSecItemNotFound) { - if (prevent_overwriting_enabled && - key_creation_util_->KeyAlreadyCreated()) { - key_creation_util_->OnOverwritingPrevented(); - return std::string(); - } std::string password = AddRandomPasswordToKeychain(keychain_, service_name, account_name); - if (prevent_overwriting_enabled && !password.empty()) { - key_creation_util_->OnKeyWasStored(); - } + key_creation_util_->OnKeyNotFound(!password.empty()); return password; }
diff --git a/components/os_crypt/keychain_password_mac_unittest.mm b/components/os_crypt/keychain_password_mac_unittest.mm index dc18bb5..1502ce10 100644 --- a/components/os_crypt/keychain_password_mac_unittest.mm +++ b/components/os_crypt/keychain_password_mac_unittest.mm
@@ -12,11 +12,9 @@ #include "components/os_crypt/encryption_key_creation_util_ios.h" #else #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "components/os_crypt/encryption_key_creation_util_mac.h" -#include "components/os_crypt/os_crypt_features_mac.h" #include "components/os_crypt/os_crypt_pref_names_mac.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" @@ -31,18 +29,14 @@ // An environment for KeychainPassword which initializes mock keychain with // the given value that is going to be returned when accessing the Keychain and // key creation utility with the given initial state (was the encryption key -// previously added to the Keychain or not and how many times overwriting the -// key was prevented initially). +// previously added to the Keychain or not). class KeychainPasswordEnvironment { public: // |keychain_result| is the value that is going to be returned when accessing // the Keychain. If |is_key_already_created| is true, a preference that // indicates if the encryption key was created in the past will be set. - // |key_overwriting_preventions| is the number of times overwriting the key - // was prevented in a row initially. KeychainPasswordEnvironment(OSStatus keychain_result, - bool is_key_already_created, - int key_overwriting_preventions); + bool is_key_already_created); ~KeychainPasswordEnvironment() = default; @@ -55,11 +49,6 @@ bool IsKeyCreationPrefSet() const { return testing_local_state_.GetBoolean(os_crypt::prefs::kKeyCreated); } - - int KeyOverwritingPreventionsPref() const { - return testing_local_state_.GetInteger( - os_crypt::prefs::kKeyOverwritingPreventions); - } #endif private: @@ -72,8 +61,7 @@ KeychainPasswordEnvironment::KeychainPasswordEnvironment( OSStatus keychain_find_generic_result, - bool is_key_already_created, - int key_overwriting_preventions) { + bool is_key_already_created) { // Set the value that keychain is going to return. keychain_.set_find_generic_result(keychain_find_generic_result); @@ -81,12 +69,8 @@ // Initialize the preference on Mac. testing_local_state_.registry()->RegisterBooleanPref( os_crypt::prefs::kKeyCreated, false); - testing_local_state_.registry()->RegisterIntegerPref( - os_crypt::prefs::kKeyOverwritingPreventions, 0); if (is_key_already_created) testing_local_state_.SetBoolean(os_crypt::prefs::kKeyCreated, true); - testing_local_state_.SetInteger(os_crypt::prefs::kKeyOverwritingPreventions, - key_overwriting_preventions); #endif // Initialize encryption key creation utility. @@ -112,50 +96,27 @@ // Waits until all tasks in the task runner's queue are finished. void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } - // If the |prevent_overwrites| is true, it enables the feature for preventing - // encryption key overwrites. Otherwise, it disables that feature. - void UseFeatureForPreventingKeyOverwrites(bool prevent_overwrites); - base::HistogramTester& histogram_tester() { return histogram_tester_; } void ExpectUniqueGetKeyAction(GetKeyAction action) { histogram_tester_.ExpectUniqueSample("OSCrypt.GetEncryptionKeyAction", action, 1); } - - void ExpectUniqueKeyOverwritingPreventions(int count) { - histogram_tester_.ExpectUniqueSample( - "OSCrypt.EncryptionKeyOverwritingPreventions", count, 1); - } #endif private: #if !defined(OS_IOS) base::HistogramTester histogram_tester_; base::test::ScopedTaskEnvironment scoped_task_environment_; - base::test::ScopedFeatureList scoped_feature_list_; #endif DISALLOW_COPY_AND_ASSIGN(KeychainPasswordTest); }; -#if !defined(OS_IOS) -void KeychainPasswordTest::UseFeatureForPreventingKeyOverwrites( - bool prevent_overwrites) { - if (prevent_overwrites) { - scoped_feature_list_.InitAndEnableFeature( - os_crypt::features::kPreventEncryptionKeyOverwrites); - } else { - scoped_feature_list_.InitAndDisableFeature( - os_crypt::features::kPreventEncryptionKeyOverwrites); - } -} -#endif - // Test that if we have an existing password in the Keychain and we are // authorized by the user to read it then we get it back correctly. TEST_F(KeychainPasswordTest, FindPasswordSuccess) { - KeychainPasswordEnvironment environment(noErr, true, 0); + KeychainPasswordEnvironment environment(noErr, true); EXPECT_FALSE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); EXPECT_EQ(0, environment.keychain().password_data_count()); @@ -164,7 +125,7 @@ // Test that if we do not have an existing password in the Keychain then it // gets added successfully and returned. TEST_F(KeychainPasswordTest, FindPasswordNotFound) { - KeychainPasswordEnvironment environment(errSecItemNotFound, false, 0); + KeychainPasswordEnvironment environment(errSecItemNotFound, false); EXPECT_EQ(24U, environment.GetPassword().length()); EXPECT_TRUE(environment.keychain().called_add_generic()); EXPECT_EQ(0, environment.keychain().password_data_count()); @@ -173,7 +134,7 @@ // Test that if get denied access by the user then we return an empty password. // And we should not try to add one. TEST_F(KeychainPasswordTest, FindPasswordNotAuthorized) { - KeychainPasswordEnvironment environment(errSecAuthFailed, false, 0); + KeychainPasswordEnvironment environment(errSecAuthFailed, false); EXPECT_TRUE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); EXPECT_EQ(0, environment.keychain().password_data_count()); @@ -187,7 +148,7 @@ // Test that if some random other error happens then we return an empty // password, and we should not try to add one. TEST_F(KeychainPasswordTest, FindPasswordOtherError) { - KeychainPasswordEnvironment environment(errSecNotAvailable, false, 0); + KeychainPasswordEnvironment environment(errSecNotAvailable, false); EXPECT_TRUE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); EXPECT_EQ(0, environment.keychain().password_data_count()); @@ -200,13 +161,13 @@ // Test that subsequent additions to the keychain give different passwords. TEST_F(KeychainPasswordTest, PasswordsDiffer) { - KeychainPasswordEnvironment environment1(errSecItemNotFound, false, 0); + KeychainPasswordEnvironment environment1(errSecItemNotFound, false); std::string password1 = environment1.GetPassword(); EXPECT_FALSE(password1.empty()); EXPECT_TRUE(environment1.keychain().called_add_generic()); EXPECT_EQ(0, environment1.keychain().password_data_count()); - KeychainPasswordEnvironment environment2(errSecItemNotFound, false, 0); + KeychainPasswordEnvironment environment2(errSecItemNotFound, false); std::string password2 = environment2.GetPassword(); EXPECT_FALSE(password2.empty()); EXPECT_TRUE(environment2.keychain().called_add_generic()); @@ -217,106 +178,59 @@ } #if !defined(OS_IOS) -// Test that a preference is not set when the feature for preventing key -// overwrites is disabled when new key is added to the Keychain. -TEST_F(KeychainPasswordTest, PreventingOverwritesDisabledAddKey) { - UseFeatureForPreventingKeyOverwrites(false); - KeychainPasswordEnvironment environment(errSecItemNotFound, false, 0); +// Test that a key is overwritten even if it was created in the past. +TEST_F(KeychainPasswordTest, OverwriteKey) { + KeychainPasswordEnvironment environment(errSecItemNotFound, true); EXPECT_FALSE(environment.GetPassword().empty()); EXPECT_TRUE(environment.keychain().called_add_generic()); RunUntilIdle(); - EXPECT_FALSE(environment.IsKeyCreationPrefSet()); -} - -// Test that a key is overwritten if it was created in the past when the -// feature is disabled. -TEST_F(KeychainPasswordTest, PreventingOverwritesDisabledOverwriteKey) { - UseFeatureForPreventingKeyOverwrites(false); - KeychainPasswordEnvironment environment(errSecItemNotFound, true, 0); - EXPECT_FALSE(environment.GetPassword().empty()); - EXPECT_TRUE(environment.keychain().called_add_generic()); - RunUntilIdle(); - EXPECT_EQ(0, environment.KeyOverwritingPreventionsPref()); -} - -// Test that a new key is not added if one should already exist in the Keychain, -// and that an empty string is returned. -TEST_F(KeychainPasswordTest, PreventingOverwritesEnabledKeyExistsButNotFound) { - UseFeatureForPreventingKeyOverwrites(true); - KeychainPasswordEnvironment environment(errSecItemNotFound, true, 0); - - EXPECT_TRUE(environment.GetPassword().empty()); - EXPECT_FALSE(environment.keychain().called_add_generic()); - RunUntilIdle(); - // Make sure that prevention counter has increased. - EXPECT_EQ(1, environment.KeyOverwritingPreventionsPref()); - - ExpectUniqueGetKeyAction(GetKeyAction::kOverwritingPrevented); - ExpectUniqueKeyOverwritingPreventions(1); + ExpectUniqueGetKeyAction(GetKeyAction::kKeyPotentiallyOverwritten); } // Test that a new key is added if one doesn't already exist in the Keychain, // and that the key creation preference is set. -TEST_F(KeychainPasswordTest, PreventingOverwritesEnabledAddNewKey) { - UseFeatureForPreventingKeyOverwrites(true); - KeychainPasswordEnvironment environment(errSecItemNotFound, false, 0); +TEST_F(KeychainPasswordTest, AddNewKey) { + KeychainPasswordEnvironment environment(errSecItemNotFound, false); EXPECT_FALSE(environment.GetPassword().empty()); EXPECT_TRUE(environment.keychain().called_add_generic()); RunUntilIdle(); EXPECT_TRUE(environment.IsKeyCreationPrefSet()); - EXPECT_EQ(0, environment.KeyOverwritingPreventionsPref()); - ExpectUniqueGetKeyAction(GetKeyAction::kNewKeyAddedToKeychain); - ExpectUniqueKeyOverwritingPreventions(0); } // Test that the key creation preference is set when successfully accessing the // key from the Keychain for the first time. -TEST_F(KeychainPasswordTest, PreventingOverwritesEnabledFindKeyTheFirstTime) { - UseFeatureForPreventingKeyOverwrites(true); - KeychainPasswordEnvironment environment(noErr, false, 0); +TEST_F(KeychainPasswordTest, FindKeyTheFirstTime) { + KeychainPasswordEnvironment environment(noErr, false); EXPECT_FALSE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); RunUntilIdle(); EXPECT_TRUE(environment.IsKeyCreationPrefSet()); - EXPECT_EQ(0, environment.KeyOverwritingPreventionsPref()); - ExpectUniqueGetKeyAction(GetKeyAction::kKeyFoundFirstTime); - ExpectUniqueKeyOverwritingPreventions(0); } // Test that the key creation preference is not set, that an empty password is // returned and no password is added to the Keychain if an error other than // errSecItemNotFound is returned by the Keychain. -TEST_F(KeychainPasswordTest, PreventingOverwritesEnabledOtherError) { - UseFeatureForPreventingKeyOverwrites(true); - KeychainPasswordEnvironment environment(errSecNotAvailable, false, 0); +TEST_F(KeychainPasswordTest, LookupOtherError) { + KeychainPasswordEnvironment environment(errSecNotAvailable, false); EXPECT_TRUE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); RunUntilIdle(); EXPECT_FALSE(environment.IsKeyCreationPrefSet()); - EXPECT_EQ(0, environment.KeyOverwritingPreventionsPref()); - ExpectUniqueGetKeyAction(GetKeyAction::kKeychainLookupFailed); - EXPECT_TRUE(histogram_tester() - .GetAllSamples("OSCrypt.EncryptionKeyOverwritingPreventions") - .empty()); } -TEST_F(KeychainPasswordTest, PreventingOverwritesEnabledKeyFoundSecondTime) { - UseFeatureForPreventingKeyOverwrites(true); - KeychainPasswordEnvironment environment(noErr, true, 1); +TEST_F(KeychainPasswordTest, KeyFoundSecondTime) { + KeychainPasswordEnvironment environment(noErr, true); EXPECT_FALSE(environment.GetPassword().empty()); EXPECT_FALSE(environment.keychain().called_add_generic()); RunUntilIdle(); - EXPECT_EQ(0, environment.KeyOverwritingPreventionsPref()); - ExpectUniqueGetKeyAction(GetKeyAction::kKeyFound); - ExpectUniqueKeyOverwritingPreventions(0); } #endif // !defined(OS_IOS)
diff --git a/components/os_crypt/os_crypt_features_mac.cc b/components/os_crypt/os_crypt_features_mac.cc deleted file mode 100644 index cdbc7b7..0000000 --- a/components/os_crypt/os_crypt_features_mac.cc +++ /dev/null
@@ -1,17 +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 "components/os_crypt/os_crypt_features_mac.h" - -namespace os_crypt { -namespace features { - -// Prevents overwriting the encryption key in the Keychain on Mac if the key is -// unavailable, but there is a preference set that the key was created in the -// past. -const base::Feature kPreventEncryptionKeyOverwrites = { - "PreventEncryptionKeyOverwrites", base::FEATURE_DISABLED_BY_DEFAULT}; - -} // namespace features -} // namespace os_crypt
diff --git a/components/os_crypt/os_crypt_features_mac.h b/components/os_crypt/os_crypt_features_mac.h deleted file mode 100644 index 6821ee72..0000000 --- a/components/os_crypt/os_crypt_features_mac.h +++ /dev/null
@@ -1,20 +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 COMPONENTS_OS_CRYPT_OS_CRYPT_FEATURES_MAC_H_ -#define COMPONENTS_OS_CRYPT_OS_CRYPT_FEATURES_MAC_H_ - -#include "base/component_export.h" -#include "base/feature_list.h" - -namespace os_crypt { -namespace features { - -COMPONENT_EXPORT(OS_CRYPT) -extern const base::Feature kPreventEncryptionKeyOverwrites; - -} // namespace features -} // namespace os_crypt - -#endif // COMPONENTS_OS_CRYPT_OS_CRYPT_FEATURES_MAC_H_
diff --git a/components/os_crypt/os_crypt_mac.mm b/components/os_crypt/os_crypt_mac.mm index 91a27e4f..cde83f0 100644 --- a/components/os_crypt/os_crypt_mac.mm +++ b/components/os_crypt/os_crypt_mac.mm
@@ -236,7 +236,6 @@ #if !defined(OS_IOS) void OSCrypt::RegisterLocalPrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(os_crypt::prefs::kKeyCreated, false); - registry->RegisterIntegerPref(os_crypt::prefs::kKeyOverwritingPreventions, 0); } void OSCrypt::Init(PrefService* local_state) {
diff --git a/components/os_crypt/os_crypt_pref_names_mac.cc b/components/os_crypt/os_crypt_pref_names_mac.cc index 987d362..13f247d 100644 --- a/components/os_crypt/os_crypt_pref_names_mac.cc +++ b/components/os_crypt/os_crypt_pref_names_mac.cc
@@ -8,8 +8,6 @@ namespace prefs { const char kKeyCreated[] = "os_crypt.key_created"; -const char kKeyOverwritingPreventions[] = - "os_crypt.key_overwriting_preventions"; } // namespace prefs } // namespace os_crypt
diff --git a/components/os_crypt/os_crypt_pref_names_mac.h b/components/os_crypt/os_crypt_pref_names_mac.h index a522b84..02886d1 100644 --- a/components/os_crypt/os_crypt_pref_names_mac.h +++ b/components/os_crypt/os_crypt_pref_names_mac.h
@@ -15,18 +15,12 @@ // Sometimes when the Keychain seems to be available, it may happen that Chrome // fails to retrieve the key from the Keychain, which causes Chrome to overwrite // the old key with a newly generated key. Overwriting the encryption key can -// cause various problems, so there should be another mechanism to make sure -// that the key is not overwritten. This flag should be set to true once the +// cause various problems. This flag should be set to true once the // encryption key is generated or successfully retrieved. If this flag is set to -// true and Chrome couldn't get the encryption key from the Keychain, encryption -// should be temporarily unavailable instead of generating a new key. +// true and Chrome couldn't get the encryption key from the Keychain, it signals +// that something is going wrong on the machine. COMPONENT_EXPORT(OS_CRYPT) extern const char kKeyCreated[]; -// The number of times Chrome prevented overwriting the encryption key in a row. -// Initial value is zero and is reset back to zero once the key is successfully -// retrieved from the Keychain. -COMPONENT_EXPORT(OS_CRYPT) extern const char kKeyOverwritingPreventions[]; - } // namespace prefs } // namespace os_crypt
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index a8fb5a5..ec742e8 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -157,6 +157,10 @@ const FormFieldData* password = nullptr; const FormFieldData* new_password = nullptr; const FormFieldData* confirmation_password = nullptr; + // True if the information about fields could only be derived after relaxing + // some constraints. The resulting PasswordForm should only be used for + // fallback UI. + bool is_fallback = false; // Returns true if some password field is present. This is the minimal // requirement for a successful creation of a PasswordForm is present. @@ -319,60 +323,83 @@ return result->HasPasswords() ? std::move(result) : nullptr; } -// Returns only relevant password fields from |processed_fields|. Namely, if -// |mode| == SAVING return only non-empty fields (for saving empty fields are -// useless). This ignores all passwords with Interactability below -// |best_interactability| and also fields with names which sound like CVC -// fields. Stores the iterator to the first relevant password in -// |first_relevant_password|. |readonly_status| will be updated according to the -// processing of the parsed fields; it must not be null. +// This computes the "likely" condition from the design https://goo.gl/ERvoEN . +// The |field| is likely to be a password if it is not a CVC field, not +// readonly, etc. |*ignored_readonly| is incremented specifically if this +// function returns false because of the |field| being readonly. +bool IsLikelyPassword(const FormFieldData& field, size_t* ignored_readonly) { + // Readonly fields can be an indication that filling is useless (e.g., the + // page might use a virtual keyboard). However, if the field was readonly + // only temporarily, that makes it still interesting for saving. The fact + // that a user typed or Chrome filled into that field in the past is an + // indicator that the readonly was only temporary. + if (field.is_readonly && + !(field.properties_mask & (FieldPropertiesFlags::USER_TYPED | + FieldPropertiesFlags::AUTOFILLED))) { + ++*ignored_readonly; + return false; + } + return !IsFieldCVC(field); +} + +// Filters the available passwords from |processed_fields| using these rules: +// (1) Passwords with Interactability below |best_interactability| are removed. +// (2) If |mode| == |kSaving|, passwords with empty values are removed. +// (3) Passwords for which IsLikelyPassword returns false are removed. +// If applying rules (1)-(3) results in a non-empty vector of password fields, +// that vector is returned. Otherwise, only rules (1) and (2) are applied and +// the result returned (even if it is empty). +// Neither of the following output parameters may be null: +// |readonly_status| will be updated according to the processing of the parsed +// fields. +// |is_fallback| is set to true if the filtering rule (3) was not used to +// obtain the result. std::vector<const FormFieldData*> GetRelevantPasswords( const std::vector<ProcessedField>& processed_fields, FormDataParser::Mode mode, Interactability best_interactability, - std::vector<ProcessedField>::const_iterator* first_relevant_password, - FormDataParser::ReadonlyPasswordFields* readonly_status) { - DCHECK(first_relevant_password); - *first_relevant_password = processed_fields.end(); - std::vector<const FormFieldData*> result; - result.reserve(processed_fields.size()); + FormDataParser::ReadonlyPasswordFields* readonly_status, + bool* is_fallback) { DCHECK(readonly_status); + DCHECK(is_fallback); - const bool consider_only_non_empty = mode == FormDataParser::Mode::kSaving; + // Step 0: filter out all non-password fields. + std::vector<const ProcessedField*> passwords; + passwords.reserve(processed_fields.size()); + for (const ProcessedField& processed_field : processed_fields) { + if (processed_field.is_password) + passwords.push_back(&processed_field); + } + DCHECK(!passwords.empty()); - // These two counters are used to determine the ReadonlyPassowrdFields value + // These two counters are used to determine the ReadonlyPasswordFields value // corresponding to this form. - size_t all_passwords_seen = 0; + const size_t all_passwords_seen = passwords.size(); size_t ignored_readonly = 0; - for (auto it = processed_fields.begin(); it != processed_fields.end(); ++it) { - const ProcessedField& processed_field = *it; - if (!processed_field.is_password) - continue; - ++all_passwords_seen; - if (!MatchesInteractability(processed_field, best_interactability)) - continue; - if (consider_only_non_empty && processed_field.field->value.empty()) - continue; - // Readonly fields can be an indication that filling is useless (e.g., the - // page might use a virtual keyboard). However, if the field was readonly - // only temporarily, that makes it still interesting for saving. The fact - // that a user typed or Chrome filled into that field in the past is an - // indicator that the readonly was only temporary. - if (processed_field.field->is_readonly && - !(processed_field.field->properties_mask & - (FieldPropertiesFlags::USER_TYPED | - FieldPropertiesFlags::AUTOFILLED))) { - ++ignored_readonly; - continue; - } - if (IsFieldCVC(*processed_field.field)) - continue; - if (*first_relevant_password == processed_fields.end()) - *first_relevant_password = it; - result.push_back(processed_field.field); + + // Step 1: apply filter criterion (1). + base::EraseIf( + passwords, [best_interactability](const ProcessedField* processed_field) { + return !MatchesInteractability(*processed_field, best_interactability); + }); + + if (mode == FormDataParser::Mode::kSaving) { + // Step 2: apply filter criterion (2). + base::EraseIf(passwords, [](const ProcessedField* processed_field) { + return processed_field->field->value.empty(); + }); } - DCHECK_NE(0u, all_passwords_seen); + // Step 3: apply filter criterion (3). Keep the current content of + // |passwords| though, in case it is needed for fallback. + std::vector<const ProcessedField*> filtered; + filtered.reserve(passwords.size()); + std::copy_if(passwords.begin(), passwords.end(), std::back_inserter(filtered), + [&ignored_readonly](const ProcessedField* processed_field) { + return IsLikelyPassword(*processed_field->field, + &ignored_readonly); + }); + // Compute the readonly statistic for metrics. DCHECK_LE(ignored_readonly, all_passwords_seen); if (ignored_readonly == 0) *readonly_status = FormDataParser::ReadonlyPasswordFields::kNoneIgnored; @@ -381,6 +408,18 @@ else *readonly_status = FormDataParser::ReadonlyPasswordFields::kAllIgnored; + // Ensure that |filtered| contains what needs to be returned... + if (filtered.empty()) { + filtered = std::move(passwords); + *is_fallback = true; + } + + // ...and strip ProcessedFields down to FormFieldData. + std::vector<const FormFieldData*> result; + result.reserve(filtered.size()); + for (const ProcessedField* processed_field : filtered) + result.push_back(processed_field->field); + return result; } @@ -532,10 +571,9 @@ // Try to find password elements (current, new, confirmation) among those // with best interactability. - first_relevant_password = processed_fields.end(); std::vector<const FormFieldData*> passwords = GetRelevantPasswords(processed_fields, mode, password_max, - &first_relevant_password, readonly_status); + readonly_status, &found_fields->is_fallback); if (passwords.empty()) return; LocateSpecificPasswords(passwords, &found_fields->password, @@ -543,6 +581,13 @@ &found_fields->confirmation_password); if (!found_fields->HasPasswords()) return; + for (auto it = processed_fields.begin(); it != processed_fields.end(); + ++it) { + if (it->field == passwords[0]) { + first_relevant_password = it; + break; + } + } } else { const uint32_t password_ids[] = { ExtractUniqueId(found_fields->password), @@ -762,6 +807,7 @@ result->type = PasswordForm::TYPE_MANUAL; result->username_may_use_prefilled_placeholder = GetMayUsePrefilledPlaceholder(form_predictions, significant_fields); + result->only_for_fallback_saving = significant_fields.is_fallback; // Set data related to specific fields. SetFields(significant_fields, result.get());
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 44dcecb..b11c104 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -86,6 +86,8 @@ const autofill::ValueElementVector* all_possible_usernames = nullptr; bool username_may_use_prefilled_placeholder = false; base::Optional<FormDataParser::ReadonlyPasswordFields> readonly_status; + // If the result should be marked as only useful for fallbacks. + bool fallback_only = false; }; // Returns numbers which are distinct from each other within the scope of one @@ -360,6 +362,8 @@ EXPECT_EQ(*test_case.all_possible_usernames, parsed_form->other_possible_usernames); } + EXPECT_EQ(test_case.fallback_only, + parsed_form->only_for_fallback_saving); } if (test_case.readonly_status) { EXPECT_EQ(*test_case.readonly_status, parser.readonly_status()); @@ -907,9 +911,13 @@ "For passwords, readonly means: 'give up', perhaps there is a " "virtual keyboard, filling might be ignored", { - {.form_control_type = "text"}, - {.form_control_type = "password", .is_readonly = true}, + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_readonly = true}, }, + // And "give-up" means "fallback-only". + .fallback_only = true, }, { "But correctly marked passwords are accepted even if readonly", @@ -1355,13 +1363,27 @@ TEST(FormParserTest, CVC) { CheckTestData({ { - "Name of 'verification_type' matches the CVC pattern.", + "Name of 'verification_type' matches the CVC pattern, ignore that " + "one.", { {.role = ElementRole::USERNAME, .form_control_type = "text"}, {.form_control_type = "password", .name = "verification_type"}, {.role = ElementRole::CURRENT_PASSWORD, .form_control_type = "password"}, }, + // The result should be trusted for more than just fallback, because + // the chosen password was not a suspected CVC. + .fallback_only = false, + }, + { + "Create a fallback for the only password being a CVC field.", + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .name = "verification_type"}, + }, + .fallback_only = true, }, }); } @@ -1430,15 +1452,21 @@ }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kSomeIgnored, + // The result should be trusted for more than just fallback, because + // the chosen password was not readonly. + .fallback_only = false, }, { - "All readonly passwords ignored.", + "All readonly passwords ignored, only returned as a fallback.", { - {.form_control_type = "text"}, - {.is_readonly = true, .form_control_type = "password"}, + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_readonly = true}, }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kAllIgnored, + .fallback_only = true, }, }); }
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 6f838eb..0f109c6 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -892,18 +892,25 @@ void PasswordManager::ProcessSubmittedForm( const FormData& submitted_form, const PasswordManagerDriver* driver) { + std::unique_ptr<BrowserSavePasswordProgressLogger> logger; + if (password_manager_util::IsLoggingActive(client_)) { + logger.reset( + new BrowserSavePasswordProgressLogger(client_->GetLogManager())); + } if (!client_->IsSavingAndFillingEnabledForCurrentPage()) { - std::unique_ptr<BrowserSavePasswordProgressLogger> logger; - if (password_manager_util::IsLoggingActive(client_)) { - logger.reset( - new BrowserSavePasswordProgressLogger(client_->GetLogManager())); - } RecordProvisionalSaveFailure( PasswordManagerMetricsRecorder::SAVING_DISABLED, submitted_form.origin, logger.get()); return; } + // No need to report PasswordManagerMetricsRecorder::EMPTY_PASSWORD, because + // PasswordToSave in NewPasswordFormManager DCHECKs that the password is never + // empty. + + // TODO(https://crbug.com/831123): Add the + // ShouldBlockPasswordForSameOriginButDifferentScheme check. + NewPasswordFormManager* matching_form_manager = nullptr; for (const auto& manager : form_managers_) { if (manager->SetSubmittedFormIfIsManaged(submitted_form, driver)) { @@ -912,8 +919,11 @@ } } if (!matching_form_manager) { - // TODO(https://crbug.com/831123). Add metrics and implement more robust - // handling when |matching_form_manager| is not found. + // TODO(https://crbug.com/831123): Implement more robust handling when + // |matching_form_manager| is not found. + RecordProvisionalSaveFailure( + PasswordManagerMetricsRecorder::NO_MATCHING_FORM, submitted_form.origin, + logger.get()); return; }
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 1e1f8133..e1f09e65 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -101,6 +101,7 @@ MOCK_CONST_METHOD0(GetMainFrameURL, const GURL&()); MOCK_METHOD0(GetDriver, PasswordManagerDriver*()); MOCK_CONST_METHOD0(GetStoreResultFilter, const MockStoreResultFilter*()); + MOCK_METHOD0(GetMetricsRecorder, PasswordManagerMetricsRecorder*()); // Workaround for std::unique_ptr<> lacking a copy constructor. bool PromptUserToSaveOrUpdatePassword( @@ -202,6 +203,7 @@ EXPECT_CALL(*store_, IsAbleToSavePasswords()).WillRepeatedly(Return(true)); ON_CALL(client_, GetMainFrameURL()).WillByDefault(ReturnRef(test_url_)); + ON_CALL(client_, GetMetricsRecorder()).WillByDefault(Return(nullptr)); } void TearDown() override { @@ -2936,4 +2938,42 @@ task_runner_->FastForwardUntilNoTasksRemain(); } +// Check that when a form is submitted and a NewPasswordFormManager not present, +// this ends up reported. +TEST_F(PasswordManagerTest, ReportMissingFormManager_New) { + base::test::ScopedFeatureList scoped_feature_list; + TurnOnNewParsingForSaving(&scoped_feature_list); + + EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage()) + .WillRepeatedly(Return(true)); + manager()->OnPasswordFormsParsed(&driver_, {}); + manager()->OnPasswordFormsRendered(&driver_, {}, true); + + base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + auto metrics_recorder = std::make_unique<PasswordManagerMetricsRecorder>( + 1234, GURL("http://example.com")); + EXPECT_CALL(client_, GetMetricsRecorder()) + .WillRepeatedly(Return(metrics_recorder.get())); + + PasswordForm unobserved_form = MakeSimpleForm(); + manager()->OnPasswordFormSubmitted(nullptr, unobserved_form); + + // 2 samples instead of just 1, because one is also reported from the missing + // (old) PasswordFormManager. + histogram_tester.ExpectUniqueSample( + "PasswordManager.ProvisionalSaveFailure", + PasswordManagerMetricsRecorder::NO_MATCHING_FORM, 2); + // Flush the UKM reports. + metrics_recorder.reset(); + std::vector<const ukm::mojom::UkmEntry*> ukm_entries = + test_ukm_recorder.GetEntriesByName( + ukm::builders::PageWithPassword::kEntryName); + ASSERT_EQ(1u, ukm_entries.size()); + test_ukm_recorder.ExpectEntryMetric( + ukm_entries[0], + ukm::builders::PageWithPassword::kProvisionalSaveFailureName, + static_cast<int64_t>(PasswordManagerMetricsRecorder::NO_MATCHING_FORM)); +} + } // namespace password_manager
diff --git a/components/policy/core/browser/browser_policy_connector.cc b/components/policy/core/browser/browser_policy_connector.cc index c427f0a..290fb1e 100644 --- a/components/policy/core/browser/browser_policy_connector.cc +++ b/components/policy/core/browser/browser_policy_connector.cc
@@ -178,6 +178,8 @@ CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs); registry->RegisterStringPref( policy_prefs::kMachineLevelUserCloudPolicyEnrollmentToken, std::string()); + registry->RegisterBooleanPref( + policy_prefs::kCloudManagementEnrollmentMandatory, false); } } // namespace policy
diff --git a/components/policy/core/common/policy_pref_names.cc b/components/policy/core/common/policy_pref_names.cc index f0429e19..369bd296 100644 --- a/components/policy/core/common/policy_pref_names.cc +++ b/components/policy/core/common/policy_pref_names.cc
@@ -30,5 +30,10 @@ // by the cloud policy subsystem. const char kUserPolicyRefreshRate[] = "policy.user_refresh_rate"; +// Boolean indicates whether the cloud management enrollment is mandatory or +// not. +const char kCloudManagementEnrollmentMandatory[] = + "policy.cloud_management_enrollment_mandatory"; + } // namespace policy_prefs } // namespace policy
diff --git a/components/policy/core/common/policy_pref_names.h b/components/policy/core/common/policy_pref_names.h index 44feb561..ea9e2a6 100644 --- a/components/policy/core/common/policy_pref_names.h +++ b/components/policy/core/common/policy_pref_names.h
@@ -16,6 +16,7 @@ POLICY_EXPORT extern const char kUrlBlacklist[]; POLICY_EXPORT extern const char kUrlWhitelist[]; POLICY_EXPORT extern const char kUserPolicyRefreshRate[]; +POLICY_EXPORT extern const char kCloudManagementEnrollmentMandatory[]; } // namespace policy_prefs } // namespace policy
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 38f21fc..f8aa2b08 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -12470,6 +12470,24 @@ The value of this policy is an Enrollment token that can be retrieved from the Google Admin console.''', }, { + 'name': 'CloudManagementEnrollmentMandatory', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome.*:72-'], + 'features': { + 'dynamic_refresh': False, + 'per_profile': False, + }, + 'example_value': True, + 'id': 505, + 'caption': '''Enable mandatory cloud management enrollment''', + 'tags': [], + 'desc': ''' + If this policy is set to True, cloud management enrollment is mandatory and blocks Chrome launch process if failed. + + If this policy is left unset or set to False, cloud management enrollment is optional and does not blocks Chrome launch process if failed.''', + }, + { 'name': 'AutoplayAllowed', 'type': 'main', 'schema': { 'type': 'boolean' }, @@ -14089,5 +14107,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 504 + 'highest_id_currently_used': 505 }
diff --git a/components/printing/common/print_messages.cc b/components/printing/common/print_messages.cc index 18df7614a..528773d8 100644 --- a/components/printing/common/print_messages.cc +++ b/components/printing/common/print_messages.cc
@@ -28,15 +28,6 @@ #error "Failed to include header components/printing/common/print_messages.h" #endif -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ -#undef COMPONENTS_PRINTING_COMMON_PRINTING_PARAM_TRAITS_MACROS_H_ -#include "components/printing/common/print_messages.h" -#ifndef COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ -#error "Failed to include header components/printing/common/print_messages.h" -#endif - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/services/pdf_compositor/BUILD.gn b/components/services/pdf_compositor/BUILD.gn index 782df43..4c36e8be6 100644 --- a/components/services/pdf_compositor/BUILD.gn +++ b/components/services/pdf_compositor/BUILD.gn
@@ -53,22 +53,18 @@ "//testing/gmock/include", "//third_party/skia/include/core", ] + deps = [ ":pdf_compositor", + "//base", "//base/test:test_support", "//cc/paint:paint", "//components/crash/core/common:crash_key", "//components/services/pdf_compositor/public/interfaces", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//skia", "//testing/gmock", "//testing/gtest", ] } - - service_manifest("pdf_compositor_service_unittest_manifest") { - name = "pdf_compositor_service_unittest" - source = "pdf_compositor_service_unittest_manifest.json" - packaged_services = [ ":pdf_compositor_manifest" ] - } }
diff --git a/components/services/pdf_compositor/OWNERS b/components/services/pdf_compositor/OWNERS index 3fb8863..5f7d2e5 100644 --- a/components/services/pdf_compositor/OWNERS +++ b/components/services/pdf_compositor/OWNERS
@@ -2,6 +2,3 @@ per-file pdf_compositor_manifest.json=set noparent per-file pdf_compositor_manifest.json=file://ipc/SECURITY_OWNERS - -per-file pdf_compositor_service_unittest_manifest.json=set noparent -per-file pdf_compositor_service_unittest_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/services/pdf_compositor/pdf_compositor_service.cc b/components/services/pdf_compositor/pdf_compositor_service.cc index 23b9134..b512db0 100644 --- a/components/services/pdf_compositor/pdf_compositor_service.cc +++ b/components/services/pdf_compositor/pdf_compositor_service.cc
@@ -32,20 +32,24 @@ namespace { -void OnPdfCompositorRequest( - const std::string& creator, - service_manager::ServiceContextRefFactory* ref_factory, - printing::mojom::PdfCompositorRequest request) { +void OnPdfCompositorRequest(const std::string& creator, + service_manager::ServiceKeepalive* keepalive, + printing::mojom::PdfCompositorRequest request) { mojo::MakeStrongBinding(std::make_unique<printing::PdfCompositorImpl>( - creator, ref_factory->CreateRef()), + creator, keepalive->CreateRef()), std::move(request)); } + } // namespace namespace printing { -PdfCompositorService::PdfCompositorService(const std::string& creator) - : creator_(creator.empty() ? "Chromium" : creator), weak_factory_(this) {} +PdfCompositorService::PdfCompositorService( + const std::string& creator, + service_manager::mojom::ServiceRequest request) + : creator_(creator.empty() ? "Chromium" : creator), + binding_(this, std::move(request)), + keepalive_(&binding_, base::TimeDelta{}) {} PdfCompositorService::~PdfCompositorService() { #if defined(OS_WIN) @@ -55,27 +59,35 @@ // static std::unique_ptr<service_manager::Service> PdfCompositorService::Create( - const std::string& creator) { + const std::string& creator, + service_manager::mojom::ServiceRequest request) { #if defined(OS_WIN) // Initialize direct write font proxy so skia can use it. content::InitializeDWriteFontProxy(); #endif - return std::make_unique<printing::PdfCompositorService>(creator); + return std::make_unique<printing::PdfCompositorService>(creator, + std::move(request)); } -void PdfCompositorService::PrepareToStart() { +void PdfCompositorService::OnStart() { + registry_.AddInterface( + base::BindRepeating(&OnPdfCompositorRequest, creator_, &keepalive_)); + + if (skip_initialization_for_testing_) + return; + // Set up discardable memory manager. discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr; if (features::IsMultiProcessMash()) { #if defined(USE_AURA) - context()->connector()->BindInterface(ws::mojom::kServiceName, - &manager_ptr); + binding_.GetConnector()->BindInterface(ws::mojom::kServiceName, + &manager_ptr); #else NOTREACHED(); #endif } else { - context()->connector()->BindInterface(content::mojom::kBrowserServiceName, - &manager_ptr); + binding_.GetConnector()->BindInterface(content::mojom::kBrowserServiceName, + &manager_ptr); } discardable_shared_memory_manager_ = std::make_unique< discardable_memory::ClientDiscardableSharedMemoryManager>( @@ -99,19 +111,10 @@ // Initialize a connection to FontLoaderMac service so blink platform's web // sandbox support can communicate with it to load font. content::UtilityThread::Get()->InitializeFontLoaderMac( - context()->connector()); + binding_.GetConnector()); #endif } -void PdfCompositorService::OnStart() { - PrepareToStart(); - - ref_factory_ = std::make_unique<service_manager::ServiceContextRefFactory>( - context()->CreateQuitClosure()); - registry_.AddInterface( - base::Bind(&OnPdfCompositorRequest, creator_, ref_factory_.get())); -} - void PdfCompositorService::OnBindInterface( const service_manager::BindSourceInfo& source_info, const std::string& interface_name,
diff --git a/components/services/pdf_compositor/pdf_compositor_service.h b/components/services/pdf_compositor/pdf_compositor_service.h index 48ec8fb..b0bc48f9 100644 --- a/components/services/pdf_compositor/pdf_compositor_service.h +++ b/components/services/pdf_compositor/pdf_compositor_service.h
@@ -14,18 +14,21 @@ #include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/service_keepalive.h" namespace printing { class PdfCompositorService : public service_manager::Service { public: - explicit PdfCompositorService(const std::string& creator); + PdfCompositorService(const std::string& creator, + service_manager::mojom::ServiceRequest request); ~PdfCompositorService() override; // Factory function for use as an embedded service. static std::unique_ptr<service_manager::Service> Create( - const std::string& creator); + const std::string& creator, + service_manager::mojom::ServiceRequest request); // service_manager::Service: void OnStart() override; @@ -33,7 +36,9 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; - virtual void PrepareToStart(); + void set_skip_initialization_for_testing(bool skip) { + skip_initialization_for_testing_ = skip; + } private: // The creator of this service. @@ -41,11 +46,13 @@ // otherwise just use string "Chromium". const std::string creator_; + service_manager::ServiceBinding binding_; + service_manager::ServiceKeepalive keepalive_; + bool skip_initialization_for_testing_ = false; std::unique_ptr<discardable_memory::ClientDiscardableSharedMemoryManager> discardable_shared_memory_manager_; - std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; service_manager::BinderRegistry registry_; - base::WeakPtrFactory<PdfCompositorService> weak_factory_; + base::WeakPtrFactory<PdfCompositorService> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(PdfCompositorService); };
diff --git a/components/services/pdf_compositor/pdf_compositor_service_unittest.cc b/components/services/pdf_compositor/pdf_compositor_service_unittest.cc index 1140f26..fe38e37 100644 --- a/components/services/pdf_compositor/pdf_compositor_service_unittest.cc +++ b/components/services/pdf_compositor/pdf_compositor_service_unittest.cc
@@ -8,17 +8,14 @@ #include "base/callback.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/test/test_discardable_memory_allocator.h" #include "cc/paint/paint_flags.h" #include "cc/paint/skia_paint_canvas.h" #include "components/services/pdf_compositor/pdf_compositor_service.h" #include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h" #include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" -#include "services/service_manager/public/mojom/service_factory.mojom.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkStream.h" @@ -26,68 +23,25 @@ namespace printing { -// In order to test PdfCompositorService, this class overrides PrepareToStart() -// to do nothing. So the test discardable memory allocator set up by -// PdfCompositorServiceTest will be used. Also checks for the service setup are -// skipped since we don't have those setups in unit tests. -class PdfCompositorTestService : public printing::PdfCompositorService { +class PdfCompositorServiceTest : public testing::Test { public: - explicit PdfCompositorTestService(const std::string& creator) - : PdfCompositorService(creator) {} - ~PdfCompositorTestService() override {} - - // PdfCompositorService: - void PrepareToStart() override {} -}; - -class PdfServiceTestClient : public service_manager::test::ServiceTestClient, - public service_manager::mojom::ServiceFactory { - public: - explicit PdfServiceTestClient(service_manager::test::ServiceTest* test) - : service_manager::test::ServiceTestClient(test) { - registry_.AddInterface<service_manager::mojom::ServiceFactory>( - base::Bind(&PdfServiceTestClient::Create, base::Unretained(this))); - } - ~PdfServiceTestClient() override {} - - // service_manager::Service - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override { - registry_.BindInterface(interface_name, std::move(interface_pipe)); + PdfCompositorServiceTest() + : connector_(test_connector_factory_.CreateConnector()), + service_( + "pdf_compositor_service_unittest", + test_connector_factory_.RegisterInstance(mojom::kServiceName)) { + // We don't want the service instance setting up its own discardable memory + // allocator, which it normally does. Instead it will use the one provided + // by our fixture in |SetUp()| below. + service_.set_skip_initialization_for_testing(true); } - // service_manager::mojom::ServiceFactory - void CreateService( - service_manager::mojom::ServiceRequest request, - const std::string& name, - service_manager::mojom::PIDReceiverPtr pid_receiver) override { - if (!name.compare(mojom::kServiceName)) { - service_context_ = std::make_unique<service_manager::ServiceContext>( - std::make_unique<PdfCompositorTestService>("pdf_compositor_unittest"), - std::move(request)); - } - } - - void Create(service_manager::mojom::ServiceFactoryRequest request) { - service_factory_bindings_.AddBinding(this, std::move(request)); - } - - private: - service_manager::BinderRegistry registry_; - mojo::BindingSet<service_manager::mojom::ServiceFactory> - service_factory_bindings_; - std::unique_ptr<service_manager::ServiceContext> service_context_; -}; - -class PdfCompositorServiceTest : public service_manager::test::ServiceTest { - public: - PdfCompositorServiceTest() : ServiceTest("pdf_compositor_service_unittest") {} - ~PdfCompositorServiceTest() override {} + ~PdfCompositorServiceTest() override = default; MOCK_METHOD1(CallbackOnCompositeSuccess, void(const base::ReadOnlySharedMemoryRegion&)); MOCK_METHOD1(CallbackOnCompositeStatus, void(mojom::PdfCompositor::Status)); + void OnCompositeToPdfCallback(mojom::PdfCompositor::Status status, base::ReadOnlySharedMemoryRegion region) { if (status == mojom::PdfCompositor::Status::SUCCESS) @@ -100,11 +54,11 @@ MOCK_METHOD0(ConnectionClosed, void()); protected: - // service_manager::test::ServiceTest: + service_manager::Connector* connector() { return connector_.get(); } + void SetUp() override { base::DiscardableMemoryAllocator::SetInstance( &discardable_memory_allocator_); - ServiceTest::SetUp(); ASSERT_FALSE(compositor_); connector()->BindInterface(mojom::kServiceName, &compositor_); @@ -114,15 +68,10 @@ } void TearDown() override { - // Clean up compositor_.reset(); base::DiscardableMemoryAllocator::SetInstance(nullptr); } - std::unique_ptr<service_manager::Service> CreateService() override { - return std::make_unique<PdfServiceTestClient>(this); - } - base::ReadOnlySharedMemoryRegion CreateMSKP() { SkDynamicMemoryWStream stream; sk_sp<SkDocument> doc = SkMakeMultiPictureDocument(&stream); @@ -156,11 +105,16 @@ run_loop_->Run(); } + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<base::RunLoop> run_loop_; mojom::PdfCompositorPtr compositor_; base::TestDiscardableMemoryAllocator discardable_memory_allocator_; private: + service_manager::TestConnectorFactory test_connector_factory_; + std::unique_ptr<service_manager::Connector> connector_; + PdfCompositorService service_; + DISALLOW_COPY_AND_ASSIGN(PdfCompositorServiceTest); }; @@ -183,8 +137,8 @@ CallCompositorWithSuccess(std::move(compositor_)); } -// Test coexistence of multiple service instances. -TEST_F(PdfCompositorServiceTest, MultipleServiceInstances) { +// Test coexistence of multiple PdfCompositor interface bindings. +TEST_F(PdfCompositorServiceTest, MultipleCompositors) { // One service can bind multiple interfaces. mojom::PdfCompositorPtr another_compositor; ASSERT_FALSE(another_compositor); @@ -197,9 +151,9 @@ CallCompositorWithSuccess(std::move(another_compositor)); } -// Test data structures and content of multiple service instances +// Test data structures and content of multiple PdfCompositor interface bindings // are independent from each other. -TEST_F(PdfCompositorServiceTest, IndependentServiceInstances) { +TEST_F(PdfCompositorServiceTest, IndependentCompositors) { // Create a new connection 2. mojom::PdfCompositorPtr compositor2; ASSERT_FALSE(compositor2);
diff --git a/components/services/pdf_compositor/pdf_compositor_service_unittest_manifest.json b/components/services/pdf_compositor/pdf_compositor_service_unittest_manifest.json deleted file mode 100644 index 19a847f..0000000 --- a/components/services/pdf_compositor/pdf_compositor_service_unittest_manifest.json +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "name": "pdf_compositor_service_unittest", - "display_name": "Pdf Compositor Service Unittest", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "service_manager:service_factory": [ - "service_manager.mojom.ServiceFactory" - ] - }, - "requires": { - "pdf_compositor": [ "compositor" ], - "service_manager": [ "service_manager:service_manager" ] - } - } - } -}
diff --git a/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.cc b/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.cc index 763208c..d0eb57b 100644 --- a/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.cc +++ b/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.cc
@@ -13,7 +13,8 @@ namespace printing { std::unique_ptr<service_manager::Service> CreatePdfCompositorService( - const std::string& creator) { + const std::string& creator, + service_manager::mojom::ServiceRequest request) { #if defined(OS_POSIX) && !defined(OS_ANDROID) content::UtilityThread::Get()->EnsureBlinkInitializedWithSandboxSupport(); #else @@ -22,7 +23,7 @@ // Hook up blink's codecs so skia can call them. SkGraphics::SetImageGeneratorFromEncodedDataFactory( blink::WebImageGenerator::CreateAsSkImageGenerator); - return printing::PdfCompositorService::Create(creator); + return printing::PdfCompositorService::Create(creator, std::move(request)); } } // namespace printing
diff --git a/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.h b/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.h index 371f472..41f8b6a 100644 --- a/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.h +++ b/components/services/pdf_compositor/public/cpp/pdf_compositor_service_factory.h
@@ -9,11 +9,13 @@ #include <string> #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace printing { std::unique_ptr<service_manager::Service> CreatePdfCompositorService( - const std::string& creator); + const std::string& creator, + service_manager::mojom::ServiceRequest request); } // namespace printing
diff --git a/components/signin/core/browser/fake_signin_manager.cc b/components/signin/core/browser/fake_signin_manager.cc index 022c2a58..6a3f355d 100644 --- a/components/signin/core/browser/fake_signin_manager.cc +++ b/components/signin/core/browser/fake_signin_manager.cc
@@ -75,7 +75,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - const OAuthTokenFetchedCallback& oauth_fetched_callback) { + OAuthTokenFetchedCallback oauth_fetched_callback) { set_auth_in_progress( account_tracker_service()->SeedAccountInfo(gaia_id, username)); set_password(password); @@ -85,7 +85,7 @@ possibly_invalid_email_.assign(username); if (!oauth_fetched_callback.is_null()) - oauth_fetched_callback.Run(refresh_token); + std::move(oauth_fetched_callback).Run(refresh_token); } void FakeSigninManager::CompletePendingSignin() { @@ -164,7 +164,7 @@ client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); client_->GetPrefs()->ClearPref(prefs::kSignedInTime); - FireGoogleSignedOut(account_id, account_info); + FireGoogleSignedOut(account_info); } #endif // !defined (OS_CHROMEOS)
diff --git a/components/signin/core/browser/fake_signin_manager.h b/components/signin/core/browser/fake_signin_manager.h index a7314d2..33a2af3 100644 --- a/components/signin/core/browser/fake_signin_manager.h +++ b/components/signin/core/browser/fake_signin_manager.h
@@ -71,7 +71,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - const OAuthTokenFetchedCallback& oauth_fetched_callback) override; + OAuthTokenFetchedCallback oauth_fetched_callback) override; void CompletePendingSignin() override;
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 738def7..b71edd4 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -100,7 +100,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - const OAuthTokenFetchedCallback& callback) { + OAuthTokenFetchedCallback callback) { DCHECK(!IsAuthenticated()); SigninType signin_type = refresh_token.empty() ? SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN @@ -114,7 +114,7 @@ if (!callback.is_null()) { // Callback present, let the caller complete the pending sign-in. - callback.Run(temp_refresh_token_); + std::move(callback).Run(temp_refresh_token_); } else { // No callback, so just complete the pending signin. CompletePendingSignin(); @@ -259,7 +259,7 @@ break; } - FireGoogleSignedOut(account_id, account_info); + FireGoogleSignedOut(account_info); } void SigninManager::Initialize(PrefService* local_state) { @@ -443,10 +443,8 @@ } } -void SigninManager::FireGoogleSignedOut(const std::string& account_id, - const AccountInfo& account_info) { +void SigninManager::FireGoogleSignedOut(const AccountInfo& account_info) { for (auto& observer : observer_list_) { - observer.GoogleSignedOut(account_id, account_info.email); observer.GoogleSignedOut(account_info); } }
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h index 836a9910..3e889c0 100644 --- a/components/signin/core/browser/signin_manager.h +++ b/components/signin/core/browser/signin_manager.h
@@ -64,7 +64,8 @@ // but before the profile transitions to the "signed-in" state. This allows // callers to load policy and prompt the user appropriately before completing // signin. The callback is passed the just-fetched OAuth login refresh token. - typedef base::Callback<void(const std::string&)> OAuthTokenFetchedCallback; + using OAuthTokenFetchedCallback = + base::OnceCallback<void(const std::string&)>; // Used to remove accounts from the token service and the account tracker. enum class RemoveAccountsOption { @@ -108,7 +109,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - const OAuthTokenFetchedCallback& oauth_fetched_callback); + OAuthTokenFetchedCallback oauth_fetched_callback); // Copies auth credentials from one SigninManager to this one. This is used // when creating a new profile during the signin process to transfer the @@ -224,8 +225,7 @@ void FireGoogleSigninSucceeded(); // Send all observers |GoogleSignedOut| notifications. - void FireGoogleSignedOut(const std::string& account_id, - const AccountInfo& account_info); + void FireGoogleSignedOut(const AccountInfo& account_info); // Waits for the AccountTrackerService, then sends GoogleSigninSucceeded to // the client and clears the local password.
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index e010297..e30a2ea 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -74,10 +74,6 @@ // Called when the currently signed-in user for a user has been signed out. virtual void GoogleSignedOut(const AccountInfo& account_info) {} - // DEPRECATED: Use the above method instead. - virtual void GoogleSignedOut(const std::string& account_id, - const std::string& username) {} - protected: virtual ~Observer() {}
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc index 740fb56c..75bd3d8 100644 --- a/components/signin/core/browser/signin_manager_unittest.cc +++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -65,8 +65,7 @@ num_successful_signins_with_password_++; } - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override { + void GoogleSignedOut(const AccountInfo& account_info) override { num_signouts_++; } }; @@ -194,10 +193,10 @@ EXPECT_FALSE(manager_->IsAuthenticated()); // Since the password is empty, must verify the gaia cookies first. - SigninManager::OAuthTokenFetchedCallback callback = base::Bind( - &SigninManagerTest::CompleteSigninCallback, base::Unretained(this)); - manager_->StartSignInWithRefreshToken("rt", "gaia_id", "user@gmail.com", - "password", callback); + manager_->StartSignInWithRefreshToken( + "rt", "gaia_id", "user@gmail.com", "password", + base::BindOnce(&SigninManagerTest::CompleteSigninCallback, + base::Unretained(this))); ExpectSignInWithRefreshTokenSuccess(); ASSERT_EQ(1U, oauth_tokens_fetched_.size());
diff --git a/components/signin/core/browser/signin_status_metrics_provider.cc b/components/signin/core/browser/signin_status_metrics_provider.cc index d1ff779..56d2db4 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.cc +++ b/components/signin/core/browser/signin_status_metrics_provider.cc
@@ -87,8 +87,8 @@ } } -void SigninStatusMetricsProvider::GoogleSignedOut(const std::string& account_id, - const std::string& username) { +void SigninStatusMetricsProvider::GoogleSignedOut( + const AccountInfo& account_info) { SigninStatus recorded_signin_status = signin_status(); if (recorded_signin_status == ALL_PROFILES_SIGNED_IN) { UpdateSigninStatus(MIXED_SIGNIN_STATUS);
diff --git a/components/signin/core/browser/signin_status_metrics_provider.h b/components/signin/core/browser/signin_status_metrics_provider.h index b9b5363..f01dfe5f 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.h +++ b/components/signin/core/browser/signin_status_metrics_provider.h
@@ -70,8 +70,7 @@ // SigninManagerBase::Observer: void GoogleSigninSucceeded(const AccountInfo& account_info) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + void GoogleSignedOut(const AccountInfo& account_info) override; // Obtain sign-in status and add observers. void Initialize();
diff --git a/components/signin/core/browser/signin_status_metrics_provider_unittest.cc b/components/signin/core/browser/signin_status_metrics_provider_unittest.cc index f56ff6d..203e98a 100644 --- a/components/signin/core/browser/signin_status_metrics_provider_unittest.cc +++ b/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
@@ -43,13 +43,13 @@ // Initial status is all signed in and then one of the profiles is signed out. metrics_provider.UpdateInitialSigninStatus(2, 2); - metrics_provider.GoogleSignedOut(std::string(), std::string()); + metrics_provider.GoogleSignedOut(AccountInfo()); EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, metrics_provider.GetSigninStatusForTesting()); // Initial status is mixed and then one of the profiles is signed out. metrics_provider.UpdateInitialSigninStatus(2, 1); - metrics_provider.GoogleSignedOut(std::string(), std::string()); + metrics_provider.GoogleSignedOut(AccountInfo()); EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, metrics_provider.GetSigninStatusForTesting()); }
diff --git a/components/signin/ios/browser/account_consistency_service.h b/components/signin/ios/browser/account_consistency_service.h index a2ecd59c..4488de9 100644 --- a/components/signin/ios/browser/account_consistency_service.h +++ b/components/signin/ios/browser/account_consistency_service.h
@@ -157,8 +157,7 @@ // SigninManagerBase::Observer implementation. void GoogleSigninSucceeded(const AccountInfo& account_info) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + void GoogleSignedOut(const AccountInfo& account_info) override; // ActiveStateManager::Observer implementation. void OnActive() override;
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm index 62110fa..39095fa6 100644 --- a/components/signin/ios/browser/account_consistency_service.mm +++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -495,8 +495,8 @@ AddChromeConnectedCookies(); } -void AccountConsistencyService::GoogleSignedOut(const std::string& account_id, - const std::string& username) { +void AccountConsistencyService::GoogleSignedOut( + const AccountInfo& account_info) { // There is not need to remove CHROME_CONNECTED cookies on |GoogleSignedOut| // events as these cookies will be removed by the GaiaCookieManagerServer // right before fetching the Gaia logout request.
diff --git a/components/subresource_filter/content/common/subresource_filter_message_generator.h b/components/subresource_filter/content/common/subresource_filter_message_generator.h index 3820c798..a1f06db 100644 --- a/components/subresource_filter/content/common/subresource_filter_message_generator.h +++ b/components/subresource_filter/content/common/subresource_filter_message_generator.h
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "components/subresource_filter/content/common/subresource_filter_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/components/sync/engine/net/http_bridge.cc b/components/sync/engine/net/http_bridge.cc index 6464d429..f964584 100644 --- a/components/sync/engine/net/http_bridge.cc +++ b/components/sync/engine/net/http_bridge.cc
@@ -131,7 +131,7 @@ request_completed(false), request_succeeded(false), http_response_code(-1), - error_code(-1) {} + net_error_code(-1) {} HttpBridge::URLFetchState::~URLFetchState() {} HttpBridge::HttpBridge( @@ -199,7 +199,8 @@ } } -bool HttpBridge::MakeSynchronousPost(int* error_code, int* response_code) { +bool HttpBridge::MakeSynchronousPost(int* net_error_code, + int* http_response_code) { #if DCHECK_IS_ON() DCHECK(thread_checker_.CalledOnValidThread()); { @@ -224,8 +225,8 @@ base::AutoLock lock(fetch_state_lock_); DCHECK(fetch_state_.request_completed || fetch_state_.aborted); - *error_code = fetch_state_.error_code; - *response_code = fetch_state_.http_response_code; + *net_error_code = fetch_state_.net_error_code; + *http_response_code = fetch_state_.http_response_code; return fetch_state_.request_succeeded; } @@ -374,7 +375,7 @@ NOTREACHED() << "Could not post task to delete URLLoader"; } - fetch_state_.error_code = net::ERR_ABORTED; + fetch_state_.net_error_code = net::ERR_ABORTED; http_post_completed_.Signal(); } @@ -399,20 +400,20 @@ if (fetch_state_.aborted) return; - int response_code = -1; + int http_response_code = -1; if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) { - response_code = url_loader->ResponseInfo()->headers->response_code(); + http_response_code = url_loader->ResponseInfo()->headers->response_code(); fetch_state_.response_headers = url_loader->ResponseInfo()->headers; } OnURLLoadCompleteInternal( - response_code, url_loader->NetError(), url_loader->GetContentSize(), + http_response_code, url_loader->NetError(), url_loader->GetContentSize(), url_loader->GetFinalURL(), std::move(response_body)); } void HttpBridge::OnURLLoadCompleteInternal( - int response_code, - int net_error, + int http_response_code, + int net_error_code, int64_t compressed_content_length, const GURL& final_url, std::unique_ptr<std::string> response_body) { @@ -428,9 +429,10 @@ fetch_state_.end_time = base::Time::Now(); fetch_state_.request_completed = true; - fetch_state_.request_succeeded = net_error == net::OK && response_code != -1; - fetch_state_.http_response_code = response_code; - fetch_state_.error_code = net_error; + fetch_state_.request_succeeded = + net_error_code == net::OK && http_response_code != -1; + fetch_state_.http_response_code = http_response_code; + fetch_state_.net_error_code = net_error_code; if (fetch_state_.request_succeeded) LogTimeout(false); @@ -438,7 +440,7 @@ "Sync.URLFetchResponse", fetch_state_.request_succeeded ? fetch_state_.http_response_code - : net::URLRequestStatus::FromError(fetch_state_.error_code) + : net::URLRequestStatus::FromError(fetch_state_.net_error_code) .ToNetError()); UMA_HISTOGRAM_LONG_TIMES("Sync.URLFetchTime", fetch_state_.end_time - fetch_state_.start_time); @@ -487,7 +489,7 @@ fetch_state_.request_completed = true; fetch_state_.request_succeeded = false; fetch_state_.http_response_code = -1; - fetch_state_.error_code = net::ERR_TIMED_OUT; + fetch_state_.net_error_code = net::ERR_TIMED_OUT; // This method is called by the timer, not the url fetcher implementation, // so it's safe to delete the fetcher here.
diff --git a/components/sync/engine/net/http_bridge.h b/components/sync/engine/net/http_bridge.h index ff2033a..e113328 100644 --- a/components/sync/engine/net/http_bridge.h +++ b/components/sync/engine/net/http_bridge.h
@@ -59,7 +59,8 @@ void SetPostPayload(const char* content_type, int content_length, const char* content) override; - bool MakeSynchronousPost(int* error_code, int* response_code) override; + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override; void Abort() override; // WARNING: these response content methods are used to extract plain old data @@ -104,8 +105,8 @@ void CallMakeAsynchronousPost() { MakeAsynchronousPost(); } // Actual implementation of the load complete callback. Called by tests too. - void OnURLLoadCompleteInternal(int response_code, - int net_error, + void OnURLLoadCompleteInternal(int http_response_code, + int net_error_code, int64_t compressed_content_length, const GURL& final_url, std::unique_ptr<std::string> response_body); @@ -168,7 +169,7 @@ bool request_completed; bool request_succeeded; int http_response_code; - int error_code; + int net_error_code; std::string response_content; scoped_refptr<net::HttpResponseHeaders> response_headers;
diff --git a/components/sync/engine/net/http_post_provider_interface.h b/components/sync/engine/net/http_post_provider_interface.h index 5e52b9c..d3e5544 100644 --- a/components/sync/engine/net/http_post_provider_interface.h +++ b/components/sync/engine/net/http_post_provider_interface.h
@@ -32,7 +32,8 @@ // Returns true if the URL request succeeded. If the request failed, // error() may be non-zero and hence contain more information. - virtual bool MakeSynchronousPost(int* error_code, int* response_code) = 0; + virtual bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) = 0; // Get the length of the content returned in the HTTP response. // This does not count the trailing null-terminating character returned
diff --git a/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc b/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc index ee1bd0f..a02dea4 100644 --- a/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc +++ b/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc
@@ -3,6 +3,9 @@ // found in the LICENSE file. #include "components/sync/engine_impl/loopback_server/loopback_connection_manager.h" +#include "components/sync/engine_impl/net/server_connection_manager.h" +#include "net/http/http_status_code.h" + namespace syncer { LoopbackConnectionManager::LoopbackConnectionManager( @@ -17,10 +20,17 @@ PostBufferParams* params, const std::string& path, const std::string& auth_token) { - loopback_server_.HandleCommand( - params->buffer_in, ¶ms->response.server_status, - ¶ms->response.response_code, ¶ms->buffer_out); - return params->response.server_status == HttpResponse::SERVER_CONNECTION_OK; + loopback_server_.HandleCommand(params->buffer_in, + ¶ms->response.http_response_code, + ¶ms->buffer_out); + + if (params->response.http_response_code != net::HTTP_OK) { + params->response.server_status = HttpResponse::SYNC_SERVER_ERROR; + return false; + } + + params->response.server_status = HttpResponse::SERVER_CONNECTION_OK; + return true; } } // namespace syncer
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.cc b/components/sync/engine_impl/loopback_server/loopback_server.cc index eb4108d9..ce65b6f8 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server.cc +++ b/components/sync/engine_impl/loopback_server/loopback_server.cc
@@ -233,11 +233,9 @@ entities_[entity->GetId()] = std::move(entity); } -void LoopbackServer::HandleCommand( - const string& request, - HttpResponse::ServerConnectionCode* server_status, - int64_t* response_code, - std::string* response) { +void LoopbackServer::HandleCommand(const string& request, + int* http_response_code, + std::string* response) { DCHECK(thread_checker_.CalledOnValidThread()); sync_pb::ClientToServerMessage message; @@ -267,15 +265,13 @@ success = true; break; default: - *server_status = HttpResponse::SYNC_SERVER_ERROR; - *response_code = net::ERR_NOT_IMPLEMENTED; + *http_response_code = net::ERR_NOT_IMPLEMENTED; *response = string(); return; } if (!success) { - *server_status = HttpResponse::SYNC_SERVER_ERROR; - *response_code = net::ERR_FAILED; + *http_response_code = net::ERR_FAILED; *response = string(); UMA_HISTOGRAM_ENUMERATION( "Sync.Local.RequestTypeOnError", message.message_contents(), @@ -288,8 +284,7 @@ response_proto.set_store_birthday(GetStoreBirthday()); - *server_status = HttpResponse::SERVER_CONNECTION_OK; - *response_code = net::HTTP_OK; + *http_response_code = net::HTTP_OK; *response = response_proto.SerializeAsString(); // TODO(pastarmovj): This should be done asynchronously.
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.h b/components/sync/engine_impl/loopback_server/loopback_server.h index de4b120..3f1574e 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server.h +++ b/components/sync/engine_impl/loopback_server/loopback_server.h
@@ -18,7 +18,6 @@ #include "base/values.h" #include "components/sync/base/model_type.h" #include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" -#include "components/sync/engine_impl/net/server_connection_manager.h" #include "components/sync/protocol/loopback_server.pb.h" #include "components/sync/protocol/sync.pb.h" @@ -44,13 +43,11 @@ explicit LoopbackServer(const base::FilePath& persistent_file); virtual ~LoopbackServer(); - // Handles a /command POST (with the given |request|) to the server. Three - // output arguments, |server_status|, |response_code|, and |response|, are - // used to pass data back to the caller. The command has failed if the value - // pointed to by |error_code| is nonzero. + // Handles a /command POST (with the given |request|) to the server. Two + // output arguments, |http_response_code|, and |response|, are used to pass + // data back to the caller. void HandleCommand(const std::string& request, - HttpResponse::ServerConnectionCode* server_status, - int64_t* response_code, + int* http_response_code, std::string* response); // Enables strong consistency model (i.e. server detects conflicts).
diff --git a/components/sync/engine_impl/net/server_connection_manager.cc b/components/sync/engine_impl/net/server_connection_manager.cc index 6009be3..20af13e 100644 --- a/components/sync/engine_impl/net/server_connection_manager.cc +++ b/components/sync/engine_impl/net/server_connection_manager.cc
@@ -29,7 +29,7 @@ static const char kSyncServerSyncPath[] = "/command/"; HttpResponse::HttpResponse() - : response_code(kUnsetResponseCode), + : http_response_code(kUnsetResponseCode), content_length(kUnsetContentLength), payload_length(kUnsetPayloadLength), server_status(NONE) {} @@ -64,7 +64,7 @@ string* buffer_out, HttpResponse* response, bool require_response) { - if (net::HTTP_OK != response->response_code) { + if (net::HTTP_OK != response->http_response_code) { response->server_status = HttpResponse::SYNC_SERVER_ERROR; return false; } @@ -232,7 +232,7 @@ auth_token_.clear(); } - if (!ok || net::HTTP_OK != params->response.response_code) + if (!ok || net::HTTP_OK != params->response.http_response_code) return false; if (connection->ReadBufferResponse(¶ms->buffer_out, ¶ms->response, @@ -261,7 +261,7 @@ } std::ostream& operator<<(std::ostream& s, const struct HttpResponse& hr) { - s << " Response Code (bogus on error): " << hr.response_code; + s << " Response Code (bogus on error): " << hr.http_response_code; s << " Content-Length (bogus on error): " << hr.content_length; s << " Server Status: " << HttpResponse::GetServerConnectionCodeString(hr.server_status);
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h index 30739949..198dfcd 100644 --- a/components/sync/engine_impl/net/server_connection_manager.h +++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -55,7 +55,7 @@ }; // The HTTP Status code. - int64_t response_code; + int http_response_code; // The value of the Content-length header. int64_t content_length;
diff --git a/components/sync/engine_impl/net/sync_server_connection_manager.cc b/components/sync/engine_impl/net/sync_server_connection_manager.cc index 2ba9ebbc..a05ab4ed9 100644 --- a/components/sync/engine_impl/net/sync_server_connection_manager.cc +++ b/components/sync/engine_impl/net/sync_server_connection_manager.cc
@@ -55,8 +55,8 @@ payload.data()); // Issue the POST, blocking until it finishes. - int error_code = 0; - int response_code = 0; + int net_error_code = 0; + int http_response_code = 0; if (!cancelation_signal_->TryRegisterHandler(this)) { // Return early because cancelation signal was signaled. response->server_status = HttpResponse::CONNECTION_UNAVAILABLE; @@ -66,22 +66,22 @@ &CancelationSignal::UnregisterHandler, base::Unretained(cancelation_signal_), base::Unretained(this))); - if (!http->MakeSynchronousPost(&error_code, &response_code)) { - DCHECK_NE(error_code, net::OK); - DVLOG(1) << "Http POST failed, error returns: " << error_code; + if (!http->MakeSynchronousPost(&net_error_code, &http_response_code)) { + DCHECK_NE(net_error_code, net::OK); + DVLOG(1) << "Http POST failed, error returns: " << net_error_code; response->server_status = HttpResponse::CONNECTION_UNAVAILABLE; return false; } // We got a server response, copy over response codes and content. - response->response_code = response_code; + response->http_response_code = http_response_code; response->content_length = static_cast<int64_t>(http->GetResponseContentLength()); response->payload_length = static_cast<int64_t>(http->GetResponseContentLength()); - if (response->response_code < 400) + if (response->http_response_code < 400) response->server_status = HttpResponse::SERVER_CONNECTION_OK; - else if (response->response_code == net::HTTP_UNAUTHORIZED) + else if (response->http_response_code == net::HTTP_UNAUTHORIZED) response->server_status = HttpResponse::SYNC_AUTH_ERROR; else response->server_status = HttpResponse::SYNC_SERVER_ERROR;
diff --git a/components/sync/engine_impl/net/sync_server_connection_manager_unittest.cc b/components/sync/engine_impl/net/sync_server_connection_manager_unittest.cc index fd410e216..97b0e76f 100644 --- a/components/sync/engine_impl/net/sync_server_connection_manager_unittest.cc +++ b/components/sync/engine_impl/net/sync_server_connection_manager_unittest.cc
@@ -34,9 +34,10 @@ void SetPostPayload(const char* content_type, int content_length, const char* content) override {} - bool MakeSynchronousPost(int* error_code, int* response_code) override { + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override { wait_for_abort_.TimedWait(TestTimeouts::action_max_timeout()); - *error_code = net::ERR_ABORTED; + *net_error_code = net::ERR_ABORTED; return false; } int GetResponseContentLength() const override { return 0; } @@ -126,7 +127,8 @@ class FailingHttpPost : public HttpPostProviderInterface { public: - explicit FailingHttpPost(int error_code) : error_code_(error_code) {} + explicit FailingHttpPost(int net_error_code) + : net_error_code_(net_error_code) {} ~FailingHttpPost() override {} void SetExtraRequestHeaders(const char* headers) override {} @@ -134,8 +136,9 @@ void SetPostPayload(const char* content_type, int content_length, const char* content) override {} - bool MakeSynchronousPost(int* error_code, int* response_code) override { - *error_code = error_code_; + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override { + *net_error_code = net_error_code_; return false; } int GetResponseContentLength() const override { return 0; } @@ -147,25 +150,26 @@ void Abort() override {} private: - int error_code_; + int net_error_code_; }; class FailingHttpPostFactory : public HttpPostProviderFactory { public: - explicit FailingHttpPostFactory(int error_code) : error_code_(error_code) {} + explicit FailingHttpPostFactory(int net_error_code) + : net_error_code_(net_error_code) {} ~FailingHttpPostFactory() override {} void Init(const std::string& user_agent, const BindToTrackerCallback& bind_to_tracker_callback) override {} HttpPostProviderInterface* Create() override { - return new FailingHttpPost(error_code_); + return new FailingHttpPost(net_error_code_); } void Destroy(HttpPostProviderInterface* http) override { delete static_cast<FailingHttpPost*>(http); } private: - int error_code_; + int net_error_code_; }; } // namespace
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 50482e2c..7072361 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -849,7 +849,8 @@ void SetPostPayload(const char* content_type, int content_length, const char* content) override {} - bool MakeSynchronousPost(int* error_code, int* response_code) override { + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override { return false; } int GetResponseContentLength() const override { return 0; }
diff --git a/components/sync/model/fake_model_type_change_processor.cc b/components/sync/model/fake_model_type_change_processor.cc index 4135fc4..c2fe6da 100644 --- a/components/sync/model/fake_model_type_change_processor.cc +++ b/components/sync/model/fake_model_type_change_processor.cc
@@ -37,12 +37,12 @@ const std::string& storage_key, MetadataChangeList* metadata_change_list) {} -void FakeModelTypeChangeProcessor::UntrackEntity( - const EntityData& entity_data) {} - void FakeModelTypeChangeProcessor::UntrackEntityForStorageKey( const std::string& storage_key) {} +void FakeModelTypeChangeProcessor::UntrackEntityForClientTagHash( + const std::string& client_tag_hash) {} + bool FakeModelTypeChangeProcessor::IsEntityUnsynced( const std::string& storage_key) { return false;
diff --git a/components/sync/model/fake_model_type_change_processor.h b/components/sync/model/fake_model_type_change_processor.h index fa1c4d96..48c70965 100644 --- a/components/sync/model/fake_model_type_change_processor.h +++ b/components/sync/model/fake_model_type_change_processor.h
@@ -35,8 +35,9 @@ void UpdateStorageKey(const EntityData& entity_data, const std::string& storage_key, MetadataChangeList* metadata_change_list) override; - void UntrackEntity(const EntityData& entity_data) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; + void UntrackEntityForClientTagHash( + const std::string& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; void OnModelStarting(ModelTypeSyncBridge* bridge) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override;
diff --git a/components/sync/model/fake_model_type_sync_bridge.cc b/components/sync/model/fake_model_type_sync_bridge.cc index 16e0196e..86fe0ae 100644 --- a/components/sync/model/fake_model_type_sync_bridge.cc +++ b/components/sync/model/fake_model_type_sync_bridge.cc
@@ -228,7 +228,8 @@ if (storage_key.empty()) { storage_key = GetStorageKeyImpl(change.data()); if (base::ContainsKey(keys_to_ignore_, storage_key)) { - change_processor()->UntrackEntity(change.data()); + change_processor()->UntrackEntityForClientTagHash( + change.data().client_tag_hash); } else { change_processor()->UpdateStorageKey(change.data(), storage_key, metadata_change_list.get());
diff --git a/components/sync/model/mock_model_type_change_processor.cc b/components/sync/model/mock_model_type_change_processor.cc index 8c7d7af..4f204ac 100644 --- a/components/sync/model/mock_model_type_change_processor.cc +++ b/components/sync/model/mock_model_type_change_processor.cc
@@ -40,14 +40,15 @@ other_->UpdateStorageKey(entity_data, storage_key, metadata_change_list); } - void UntrackEntity(const EntityData& entity_data) override { - other_->UntrackEntity(entity_data); - } - void UntrackEntityForStorageKey(const std::string& storage_key) override { other_->UntrackEntityForStorageKey(storage_key); } + void UntrackEntityForClientTagHash( + const std::string& client_tag_hash) override { + other_->UntrackEntityForClientTagHash(client_tag_hash); + } + bool IsEntityUnsynced(const std::string& storage_key) override { return other_->IsEntityUnsynced(storage_key); } @@ -108,12 +109,12 @@ ON_CALL(*this, UpdateStorageKey(_, _, _)) .WillByDefault( Invoke(delegate, &ModelTypeChangeProcessor::UpdateStorageKey)); - ON_CALL(*this, UntrackEntity(_)) - .WillByDefault( - Invoke(delegate, &ModelTypeChangeProcessor::UntrackEntity)); ON_CALL(*this, UntrackEntityForStorageKey(_)) .WillByDefault(Invoke( delegate, &ModelTypeChangeProcessor::UntrackEntityForStorageKey)); + ON_CALL(*this, UntrackEntityForClientTagHash(_)) + .WillByDefault(Invoke( + delegate, &ModelTypeChangeProcessor::UntrackEntityForClientTagHash)); ON_CALL(*this, IsEntityUnsynced(_)) .WillByDefault( Invoke(delegate, &ModelTypeChangeProcessor::IsEntityUnsynced));
diff --git a/components/sync/model/mock_model_type_change_processor.h b/components/sync/model/mock_model_type_change_processor.h index 1fd3104c..725a9fd9 100644 --- a/components/sync/model/mock_model_type_change_processor.h +++ b/components/sync/model/mock_model_type_change_processor.h
@@ -30,9 +30,10 @@ void(const EntityData& entity_data, const std::string& storage_key, MetadataChangeList* metadata_change_list)); - MOCK_METHOD1(UntrackEntity, void(const EntityData& entity_data)); MOCK_METHOD1(UntrackEntityForStorageKey, void(const std::string& storage_key)); + MOCK_METHOD1(UntrackEntityForClientTagHash, + void(const std::string& client_tag_hash)); MOCK_METHOD1(IsEntityUnsynced, bool(const std::string& storage_key)); MOCK_METHOD1(OnModelStarting, void(ModelTypeSyncBridge* bridge)); MOCK_METHOD1(ModelReadyToSync, void(std::unique_ptr<MetadataBatch> batch));
diff --git a/components/sync/model/model_type_change_processor.h b/components/sync/model/model_type_change_processor.h index 35f3b7a..fd52c5a 100644 --- a/components/sync/model/model_type_change_processor.h +++ b/components/sync/model/model_type_change_processor.h
@@ -37,7 +37,8 @@ std::unique_ptr<EntityData> entity_data, MetadataChangeList* metadata_change_list) = 0; - // Inform the processor of a deleted entity. + // Inform the processor of a deleted entity. The call is ignored if + // |storage_key| is unknown. virtual void Delete(const std::string& storage_key, MetadataChangeList* metadata_change_list) = 0; @@ -51,14 +52,6 @@ const std::string& storage_key, MetadataChangeList* metadata_change_list) = 0; - // Remove entity metadata and do not track the entity. This function only - // applies to datatypes that can't generate storage key based on EntityData. - // Bridge should call this function when handling - // MergeSyncData/ApplySyncChanges to inform the processor that this entity - // should not been tracked. Datatypes that support GetStorageKey should call - // change_processor()->Delete() instead. - virtual void UntrackEntity(const EntityData& entity_data) = 0; - // Remove entity metadata and do not track the entity. Applies to datatypes // that support local deletions that should not get synced up (e.g. TYPED_URL // does not sync up deletions of expired URLs). If the deletion should get @@ -66,6 +59,13 @@ // |storage_key| is unknown. virtual void UntrackEntityForStorageKey(const std::string& storage_key) = 0; + // Remove entity metadata and do not track the entity, exactly like + // UntrackEntityForStorageKey() above. This function should only be called by + // datatypes that can't generate storage keys. The call is ignored if + // |client_tag_hash| is unknown. + virtual void UntrackEntityForClientTagHash( + const std::string& client_tag_hash) = 0; + // Returns true if a tracked entity has local changes. A commit may or may not // be in progress at this time. // TODO(mastiz): The only user of this is HISTORY_DELETE_DIRECTIVES which
diff --git a/components/sync/model/recording_model_type_change_processor.cc b/components/sync/model/recording_model_type_change_processor.cc index 0b7af30..8e54c6fa 100644 --- a/components/sync/model/recording_model_type_change_processor.cc +++ b/components/sync/model/recording_model_type_change_processor.cc
@@ -38,16 +38,16 @@ storage_key, FakeModelTypeSyncBridge::CopyEntityData(entity_data))); } -void RecordingModelTypeChangeProcessor::UntrackEntity( - const EntityData& entity_data) { - untrack_set_.insert(FakeModelTypeSyncBridge::CopyEntityData(entity_data)); -} - void RecordingModelTypeChangeProcessor::UntrackEntityForStorageKey( const std::string& storage_key) { untrack_for_storage_key_set_.insert(storage_key); } +void RecordingModelTypeChangeProcessor::UntrackEntityForClientTagHash( + const std::string& client_tag_hash) { + untrack_for_client_tag_hash_set_.insert(client_tag_hash); +} + void RecordingModelTypeChangeProcessor::ModelReadyToSync( std::unique_ptr<MetadataBatch> batch) { std::swap(metadata_, batch);
diff --git a/components/sync/model/recording_model_type_change_processor.h b/components/sync/model/recording_model_type_change_processor.h index 3d231c8..a3aa2f72 100644 --- a/components/sync/model/recording_model_type_change_processor.h +++ b/components/sync/model/recording_model_type_change_processor.h
@@ -31,8 +31,9 @@ void UpdateStorageKey(const EntityData& entity_data, const std::string& storage_key, MetadataChangeList* metadata_change_list) override; - void UntrackEntity(const EntityData& entity_data) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; + void UntrackEntityForClientTagHash( + const std::string& client_tag_hash) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override; bool IsTrackingMetadata() override; std::string TrackedAccountId() override; @@ -51,14 +52,14 @@ const std::set<std::string>& delete_set() const { return delete_set_; } - const std::set<std::unique_ptr<EntityData>>& untrack_set() const { - return untrack_set_; - } - const std::set<std::string>& untrack_for_storage_key_set() const { return untrack_for_storage_key_set_; } + const std::set<std::string>& untrack_for_client_tag_hash_set() const { + return untrack_for_client_tag_hash_set_; + } + MetadataBatch* metadata() const { return metadata_.get(); } // Constructs the processor and assigns its raw pointer to the given address. @@ -72,8 +73,8 @@ std::multimap<std::string, std::unique_ptr<EntityData>> put_multimap_; std::multimap<std::string, std::unique_ptr<EntityData>> update_multimap_; std::set<std::string> delete_set_; - std::set<std::unique_ptr<EntityData>> untrack_set_; std::set<std::string> untrack_for_storage_key_set_; + std::set<std::string> untrack_for_client_tag_hash_set_; std::unique_ptr<MetadataBatch> metadata_; bool is_tracking_metadata_ = true; };
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 4971349..3f6c3d6 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -445,10 +445,7 @@ ProcessorEntityTracker* entity = GetEntityForStorageKey(storage_key); if (entity == nullptr) { - // That's unusual, but not necessarily a bad thing. // Missing is as good as deleted as far as the model is concerned. - DLOG(WARNING) << "Attempted to delete missing item." - << " storage key: " << storage_key; return; } @@ -482,15 +479,6 @@ metadata_change_list->UpdateMetadata(storage_key, entity->metadata()); } -void ClientTagBasedModelTypeProcessor::UntrackEntity( - const EntityData& entity_data) { - const std::string& client_tag_hash = entity_data.client_tag_hash; - DCHECK(model_type_state_.initial_sync_done()); - DCHECK(!client_tag_hash.empty()); - DCHECK(GetEntityForTagHash(client_tag_hash)->storage_key().empty()); - entities_.erase(client_tag_hash); -} - void ClientTagBasedModelTypeProcessor::UntrackEntityForStorageKey( const std::string& storage_key) { DCHECK(model_type_state_.initial_sync_done()); @@ -498,12 +486,7 @@ // Look-up the client tag hash. auto iter = storage_key_to_tag_hash_.find(storage_key); if (iter == storage_key_to_tag_hash_.end()) { - // TODO(jkrcal): Add metrics keyed by the model_type to see which model_type - // violates the proper behavior expected here (https://crbug.com/847822). - // That's unusual, but not necessarily a bad thing. // Missing is as good as untracked as far as the model is concerned. - DLOG(WARNING) << "Attempted to untrack missing item with storage_key: " - << storage_key; return; } @@ -511,6 +494,16 @@ storage_key_to_tag_hash_.erase(iter); } +void ClientTagBasedModelTypeProcessor::UntrackEntityForClientTagHash( + const std::string& client_tag_hash) { + DCHECK(model_type_state_.initial_sync_done()); + DCHECK(!client_tag_hash.empty()); + // Is a no-op if no entity for |client_tag_hash| is tracked. + DCHECK(GetEntityForTagHash(client_tag_hash) == nullptr || + GetEntityForTagHash(client_tag_hash)->storage_key().empty()); + entities_.erase(client_tag_hash); +} + bool ClientTagBasedModelTypeProcessor::IsEntityUnsynced( const std::string& storage_key) { ProcessorEntityTracker* entity = GetEntityForStorageKey(storage_key);
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.h b/components/sync/model_impl/client_tag_based_model_type_processor.h index 360deef..36d8c19f 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.h +++ b/components/sync/model_impl/client_tag_based_model_type_processor.h
@@ -66,8 +66,9 @@ void UpdateStorageKey(const EntityData& entity_data, const std::string& storage_key, MetadataChangeList* metadata_change_list) override; - void UntrackEntity(const EntityData& entity_data) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; + void UntrackEntityForClientTagHash( + const std::string& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; void OnModelStarting(ModelTypeSyncBridge* bridge) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override;
diff --git a/components/sync/test/fake_server/fake_server.cc b/components/sync/test/fake_server/fake_server.cc index 71c7b81..f13e5b4e 100644 --- a/components/sync/test/fake_server/fake_server.cc +++ b/components/sync/test/fake_server/fake_server.cc
@@ -38,7 +38,6 @@ error_type_(sync_pb::SyncEnums::SUCCESS), alternate_triggered_errors_(false), request_counter_(0), - network_enabled_(true), weak_ptr_factory_(this) { base::ThreadRestrictions::SetIOAllowed(true); loopback_server_storage_ = std::make_unique<base::ScopedTempDir>(); @@ -160,32 +159,20 @@ } void FakeServer::HandleCommand(const std::string& request, - const base::Closure& completion_closure, - int* error_code, - int* response_code, + int* http_response_code, std::string* response) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!network_enabled_) { - *error_code = net::ERR_FAILED; - *response_code = net::ERR_FAILED; - *response = std::string(); - completion_closure.Run(); - return; - } request_counter_++; if (!authenticated_) { - *error_code = 0; - *response_code = net::HTTP_UNAUTHORIZED; + *http_response_code = net::HTTP_UNAUTHORIZED; *response = std::string(); - completion_closure.Run(); return; } sync_pb::ClientToServerResponse response_proto; - *response_code = 200; - *error_code = 0; + *http_response_code = net::HTTP_OK; if (error_type_ != sync_pb::SyncEnums::SUCCESS && ShouldSendTriggeredError()) { response_proto.set_error_code(error_type_); @@ -216,25 +203,23 @@ // before handling those requests. std::unique_ptr<sync_pb::DataTypeProgressMarker> wallet_marker = RemoveWalletProgressMarkerIfExists(&message); - *response_code = + *http_response_code = SendToLoopbackServer(message.SerializeAsString(), response); if (wallet_marker != nullptr) { *message.mutable_get_updates()->add_from_progress_marker() = *wallet_marker; - if (*response_code == net::HTTP_OK) { + if (*http_response_code == net::HTTP_OK) { HandleWalletRequest(message, *wallet_marker, response); } } - if (*response_code == net::HTTP_OK) { + if (*http_response_code == net::HTTP_OK) { InjectClientCommand(response); } - completion_closure.Run(); return; } response_proto.set_store_birthday(loopback_server_->GetStoreBirthday()); *response = response_proto.SerializeAsString(); - completion_closure.Run(); } void FakeServer::HandleWalletRequest( @@ -254,12 +239,10 @@ int FakeServer::SendToLoopbackServer(const std::string& request, std::string* response) { - int64_t response_code; - syncer::HttpResponse::ServerConnectionCode server_status; + int http_response_code; base::ThreadRestrictions::SetIOAllowed(true); - loopback_server_->HandleCommand(request, &server_status, &response_code, - response); - return static_cast<int>(response_code); + loopback_server_->HandleCommand(request, &http_response_code, response); + return http_response_code; } void FakeServer::InjectClientCommand(std::string* response) { @@ -447,16 +430,6 @@ observer.OnCommit(committer_id, committed_model_types); } -void FakeServer::EnableNetwork() { - DCHECK(thread_checker_.CalledOnValidThread()); - network_enabled_ = true; -} - -void FakeServer::DisableNetwork() { - DCHECK(thread_checker_.CalledOnValidThread()); - network_enabled_ = false; -} - void FakeServer::EnableStrongConsistencyWithConflictDetectionModel() { DCHECK(thread_checker_.CalledOnValidThread()); loopback_server_->EnableStrongConsistencyWithConflictDetectionModel();
diff --git a/components/sync/test/fake_server/fake_server.h b/components/sync/test/fake_server/fake_server.h index 0e7a891..a39948be 100644 --- a/components/sync/test/fake_server/fake_server.h +++ b/components/sync/test/fake_server/fake_server.h
@@ -12,7 +12,6 @@ #include <string> #include <vector> -#include "base/callback.h" #include "base/files/scoped_temp_dir.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" @@ -55,15 +54,11 @@ FakeServer(); ~FakeServer() override; - // Handles a /command POST (with the given |request|) to the server. Three - // output arguments, |error_code|, |response_code|, and |response|, are used - // to pass data back to the caller. The command has failed if the value - // pointed to by |error_code| is nonzero. |completion_closure| will be called - // immediately before return. + // Handles a /command POST (with the given |request|) to the server. Two + // output arguments, |http_response_code|, and |response|, are used + // to pass data back to the caller. void HandleCommand(const std::string& request, - const base::Closure& completion_closure, - int* error_code, - int* response_code, + int* http_response_code, std::string* response); // Helpers for fetching the last Commit or GetUpdates messages, respectively. @@ -170,13 +165,6 @@ // must be called if AddObserver was ever called with |observer|. void RemoveObserver(Observer* observer); - // Undoes the effects of DisableNetwork. - void EnableNetwork(); - - // Forces every request to fail in a way that simulates a network failure. - // This can be used to trigger exponential backoff in the client. - void DisableNetwork(); - // Enables strong consistency model (i.e. server detects conflicts). void EnableStrongConsistencyWithConflictDetectionModel(); @@ -241,10 +229,6 @@ // FakeServer's observers. base::ObserverList<Observer, true>::Unchecked observers_; - // When true, the server operates normally. When false, a failure is returned - // on every request. This is used to simulate a network failure on the client. - bool network_enabled_; - // The last received client to server messages. sync_pb::ClientToServerMessage last_commit_message_; sync_pb::ClientToServerMessage last_getupdates_message_;
diff --git a/components/sync/test/fake_server/fake_server_http_post_provider.cc b/components/sync/test/fake_server/fake_server_http_post_provider.cc index c023861..e74a7de 100644 --- a/components/sync/test/fake_server/fake_server_http_post_provider.cc +++ b/components/sync/test/fake_server/fake_server_http_post_provider.cc
@@ -4,6 +4,8 @@ #include "components/sync/test/fake_server/fake_server_http_post_provider.h" +#include <utility> + #include "base/bind.h" #include "base/location.h" #include "base/time/time.h" @@ -14,6 +16,19 @@ namespace fake_server { +// static +bool FakeServerHttpPostProvider::network_enabled_ = true; + +namespace { + +void RunAndSignal(base::OnceClosure task, + base::WaitableEvent* completion_event) { + std::move(task).Run(); + completion_event->Signal(); +} + +} // namespace + FakeServerHttpPostProviderFactory::FakeServerHttpPostProviderFactory( const base::WeakPtr<FakeServer>& fake_server, scoped_refptr<base::SequencedTaskRunner> fake_server_task_runner) @@ -64,28 +79,37 @@ request_content_.assign(content, content_length); } -bool FakeServerHttpPostProvider::MakeSynchronousPost(int* error_code, - int* response_code) { +bool FakeServerHttpPostProvider::MakeSynchronousPost(int* net_error_code, + int* http_response_code) { + if (!network_enabled_) { + response_.clear(); + *net_error_code = net::ERR_INTERNET_DISCONNECTED; + *http_response_code = 0; + return false; + } + // It is assumed that a POST is being made to /command. - int post_error_code = -1; int post_response_code = -1; std::string post_response; base::WaitableEvent post_complete( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Closure signal_closure = base::Bind(&base::WaitableEvent::Signal, - base::Unretained(&post_complete)); bool result = fake_server_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&FakeServer::HandleCommand, fake_server_, - base::ConstRef(request_content_), - base::ConstRef(signal_closure), &post_error_code, - &post_response_code, &post_response)); + base::BindOnce(&RunAndSignal, + base::BindOnce(&FakeServer::HandleCommand, fake_server_, + base::ConstRef(request_content_), + &post_response_code, &post_response), + base::Unretained(&post_complete))); - if (!result) + if (!result) { + response_.clear(); + *net_error_code = net::ERR_UNEXPECTED; + *http_response_code = 0; return false; + } // Note: This is a potential deadlock. Here we're on the sync thread, and // we're waiting for something to happen on the UI thread (where the @@ -94,16 +118,16 @@ // just give up after a few seconds. // TODO(crbug.com/869404): Maybe the FakeServer should live on its own thread. if (!post_complete.TimedWait(base::TimeDelta::FromSeconds(5))) { - *error_code = net::ERR_TIMED_OUT; + *net_error_code = net::ERR_TIMED_OUT; return false; } - post_error_code_ = post_error_code; - post_response_code_ = post_response_code; + + // Zero means success. + *net_error_code = 0; + *http_response_code = post_response_code; response_ = post_response; - *error_code = post_error_code_; - *response_code = post_response_code_; - return *error_code == 0; + return true; } int FakeServerHttpPostProvider::GetResponseContentLength() const { @@ -121,4 +145,12 @@ void FakeServerHttpPostProvider::Abort() {} +void FakeServerHttpPostProvider::DisableNetwork() { + network_enabled_ = false; +} + +void FakeServerHttpPostProvider::EnableNetwork() { + network_enabled_ = true; +} + } // namespace fake_server
diff --git a/components/sync/test/fake_server/fake_server_http_post_provider.h b/components/sync/test/fake_server/fake_server_http_post_provider.h index 7dc11a38..65a6ce52 100644 --- a/components/sync/test/fake_server/fake_server_http_post_provider.h +++ b/components/sync/test/fake_server/fake_server_http_post_provider.h
@@ -34,19 +34,29 @@ void SetPostPayload(const char* content_type, int content_length, const char* content) override; - bool MakeSynchronousPost(int* error_code, int* response_code) override; + bool MakeSynchronousPost(int* net_error_code, + int* http_response_code) override; void Abort() override; int GetResponseContentLength() const override; const char* GetResponseContent() const override; const std::string GetResponseHeaderValue( const std::string& name) const override; + // Forces every request to fail in a way that simulates a network failure. + // This can be used to trigger exponential backoff in the client. + static void DisableNetwork(); + + // Undoes the effects of DisableNetwork. + static void EnableNetwork(); + protected: ~FakeServerHttpPostProvider() override; private: friend class base::RefCountedThreadSafe<FakeServerHttpPostProvider>; + static bool network_enabled_; + // |fake_server_| should only be dereferenced on the same thread as // |fake_server_task_runner_| runs on. base::WeakPtr<FakeServer> fake_server_; @@ -58,8 +68,6 @@ std::string request_content_; std::string request_content_type_; std::string extra_request_headers_; - int post_error_code_; - int post_response_code_; DISALLOW_COPY_AND_ASSIGN(FakeServerHttpPostProvider); };
diff --git a/components/test/BUILD.gn b/components/test/BUILD.gn index a468e55..2855473 100644 --- a/components/test/BUILD.gn +++ b/components/test/BUILD.gn
@@ -58,26 +58,4 @@ deps = [ ":test_support", ] - - if (enable_basic_printing) { - defines = [ "HAS_SERVICE_IN_UNIT_TEST" ] - deps += [ - ":components_unittests_catalog_source", - "//services/catalog:lib", - ] - } -} - -if (enable_basic_printing) { - # There is only one service in catalog, which depends on printing feature. - # When more services are added, the condition can be moved inside of catalog. - catalog("components_unittests_catalog") { - embedded_services = [ "//components/services/pdf_compositor:pdf_compositor_service_unittest_manifest" ] - } - - catalog_cpp_source("components_unittests_catalog_source") { - testonly = true - catalog = ":components_unittests_catalog" - generated_function_name = "components::CreateUnittestsCatalog" - } }
diff --git a/components/test/run_all_unittests.cc b/components/test/run_all_unittests.cc index fca628c6..92af0b5 100644 --- a/components/test/run_all_unittests.cc +++ b/components/test/run_all_unittests.cc
@@ -4,18 +4,6 @@ #include "components/test/components_test_suite.h" -#if defined(HAS_SERVICE_IN_UNIT_TEST) -#include "components/test/components_unittests_catalog_source.h" // nogncheck -#include "services/catalog/catalog.h" // nogncheck -#endif - int main(int argc, char** argv) { - // GetLaunchCallback() sets up the environment needed by Catalog. - base::RunTestSuiteCallback callback = GetLaunchCallback(argc, argv); -#if defined(HAS_SERVICE_IN_UNIT_TEST) - catalog::Catalog::SetDefaultCatalogManifest( - components::CreateUnittestsCatalog()); -#endif - - return base::LaunchUnitTests(argc, argv, std::move(callback)); + return base::LaunchUnitTests(argc, argv, GetLaunchCallback(argc, argv)); }
diff --git a/components/tracing/common/tracing_messages.cc b/components/tracing/common/tracing_messages.cc index f4e4105..5593d8a 100644 --- a/components/tracing/common/tracing_messages.cc +++ b/components/tracing/common/tracing_messages.cc
@@ -18,14 +18,6 @@ #error "Failed to include components/tracing/common/tracing_messages.h" #endif -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef COMPONENTS_TRACING_COMMON_TRACING_MESSAGES_H_ -#include "components/tracing/common/tracing_messages.h" -#ifndef COMPONENTS_TRACING_COMMON_TRACING_MESSAGES_H_ -#error "Failed to include components/tracing/common/tracing_messages.h" -#endif - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 97f10dc..2fb9491b 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -515,14 +515,28 @@ } // The ResourceDispatcherHostImpl can be null in unit tests. - if (!intercepted && ResourceDispatcherHostImpl::Get()) { - ResourceDispatcherHostImpl::Get()->BeginNavigationRequest( + ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); + if (!intercepted && rdh) { + rdh->BeginNavigationRequest( resource_context_, url_request_context_getter->GetURLRequestContext(), upload_file_system_context, *request_info_, std::move(navigation_ui_data_), std::move(url_loader_client), std::move(url_loader), service_worker_navigation_handle_core, appcache_handle_core, options, resource_request_->priority, global_request_id_); + + if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) { + // Get the SWProviderHost for non-S13nSW path. For S13nSW path, + // |service_worker_provider_host_| must be set in + // CreateServiceWorkerInterceptor(). + net::URLRequest* url_request = rdh->GetURLRequest(global_request_id_); + ServiceWorkerProviderHost* service_worker_provider_host = + ServiceWorkerRequestHandler::GetProviderHost(url_request); + if (service_worker_provider_host) { + service_worker_provider_host_ = + service_worker_provider_host->AsWeakPtr(); + } + } } // TODO(arthursonzogni): Detect when the ResourceDispatcherHost didn't @@ -1376,6 +1390,17 @@ new_interceptors; new_interceptors.push_back(std::move(interceptors_[i])); new_interceptors.swap(interceptors_); + if (service_worker_provider_host_) { + // Reset the state of ServiceWorkerProviderHost. + // Currently we don't support Service Worker in Signed Exchange + // pages. The page will not be controlled by service workers. And + // Service Worker related APIs will fail with NoDocumentURL error. + // TODO(crbug/898733): Support SignedExchange loading and Service + // Worker integration. + service_worker_provider_host_->SetControllerRegistration( + nullptr, false /* notify_controllerchange */); + service_worker_provider_host_->UpdateURLs(GURL(), GURL()); + } } return true; } @@ -1391,8 +1416,8 @@ std::unique_ptr<NavigationLoaderInterceptor> CreateServiceWorkerInterceptor( const NavigationRequestInfo& request_info, - ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core) - const { + ServiceWorkerNavigationHandleCore* + service_worker_navigation_handle_core) { const ResourceType resource_type = request_info.is_main_frame ? RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME; @@ -1408,7 +1433,7 @@ request_info.begin_params->skip_service_worker, resource_type, request_info.begin_params->request_context_type, frame_type, request_info.are_ancestors_secure, request_info.common_params.post_data, - web_contents_getter_); + web_contents_getter_, &service_worker_provider_host_); } std::unique_ptr<SignedExchangeRequestHandler> @@ -1543,6 +1568,10 @@ // If true, redirect checks will be handled in a proxy, and not here. bool bypass_redirect_checks_; + // Used to reset the state of ServiceWorkerProviderHost when + // SignedExchangeRequestHandler will handle the response. + base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_; + mutable base::WeakPtrFactory<URLLoaderRequestController> weak_factory_; DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
diff --git a/content/browser/net/reporting_service_proxy.cc b/content/browser/net/reporting_service_proxy.cc index f661d32..90176c2 100644 --- a/content/browser/net/reporting_service_proxy.cc +++ b/content/browser/net/reporting_service_proxy.cc
@@ -107,23 +107,24 @@ void QueueFeaturePolicyViolationReport( const GURL& url, - const std::string& policy, + const std::string& policy_id, const std::string& disposition, - const std::string& message, + const base::Optional<std::string>& message, const base::Optional<std::string>& source_file, int line_number, int column_number) override { auto body = std::make_unique<base::DictionaryValue>(); - body->SetString("policy", policy); + body->SetString("policyId", policy_id); body->SetString("disposition", disposition); - body->SetString("message", message); + if (message) + body->SetString("message", *message); if (source_file) body->SetString("sourceFile", *source_file); if (line_number) body->SetInteger("lineNumber", line_number); if (column_number) body->SetInteger("columnNumber", column_number); - QueueReport(url, "default", "feature-policy", std::move(body)); + QueueReport(url, "default", "feature-policy-violation", std::move(body)); } private:
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 0bc52c66..2a10c1f 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -412,6 +412,21 @@ return std::make_unique<video_capture::ServiceImpl>(std::move(request)); } +void CreateInProcessAudioService( + scoped_refptr<base::SequencedTaskRunner> task_runner, + service_manager::mojom::ServiceRequest request) { + // TODO(https://crbug.com/853254): Remove BrowserMainLoop::GetAudioManager(). + task_runner->PostTask( + FROM_HERE, base::BindOnce( + [](media::AudioManager* audio_manager, + service_manager::mojom::ServiceRequest request) { + service_manager::Service::RunUntilTermination( + audio::CreateEmbeddedService(audio_manager, + std::move(request))); + }, + BrowserMainLoop::GetAudioManager(), std::move(request))); +} + #if defined(OS_LINUX) void CreateFontService(service_manager::mojom::ServiceRequest request) { // The font service owns itself here, deleting on self-termination. @@ -594,6 +609,9 @@ packaged_services_connection_ = ServiceManagerConnection::Create(std::move(packaged_services_request), service_manager_thread_task_runner_); + packaged_services_connection_->SetDefaultServiceRequestHandler( + base::BindRepeating(&ServiceManagerContext::OnUnhandledServiceRequest, + weak_ptr_factory_.GetWeakPtr())); service_manager::mojom::ServicePtr root_browser_service; ServiceManagerConnection::SetForProcess( @@ -748,18 +766,10 @@ out_of_process_services[audio::mojom::kServiceName] = base::BindRepeating(&base::ASCIIToUTF16, "Audio Service"); } else { - service_manager::EmbeddedServiceInfo info; - // TODO(hanxi): Removes BrowserMainLoop::GetAudioManager(). - // https://crbug.com/853254. - info.factory = - base::BindRepeating([]() -> std::unique_ptr<service_manager::Service> { - return audio::CreateEmbeddedService( - BrowserMainLoop::GetAudioManager()); - }); - info.task_runner = GetAudioServiceRunner(); - DCHECK(info.task_runner); - packaged_services_connection_->AddEmbeddedService( - audio::mojom::kServiceName, info); + packaged_services_connection_->AddServiceRequestHandler( + audio::mojom::kServiceName, + base::BindRepeating(&CreateInProcessAudioService, + base::WrapRefCounted(GetAudioServiceRunner()))); } if (features::IsVideoCaptureServiceEnabledForOutOfProcess()) { @@ -876,4 +886,11 @@ return (*instance).get(); } +void ServiceManagerContext::OnUnhandledServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { + GetContentClient()->browser()->HandleServiceRequest(service_name, + std::move(request)); +} + } // namespace content
diff --git a/content/browser/service_manager/service_manager_context.h b/content/browser/service_manager/service_manager_context.h index eebd74a0..42c21ea 100644 --- a/content/browser/service_manager/service_manager_context.h +++ b/content/browser/service_manager/service_manager_context.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "content/common/content_export.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace base { class DeferredSequencedTaskRunner; @@ -53,10 +54,15 @@ private: class InProcessServiceManagerContext; + void OnUnhandledServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request); + scoped_refptr<base::SingleThreadTaskRunner> service_manager_thread_task_runner_; scoped_refptr<InProcessServiceManagerContext> in_process_context_; std::unique_ptr<ServiceManagerConnection> packaged_services_connection_; + base::WeakPtrFactory<ServiceManagerContext> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ServiceManagerContext); };
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index 6ffca45..e7b2eda 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -271,10 +271,24 @@ void ServiceWorkerNavigationLoader::CommitResponseBodyEmpty() { TransitionToStatus(Status::kSentBody); - mojo::DataPipe pipe; - url_loader_client_->OnStartLoadingResponseBody( - std::move(pipe.consumer_handle)); - // pipe.producer_handle is closed here. + + // TODO(arthursonzogni): As soon as https://crbug.com/905779 is fixed, switch + // back to using mojo::DataPipe instead of creating it manually. + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; + // Cannot use 0, because this means "default" in + // mojo::core::Core::CreateDataPipe. + options.element_num_bytes = 1; + options.capacity_num_bytes = 1; + mojo::ScopedDataPipeProducerHandle producer_handle; + mojo::ScopedDataPipeConsumerHandle consumer_handle; + MojoResult result = + CreateDataPipe(&options, &producer_handle, &consumer_handle); + CHECK_EQ(MOJO_RESULT_OK, result); + + producer_handle.reset(); // The data pipe is empty. + url_loader_client_->OnStartLoadingResponseBody(std::move(consumer_handle)); } void ServiceWorkerNavigationLoader::CommitCompleted(int error_code,
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc index d325b6c..88f7bdf 100644 --- a/content/browser/service_worker/service_worker_request_handler.cc +++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -146,7 +146,8 @@ network::mojom::RequestContextFrameType frame_type, bool is_parent_frame_secure, scoped_refptr<network::ResourceRequestBody> body, - base::RepeatingCallback<WebContents*()> web_contents_getter) { + base::RepeatingCallback<WebContents*()> web_contents_getter, + base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host) { DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled()); DCHECK(navigation_handle_core); @@ -165,22 +166,22 @@ return nullptr; // Initialize the SWProviderHost. - base::WeakPtr<ServiceWorkerProviderHost> provider_host = - ServiceWorkerProviderHost::PreCreateNavigationHost( - context->AsWeakPtr(), is_parent_frame_secure, - std::move(web_contents_getter)); + *out_provider_host = ServiceWorkerProviderHost::PreCreateNavigationHost( + context->AsWeakPtr(), is_parent_frame_secure, + std::move(web_contents_getter)); std::unique_ptr<ServiceWorkerRequestHandler> handler( - provider_host->CreateRequestHandler( - network::mojom::FetchRequestMode::kNavigate, - network::mojom::FetchCredentialsMode::kInclude, - network::mojom::FetchRedirectMode::kManual, - std::string() /* integrity */, false /* keepalive */, resource_type, - request_context_type, frame_type, blob_storage_context->AsWeakPtr(), - body, skip_service_worker)); + (*out_provider_host) + ->CreateRequestHandler( + network::mojom::FetchRequestMode::kNavigate, + network::mojom::FetchCredentialsMode::kInclude, + network::mojom::FetchRedirectMode::kManual, + std::string() /* integrity */, false /* keepalive */, + resource_type, request_context_type, frame_type, + blob_storage_context->AsWeakPtr(), body, skip_service_worker)); navigation_handle_core->DidPreCreateProviderHost( - provider_host->provider_id()); + (*out_provider_host)->provider_id()); return base::WrapUnique<NavigationLoaderInterceptor>(handler.release()); }
diff --git a/content/browser/service_worker/service_worker_request_handler.h b/content/browser/service_worker/service_worker_request_handler.h index 09c0d51..260941d 100644 --- a/content/browser/service_worker/service_worker_request_handler.h +++ b/content/browser/service_worker/service_worker_request_handler.h
@@ -81,7 +81,8 @@ network::mojom::RequestContextFrameType frame_type, bool is_parent_frame_secure, scoped_refptr<network::ResourceRequestBody> body, - base::RepeatingCallback<WebContents*()> web_contents_getter); + base::RepeatingCallback<WebContents*()> web_contents_getter, + base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host); static std::unique_ptr<NavigationLoaderInterceptor> InitializeForSharedWorker( const network::ResourceRequest& resource_request,
diff --git a/content/browser/service_worker/service_worker_request_handler_unittest.cc b/content/browser/service_worker/service_worker_request_handler_unittest.cc index 8bf8f7e..59973c9c 100644 --- a/content/browser/service_worker/service_worker_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -169,6 +169,7 @@ bool expected_handler_created) { std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core = CreateNavigationHandleCore(helper_->context_wrapper()); + base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host; std::unique_ptr<NavigationLoaderInterceptor> interceptor = ServiceWorkerRequestHandler::InitializeForNavigationNetworkService( GURL(url), nullptr /* resource_context */, @@ -177,7 +178,8 @@ blink::mojom::RequestContextType::HYPERLINK, network::mojom::RequestContextFrameType::kTopLevel, true /* is_parent_frame_secure */, nullptr /* body */, - base::RepeatingCallback<WebContents*(void)>()); + base::RepeatingCallback<WebContents*(void)>(), + &service_worker_provider_host); return !!interceptor.get(); }
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index 1fb4c24..f3e4a6b 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -49,6 +49,7 @@ #include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/service_worker/service_worker_utils.h" namespace content { @@ -522,7 +523,8 @@ enum class SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam { kLegacy, - kServiceWorkerServicification + kServiceWorkerServicification, + kNetworkService }; class SignedExchangeRequestHandlerWithServiceWorkerBrowserTest @@ -532,14 +534,23 @@ public: SignedExchangeRequestHandlerWithServiceWorkerBrowserTest() = default; void SetUp() override { - if (GetParam() == - SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam :: - kServiceWorkerServicification) { - feature_list_.InitWithFeatures( - {blink::features::kServiceWorkerServicification}, {}); - } else { - feature_list_.InitWithFeatures( - {}, {blink::features::kServiceWorkerServicification}); + switch (GetParam()) { + case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: + kLegacy: + feature_list_.InitWithFeatures( + {}, {blink::features::kServiceWorkerServicification, + network::features::kNetworkService}); + break; + case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: + kServiceWorkerServicification: + feature_list_.InitWithFeatures( + {blink::features::kServiceWorkerServicification}, + {network::features::kNetworkService}); + break; + case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: + kNetworkService: + feature_list_.InitAndEnableFeature(network::features::kNetworkService); + break; } SignedExchangeRequestHandlerBrowserTestBase::SetUp(); } @@ -551,16 +562,11 @@ SignedExchangeRequestHandlerWithServiceWorkerBrowserTest); }; -INSTANTIATE_TEST_CASE_P( - SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, - SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, - testing::Values( - SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::kLegacy, - SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: - kServiceWorkerServicification)); - IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, - Simple) { + LogicalUrlInServiceWorkerScope) { + // SW-scope: https://test.example.org/test/ + // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg + // SXG logical URL: https://test.example.org/test/ InstallUrlInterceptor( GURL("https://cert.example.org/cert.msg"), "content/test/data/sxg/test.example.org.public.pem.cbor"); @@ -589,9 +595,134 @@ TitleWatcher title_watcher(shell()->web_contents(), title); title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("Generated")); NavigateToURL(shell(), url); + // The page content shoud be served from the signed exchange. EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); } +IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, + NotControlledByDistributorsSW) { + // SW-scope: http://127.0.0.1:PORT/sxg/ + // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg + // SXG logical URL: https://test.example.org/test/ + InstallUrlInterceptor( + GURL("https://cert.example.org/cert.msg"), + "content/test/data/sxg/test.example.org.public.pem.cbor"); + InstallMockCert(); + embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + + const GURL install_sw_url = embedded_test_server()->GetURL( + "/sxg/no-respond-with-service-worker.html"); + + { + base::string16 title = base::ASCIIToUTF16("Done"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), install_sw_url); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + } + + base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), embedded_test_server()->GetURL( + "/sxg/test.example.org_test.sxg")); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + + // The page must not be controlled by the service worker of the physical URL. + EXPECT_EQ(false, EvalJs(shell(), "!!navigator.serviceWorker.controller")); +} + +IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, + NotControlledBySameOriginDistributorsSW) { + // SW-scope: https://test.example.org/scope/ + // SXG physical URL: https://test.example.org/scope/test.example.org_test.sxg + // SXG logical URL: https://test.example.org/test/ + InstallUrlInterceptor( + GURL("https://cert.example.org/cert.msg"), + "content/test/data/sxg/test.example.org.public.pem.cbor"); + InstallMockCert(); + + InstallUrlInterceptor(GURL("https://test.example.org/scope/test.sxg"), + "content/test/data/sxg/test.example.org_test.sxg"); + + const GURL install_sw_url = GURL( + "https://test.example.org/scope/no-respond-with-service-worker.html"); + + InstallUrlInterceptor( + install_sw_url, + "content/test/data/sxg/no-respond-with-service-worker.html"); + InstallUrlInterceptor( + GURL("https://test.example.org/scope/no-respond-with-service-worker.js"), + "content/test/data/sxg/no-respond-with-service-worker.js"); + + { + base::string16 title = base::ASCIIToUTF16("Done"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), install_sw_url); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + } + + base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), GURL("https://test.example.org/scope/test.sxg")); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + + // The page must not be controlled by the service worker of the physical URL. + EXPECT_EQ(false, EvalJs(shell(), "!!navigator.serviceWorker.controller")); +} + +IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, + RegisterServiceWorkerFromSignedExchange) { + // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg + // SXG logical URL: https://test.example.org/test/ + InstallUrlInterceptor( + GURL("https://cert.example.org/cert.msg"), + "content/test/data/sxg/test.example.org.public.pem.cbor"); + InstallMockCert(); + + InstallUrlInterceptor( + GURL("https://test.example.org/test/publisher-service-worker.js"), + "content/test/data/sxg/publisher-service-worker.js"); + + embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + + GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg"); + + { + base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), url); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + } + + const std::string register_sw_script = + "(async function() {" + " try {" + " const registration = await navigator.serviceWorker.register(" + " 'publisher-service-worker.js', {scope: './'});" + " window.domAutomationController.send(true);" + " } catch (e) {" + " window.domAutomationController.send(false);" + " }" + "})();"; + bool result = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(), + register_sw_script, &result)); + // serviceWorker.register() fails because the document URL of + // ServiceWorkerProviderHost is empty. + EXPECT_FALSE(result); +} + +INSTANTIATE_TEST_CASE_P( + SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, + SignedExchangeRequestHandlerWithServiceWorkerBrowserTest, + testing::Values( + SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::kLegacy, + SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: + kServiceWorkerServicification, + SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam:: + kNetworkService)); + struct SignedExchangeAcceptHeaderBrowserTestParam { SignedExchangeAcceptHeaderBrowserTestParam( bool sxg_enabled,
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index e5720966..cd10d4e5 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -413,6 +413,9 @@ WebRuntimeFeatures::EnableScheduledScriptStreaming( base::FeatureList::IsEnabled(features::kScheduledScriptStreaming)); + WebRuntimeFeatures::EnableScriptStreamingOnPreload( + base::FeatureList::IsEnabled(features::kScriptStreamingOnPreload)); + WebRuntimeFeatures::EnableMergeBlockingNonBlockingPools( base::FeatureList::IsEnabled(base::kMergeBlockingNonBlockingPools));
diff --git a/content/child/service_factory.cc b/content/child/service_factory.cc index 3091031..e0978d26 100644 --- a/content/child/service_factory.cc +++ b/content/child/service_factory.cc
@@ -15,6 +15,8 @@ ServiceFactory::ServiceFactory() {} ServiceFactory::~ServiceFactory() {} +void ServiceFactory::RegisterServices(ServiceMap* service) {} + bool ServiceFactory::HandleServiceRequest( const std::string& name, service_manager::mojom::ServiceRequest request) {
diff --git a/content/child/service_factory.h b/content/child/service_factory.h index 5dae5f7..060ac5d 100644 --- a/content/child/service_factory.h +++ b/content/child/service_factory.h
@@ -29,7 +29,7 @@ ServiceFactory(); ~ServiceFactory() override; - virtual void RegisterServices(ServiceMap* services) = 0; + virtual void RegisterServices(ServiceMap* services); virtual bool HandleServiceRequest( const std::string& name, service_manager::mojom::ServiceRequest request);
diff --git a/content/common/content_message_generator.cc b/content/common/content_message_generator.cc index 2e2b5a6..d1cf116 100644 --- a/content/common/content_message_generator.cc +++ b/content/common/content_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "content/common/content_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "content/common/content_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn index 14ebcf1..d9d707b 100644 --- a/content/gpu/BUILD.gn +++ b/content/gpu/BUILD.gn
@@ -75,6 +75,7 @@ "//components/viz/service/main", "//media/gpu/ipc/service", "//media/mojo/clients:clients", + "//media/mojo/interfaces:constants", "//services/service_manager/embedder", "//services/service_manager/public/cpp", "//services/service_manager/public/mojom",
diff --git a/content/gpu/gpu_service_factory.cc b/content/gpu/gpu_service_factory.cc index c1b474f..07f13ddf 100644 --- a/content/gpu/gpu_service_factory.cc +++ b/content/gpu/gpu_service_factory.cc
@@ -14,6 +14,7 @@ #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) #include "base/bind.h" +#include "media/mojo/interfaces/constants.mojom.h" // nogncheck #include "media/mojo/services/media_service_factory.h" // nogncheck #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "content/public/gpu/content_gpu_client.h" @@ -40,39 +41,57 @@ GpuServiceFactory::~GpuServiceFactory() {} -void GpuServiceFactory::RegisterServices(ServiceMap* services) { +bool GpuServiceFactory::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) - media::CdmProxyFactoryCB cdm_proxy_factory_cb; + if (service_name == media::mojom::kMediaServiceName) { + media::CdmProxyFactoryCB cdm_proxy_factory_cb; #if BUILDFLAG(ENABLE_LIBRARY_CDMS) - cdm_proxy_factory_cb = - base::BindRepeating(&ContentGpuClient::CreateCdmProxy, - base::Unretained(GetContentClient()->gpu())); + cdm_proxy_factory_cb = + base::BindRepeating(&ContentGpuClient::CreateCdmProxy, + base::Unretained(GetContentClient()->gpu())); #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - service_manager::EmbeddedServiceInfo info; - info.factory = base::BindRepeating( - &media::CreateGpuMediaService, gpu_preferences_, gpu_workarounds_, - gpu_feature_info_, task_runner_, media_gpu_channel_manager_, - android_overlay_factory_cb_, std::move(cdm_proxy_factory_cb)); - // This service will host audio/video decoders, and if these decoding - // operations are blocked, user may hear audio glitch or see video freezing, - // hence "user blocking". + // This service will host audio/video decoders, and if these decoding + // operations are blocked, user may hear audio glitch or see video freezing, + // hence "user blocking". + scoped_refptr<base::SingleThreadTaskRunner> task_runner; #if defined(OS_WIN) - // Run everything on the gpu main thread, since that's where the CDM runs. - info.task_runner = task_runner_; + // Run everything on the gpu main thread, since that's where the CDM runs. + task_runner = task_runner_; #else - // TODO(crbug.com/786169): Check whether this needs to be single threaded. - info.task_runner = base::CreateSingleThreadTaskRunnerWithTraits( - {base::TaskPriority::USER_BLOCKING}); + // TODO(crbug.com/786169): Check whether this needs to be single threaded. + task_runner = base::CreateSingleThreadTaskRunnerWithTraits( + {base::TaskPriority::USER_BLOCKING}); #endif // defined(OS_WIN) - services->insert(std::make_pair("media", info)); + + using FactoryCallback = + base::OnceCallback<std::unique_ptr<service_manager::Service>()>; + FactoryCallback factory = base::BindOnce( + &media::CreateGpuMediaService, std::move(request), gpu_preferences_, + gpu_workarounds_, gpu_feature_info_, task_runner_, + media_gpu_channel_manager_, android_overlay_factory_cb_, + std::move(cdm_proxy_factory_cb)); + task_runner->PostTask(FROM_HERE, + base::BindOnce( + [](FactoryCallback factory) { + service_manager::Service::RunUntilTermination( + std::move(factory).Run()); + }, + std::move(factory))); + return true; + } #endif // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) - service_manager::EmbeddedServiceInfo shape_detection_info; - shape_detection_info.factory = - base::Bind(&shape_detection::ShapeDetectionService::Create); - services->insert(std::make_pair(shape_detection::mojom::kServiceName, - shape_detection_info)); + if (service_name == shape_detection::mojom::kServiceName) { + service_manager::Service::RunUntilTermination( + std::make_unique<shape_detection::ShapeDetectionService>( + std::move(request))); + return true; + } + + return true; } } // namespace content
diff --git a/content/gpu/gpu_service_factory.h b/content/gpu/gpu_service_factory.h index a639f34..0c88974 100644 --- a/content/gpu/gpu_service_factory.h +++ b/content/gpu/gpu_service_factory.h
@@ -34,7 +34,9 @@ ~GpuServiceFactory() override; // ServiceFactory overrides: - void RegisterServices(ServiceMap* services) override; + bool HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; private: #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 981da973..918a9af 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -658,6 +658,10 @@ ContentBrowserClient::OutOfProcessServiceInfo::~OutOfProcessServiceInfo() = default; +void ContentBrowserClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) {} + bool ContentBrowserClient::ShouldTerminateOnServiceQuit( const service_manager::Identity& id) { return false;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 030b808..c696f9b 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -979,6 +979,13 @@ // to use for the service's host process when launched. virtual void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) {} + // Handles a Service request for the service named |service_name|. If the + // client knows how to run |service_name|, it should bind |request| + // accordingly. + virtual void HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request); + // Allows the embedder to terminate the browser if a specific service instance // quits or crashes. virtual bool ShouldTerminateOnServiceQuit(
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 5929fdb..e0ccbe7 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -620,6 +620,10 @@ const base::Feature kScheduledScriptStreaming{ "ScheduledScriptStreaming", base::FEATURE_DISABLED_BY_DEFAULT}; +// Start streaming scripts on script preload. +const base::Feature kScriptStreamingOnPreload{ + "ScriptStreamingOnPreload", base::FEATURE_DISABLED_BY_DEFAULT}; + #if defined(OS_ANDROID) // Autofill Accessibility in Android. // crbug.com/627860
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 85e9fa19..13222b41 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -138,6 +138,7 @@ CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases; CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner; CONTENT_EXPORT extern const base::Feature kScheduledScriptStreaming; +CONTENT_EXPORT extern const base::Feature kScriptStreamingOnPreload; #if defined(OS_ANDROID) CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index 980b173..79e404a 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -543,10 +543,24 @@ void ServiceWorkerSubresourceLoader::CommitResponseBodyEmpty() { TransitionToStatus(Status::kSentBody); - mojo::DataPipe pipe; - url_loader_client_->OnStartLoadingResponseBody( - std::move(pipe.consumer_handle)); - // pipe.producer_handle is closed here. + + // TODO(arthursonzogni): As soon as https://crbug.com/905779 is fixed, switch + // back to using mojo::DataPipe instead of creating it manually. + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; + // Cannot use 0, because this means "default" in + // mojo::core::Core::CreateDataPipe. + options.element_num_bytes = 1; + options.capacity_num_bytes = 1; + mojo::ScopedDataPipeProducerHandle producer_handle; + mojo::ScopedDataPipeConsumerHandle consumer_handle; + MojoResult result = + CreateDataPipe(&options, &producer_handle, &consumer_handle); + CHECK_EQ(MOJO_RESULT_OK, result); + + producer_handle.reset(); // The data pipe is empty. + url_loader_client_->OnStartLoadingResponseBody(std::move(consumer_handle)); } void ServiceWorkerSubresourceLoader::CommitCompleted(int error_code) {
diff --git a/content/renderer/web_database_observer_impl.cc b/content/renderer/web_database_observer_impl.cc index 31a64d4..6156b01 100644 --- a/content/renderer/web_database_observer_impl.cc +++ b/content/renderer/web_database_observer_impl.cc
@@ -5,7 +5,6 @@ #include "content/renderer/web_database_observer_impl.h" #include "base/bind.h" -#include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/string16.h" #include "base/threading/thread_task_runner_handle.h" @@ -18,45 +17,6 @@ namespace content { -namespace { - -const int kResultHistogramSize = 50; -const int kCallsiteHistogramSize = 10; -const int kWebSQLSuccess = -1; - -int DetermineHistogramResult(int websql_error, int sqlite_error) { - // If we have a sqlite error, log it after trimming the extended bits. - // There are 26 possible values, but we leave room for some new ones. - if (sqlite_error) - return std::min(sqlite_error & 0xff, 30); - - // Otherwise, websql_error may be an SQLExceptionCode, SQLErrorCode - // or a DOMExceptionCode, or -1 for success. - if (websql_error == kWebSQLSuccess) - return 0; // no error - - // SQLExceptionCode starts at 1000 - if (websql_error >= 1000) - websql_error -= 1000; - - return std::min(websql_error + 30, kResultHistogramSize - 1); -} - -#define UMA_HISTOGRAM_WEBSQL_RESULT(name, callsite, websql_error, sqlite_error) \ - do { \ - DCHECK(callsite < kCallsiteHistogramSize); \ - int result = DetermineHistogramResult(websql_error, sqlite_error); \ - UMA_HISTOGRAM_ENUMERATION("websql.Async." name, \ - result, kResultHistogramSize); \ - if (result) { \ - UMA_HISTOGRAM_ENUMERATION("websql.Async." name ".ErrorSite", \ - callsite, kCallsiteHistogramSize); \ - } \ - } while (0) - - -} // namespace - WebDatabaseObserverImpl::WebDatabaseObserverImpl( scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host) : web_database_host_(std::move(web_database_host)), @@ -71,107 +31,33 @@ const WebString& database_name, const WebString& database_display_name, unsigned long estimated_size) { - GetWebDatabaseHost().Opened(origin, database_name.Utf16(), - database_display_name.Utf16(), estimated_size); + (*web_database_host_) + ->Opened(origin, database_name.Utf16(), database_display_name.Utf16(), + estimated_size); } void WebDatabaseObserverImpl::DatabaseModified(const WebSecurityOrigin& origin, const WebString& database_name) { - GetWebDatabaseHost().Modified(origin, database_name.Utf16()); + (*web_database_host_)->Modified(origin, database_name.Utf16()); } void WebDatabaseObserverImpl::DatabaseClosed(const WebSecurityOrigin& origin, const WebString& database_name) { DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence()); - GetWebDatabaseHost().Closed(origin, database_name.Utf16()); + (*web_database_host_)->Closed(origin, database_name.Utf16()); } -void WebDatabaseObserverImpl::ReportOpenDatabaseResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int callsite, - int websql_error, - int sqlite_error, - base::TimeDelta call_time) { - UMA_HISTOGRAM_WEBSQL_RESULT("OpenResult", callsite, - websql_error, sqlite_error); - HandleSqliteError(origin, database_name, sqlite_error); - - if (websql_error == kWebSQLSuccess && sqlite_error == SQLITE_OK) { - UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success", call_time); - } else { - UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error", call_time); - } -} - -void WebDatabaseObserverImpl::ReportChangeVersionResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) { - UMA_HISTOGRAM_WEBSQL_RESULT("ChangeVersionResult", callsite, - websql_error, sqlite_error); - HandleSqliteError(origin, database_name, sqlite_error); -} - -void WebDatabaseObserverImpl::ReportStartTransactionResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) { - UMA_HISTOGRAM_WEBSQL_RESULT("BeginResult", callsite, - websql_error, sqlite_error); - HandleSqliteError(origin, database_name, sqlite_error); -} - -void WebDatabaseObserverImpl::ReportCommitTransactionResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) { - UMA_HISTOGRAM_WEBSQL_RESULT("CommitResult", callsite, - websql_error, sqlite_error); - HandleSqliteError(origin, database_name, sqlite_error); -} - -void WebDatabaseObserverImpl::ReportExecuteStatementResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) { - UMA_HISTOGRAM_WEBSQL_RESULT("StatementResult", callsite, - websql_error, sqlite_error); - HandleSqliteError(origin, database_name, sqlite_error); -} - -void WebDatabaseObserverImpl::ReportVacuumDatabaseResult( - const WebSecurityOrigin& origin, - const WebString& database_name, - int sqlite_error) { - int result = DetermineHistogramResult(-1, sqlite_error); - UMA_HISTOGRAM_ENUMERATION("websql.Async.VacuumResult", - result, kResultHistogramSize); - HandleSqliteError(origin, database_name, sqlite_error); -} - -void WebDatabaseObserverImpl::HandleSqliteError(const WebSecurityOrigin& origin, +void WebDatabaseObserverImpl::ReportSqliteError(const WebSecurityOrigin& origin, const WebString& database_name, int error) { // We filter out errors which the backend doesn't act on to avoid // a unnecessary ipc traffic, this method can get called at a fairly // high frequency (per-sqlstatement). - if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) { - GetWebDatabaseHost().HandleSqliteError(origin, database_name.Utf16(), - error); - } -} + if (error != SQLITE_CORRUPT && error != SQLITE_NOTADB) + return; -blink::mojom::WebDatabaseHost& WebDatabaseObserverImpl::GetWebDatabaseHost() { - return **web_database_host_; + (*web_database_host_) + ->HandleSqliteError(origin, database_name.Utf16(), error); } } // namespace content
diff --git a/content/renderer/web_database_observer_impl.h b/content/renderer/web_database_observer_impl.h index 74544bc..0ec094d 100644 --- a/content/renderer/web_database_observer_impl.h +++ b/content/renderer/web_database_observer_impl.h
@@ -31,44 +31,11 @@ const blink::WebString& database_name) override; void DatabaseClosed(const blink::WebSecurityOrigin& origin, const blink::WebString& database_name) override; - void ReportOpenDatabaseResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int callsite, - int websql_error, - int sqlite_error, - base::TimeDelta call_time) override; - void ReportChangeVersionResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) override; - void ReportStartTransactionResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) override; - void ReportCommitTransactionResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) override; - void ReportExecuteStatementResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int callsite, - int websql_error, - int sqlite_error) override; - void ReportVacuumDatabaseResult(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int sqlite_error) override; + void ReportSqliteError(const blink::WebSecurityOrigin& origin, + const blink::WebString& database_name, + int error) override; private: - void HandleSqliteError(const blink::WebSecurityOrigin& origin, - const blink::WebString& database_name, - int error); - - // Return the mojo interface for making WebDatabaseHost calls. - blink::mojom::WebDatabaseHost& GetWebDatabaseHost(); - scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index a828f8e0..454bb72 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -197,13 +197,6 @@ void ShellContentBrowserClient::RegisterInProcessServices( StaticServiceMap* services, content::ServiceManagerConnection* connection) { -#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) - { - service_manager::EmbeddedServiceInfo info; - info.factory = base::Bind(&media::CreateMediaServiceForTesting); - services->insert(std::make_pair(media::mojom::kMediaServiceName, info)); - } -#endif #if defined(OS_CHROMEOS) if (features::IsSingleProcessMash()) { service_manager::EmbeddedServiceInfo info; @@ -233,6 +226,17 @@ #endif } +void ShellContentBrowserClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { +#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) + if (service_name == media::mojom::kMediaServiceName) { + service_manager::Service::RunUntilTermination( + media::CreateMediaServiceForTesting(std::move(request))); + } +#endif +} + bool ShellContentBrowserClient::ShouldTerminateOnServiceQuit( const service_manager::Identity& id) { if (should_terminate_on_service_quit_callback_)
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 4df003a..7edf05c6 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -41,6 +41,9 @@ void RegisterInProcessServices(StaticServiceMap* services, ServiceManagerConnection* connection) override; void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; + void HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; bool ShouldTerminateOnServiceQuit( const service_manager::Identity& id) override; std::unique_ptr<base::Value> GetServiceManifestOverlay(
diff --git a/content/shell/common/layout_test/layout_test_messages.cc b/content/shell/common/layout_test/layout_test_messages.cc index 28ba210..2d30b6b 100644 --- a/content/shell/common/layout_test/layout_test_messages.cc +++ b/content/shell/common/layout_test/layout_test_messages.cc
@@ -12,11 +12,6 @@ #undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_ #include "content/shell/common/layout_test/layout_test_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_ -#include "content/shell/common/layout_test/layout_test_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/content/shell/common/shell_messages.cc b/content/shell/common/shell_messages.cc index bc5cbcf..6718c096 100644 --- a/content/shell/common/shell_messages.cc +++ b/content/shell/common/shell_messages.cc
@@ -12,11 +12,6 @@ #undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_ #include "content/shell/common/shell_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_ -#include "content/shell/common/shell_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/content/test/data/browsing_data/media_license.html b/content/test/data/browsing_data/media_license.html deleted file mode 100644 index 251f6fe..0000000 --- a/content/test/data/browsing_data/media_license.html +++ /dev/null
@@ -1,81 +0,0 @@ -<html> -<script> - - function success_() { - domAutomationController.send(true); - } - - function failure_() { - domAutomationController.send(false); - } - - // EME creates session IDs dynamically, so we have no idea what it will be. - // As the tests only need to create a single session, keep track of the - // last session ID created. - var savedSessionId = 'unknown'; - - function createPersistentSession() { - // This function creates a persistent-license type session, and resolves - // with the created session object on success. - return navigator.requestMediaKeySystemAccess( - 'org.chromium.externalclearkey', [{ - initDataTypes: ['keyids'], - audioCapabilities: [ - // Include a set of codecs that should cover all user agents. - {contentType: 'audio/mp4; codecs="mp4a.40.2"'}, - {contentType: 'audio/webm; codecs="opus"'} - ], - persistentState: 'required', - sessionTypes: ['persistent-license'], - }]) - .then(function(access) { - return access.createMediaKeys(); - }) - .then(function(mediaKeys) { - return mediaKeys.createSession('persistent-license'); - }); - } - - function handleMessageEvent(e) { - var session = e.target; - var te = new TextEncoder(); - var license = te.encode( - '{"keys":[{"kty":"oct","k":"tQ0bJVWb6b0KPL6KtZIy_A","kid":"LwVHf8JLtPrv2GUXFW2v_A"}],"type":"persistent-license"}'); - - savedSessionId = session.sessionId; - session.update(license).then(success_, failure_); - } - - function setMediaLicense() { - var te = new TextEncoder(); - var initData = te.encode('{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}'); - - createPersistentSession().then(function(session) { - // generateRequest() will trigger a 'message' event, which we need to - // wait for in order to call update() which provides the license. - session.addEventListener('message', handleMessageEvent, false); - return session.generateRequest('keyids', initData); - }) - // Success is reported from handleMessageEvent(). - .catch(failure_); - } - - function hasMediaLicense() { - createPersistentSession().then(function(session) { - return session.load(savedSessionId); - }) - .then(function(result) { - // |result| is a boolean, indicating if the session was loaded or not. - domAutomationController.send(result); - }) - .catch(failure_); - } -</script> - -<body> - This page is used to test creation and deletion of Media Licenses. - The functions are called from BrowsingDataRemoverBrowserTest::HasDataForType - and BrowsingDataRemoverBrowserTest::SetDataForType. -</body> - -</html> \ No newline at end of file
diff --git a/content/test/data/sxg/no-respond-with-service-worker.html b/content/test/data/sxg/no-respond-with-service-worker.html new file mode 100644 index 0000000..120b716 --- /dev/null +++ b/content/test/data/sxg/no-respond-with-service-worker.html
@@ -0,0 +1,13 @@ +<script> +async function register(script, scope) { + const registration = await navigator.serviceWorker.register( + script, {scope: scope}); + await new Promise(resolve => + registration.installing.addEventListener('statechange', resolve)); +} +async function initialize() { + await register('no-respond-with-service-worker.js', './'); + document.title = 'Done'; +} +initialize(); +</script>
diff --git a/content/test/data/sxg/no-respond-with-service-worker.js b/content/test/data/sxg/no-respond-with-service-worker.js new file mode 100644 index 0000000..1ee6404 --- /dev/null +++ b/content/test/data/sxg/no-respond-with-service-worker.js
@@ -0,0 +1,6 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +self.addEventListener('fetch', (event) => { +});
diff --git a/content/test/data/sxg/no-respond-with-service-worker.js.mock-http-headers b/content/test/data/sxg/no-respond-with-service-worker.js.mock-http-headers new file mode 100644 index 0000000..31aa790 --- /dev/null +++ b/content/test/data/sxg/no-respond-with-service-worker.js.mock-http-headers
@@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +Content-Type: application/javascript
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index f14201b5..7ee6337 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -101,10 +101,6 @@ #endif // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) }; -std::unique_ptr<service_manager::Service> CreateCdmService() { - return std::unique_ptr<service_manager::Service>( - new ::media::CdmService(std::make_unique<ContentCdmServiceClient>())); -} #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) std::unique_ptr<service_manager::Service> CreateVizService() { @@ -134,16 +130,6 @@ GetContentClient()->utility()->RegisterServices(services); GetContentClient()->utility()->RegisterAudioBinders(audio_registry_.get()); - service_manager::EmbeddedServiceInfo audio_info; - audio_info.factory = base::BindRepeating( - &UtilityServiceFactory::CreateAudioService, base::Unretained(this)); - services->insert(std::make_pair(audio::mojom::kServiceName, audio_info)); - -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) - service_manager::EmbeddedServiceInfo info; - info.factory = base::Bind(&CreateCdmService); - services->emplace(media::mojom::kCdmServiceName, info); -#endif #if defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) @@ -176,7 +162,9 @@ bool UtilityServiceFactory::HandleServiceRequest( const std::string& name, service_manager::mojom::ServiceRequest request) { - if (name == data_decoder::mojom::kServiceName) { + if (name == audio::mojom::kServiceName) { + running_service_ = CreateAudioService(std::move(request)); + } else if (name == data_decoder::mojom::kServiceName) { content::UtilityThread::Get()->EnsureBlinkInitialized(); running_service_ = std::make_unique<data_decoder::DataDecoderService>(std::move(request)); @@ -184,6 +172,12 @@ running_service_ = std::make_unique<video_capture::ServiceImpl>(std::move(request)); } +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + else if (name == media::mojom::kCdmServiceName) { + running_service_ = std::make_unique<media::CdmService>( + std::make_unique<ContentCdmServiceClient>(), std::move(request)); + } +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) if (!running_service_) { running_service_ = GetContentClient()->utility()->HandleServiceRequest( @@ -219,7 +213,8 @@ } std::unique_ptr<service_manager::Service> -UtilityServiceFactory::CreateAudioService() { +UtilityServiceFactory::CreateAudioService( + service_manager::mojom::ServiceRequest request) { #if defined(OS_MACOSX) // Don't connect to launch services when running sandboxed // (https://crbug.com/874785). @@ -229,7 +224,8 @@ } #endif - return audio::CreateStandaloneService(std::move(audio_registry_)); + return audio::CreateStandaloneService(std::move(audio_registry_), + std::move(request)); } } // namespace content
diff --git a/content/utility/utility_service_factory.h b/content/utility/utility_service_factory.h index ff278d4..bd91e16 100644 --- a/content/utility/utility_service_factory.h +++ b/content/utility/utility_service_factory.h
@@ -37,7 +37,8 @@ void OnLoadFailed() override; std::unique_ptr<service_manager::Service> CreateNetworkService(); - std::unique_ptr<service_manager::Service> CreateAudioService(); + std::unique_ptr<service_manager::Service> CreateAudioService( + service_manager::mojom::ServiceRequest request); // Allows embedders to register their interface implementations before the // network or audio services are created. Used for testing.
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index 9064e7e7..694df67 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -2,6 +2,9 @@ [TOC] +Note: See [Threading and Tasks FAQ](threading_and_tasks_faq.md) for more +examples. + ## Overview Chromium is a very multithreaded product. We try to keep the UI as responsive as @@ -77,7 +80,7 @@ bug to use base::CreateSequencedTaskRunnerWithTraits() when fixed). Detailed documentation on how to migrate from single-threaded contexts to -sequenced contexts can be found [here](threading_and_tasks_faq.md#How-can-I-migrate-from-SingleThreadTaskRunner-to-SequencedTaskRunner_). +sequenced contexts can be found [here](threading_and_tasks_faq.md#How-to-migrate-from-SingleThreadTaskRunner-to-SequencedTaskRunner). The discussion below covers all of these ways to execute tasks in details. @@ -677,3 +680,6 @@ Note that this still allows removing all layers of plumbing between //chrome and that component since unit tests will use the leaf layer directly. + +## FAQ +See [Threading and Tasks FAQ](threading_and_tasks_faq.md) for more examples.
diff --git a/docs/threading_and_tasks_faq.md b/docs/threading_and_tasks_faq.md index cd405d81..ac918435 100644 --- a/docs/threading_and_tasks_faq.md +++ b/docs/threading_and_tasks_faq.md
@@ -2,9 +2,12 @@ [TOC] +Note: Make sure to read the main [Threading and Tasks](threading_and_tasks.md) +docs first. + ## General -### On what thread will a task run? +### On which thread will a task run? A task is posted through the `base/task/post_task.h` API with `TaskTraits`. @@ -19,13 +22,13 @@ `CreateSingleThreadTaskRunnerWithTraits(..., mode)`: * Where `mode` is `SingleThreadTaskRunnerThreadMode::DEDICATED`: * The task runs on a thread that only runs tasks from that - SingleThreadTaskRunner. This is not the main thread or the IO + SingleThreadTaskRunner. This is not the main thread nor the IO thread. * Where `mode` is `SingleThreadTaskRunnerThreadMode::SHARED`: * The task runs on a thread that runs tasks from one or many unrelated SingleThreadTaskRunners. This is not the main thread - or the IO thread. + nor the IO thread. * Otherwise: * The task runs in a thread pool. @@ -34,7 +37,7 @@ tasks should generally run on a sequence in a thread pool rather than on a dedicated thread. -## Blocking off-CPU +## Making blocking calls (which do not use the CPU) ### How to make a blocking call without preventing other tasks from being scheduled? @@ -42,7 +45,7 @@ If the task runs in a thread pool: -* Annotate the scope that may block off-CPU with +* Annotate the scope that may block with `ScopedBlockingCall(BlockingType::MAY_BLOCK/WILL_BLOCK)`. A few milliseconds after the annotated scope is entered, the capacity of the thread pool is incremented. This ensures that your task doesn't reduce the number of tasks @@ -58,15 +61,16 @@ If the task runs on a `DEDICATED SingleThreadTaskRunner`: -* Annotate the scope that may block off-CPU with +* Annotate the scope that may block with `ScopedBlockingCall(BlockingType::MAY_BLOCK/WILL_BLOCK)`. The annotation is a - no-op that documents the blocking behavior. Tasks posted to the same - `DEDICATED SingleThreadTaskRunner` won't run until your blocking task returns - (they will never run if the blocking task never returns). + no-op that documents the blocking behavior (and makes it pass assertions). + Tasks posted to the same `DEDICATED SingleThreadTaskRunner` won't run until + your blocking task returns (they will never run if the blocking task never + returns). [base/threading/scoped_blocking_call.h](https://cs.chromium.org/chromium/src/base/threading/scoped_blocking_call.h) explains the difference between `MAY_BLOCK ` and `WILL_BLOCK` and gives -examples of off-CPU blocking operations. +examples of blocking operations. ### How to make a blocking call that may never return without preventing other tasks from being scheduled? @@ -79,7 +83,8 @@ Since tasks posted to the same sequence can't run concurrently, it is advisable to run tasks that may block indefinitely in [parallel](threading_and_tasks.md#posting-a-parallel-task) rather than in -[sequence](threading_and_tasks.md#posting-a-sequenced-task). +[sequence](threading_and_tasks.md#posting-a-sequenced-task) (unless posting many +such tasks at which point sequencing can be a useful tool to prevent flooding). ### Do calls to blocking //base APIs need to be annotated with ScopedBlockingCall? @@ -135,15 +140,16 @@ * BrowserThread::DeleteOnThread -> base::OnTaskRunnerDeleter / base::RefCountedDeleteOnSequence * BrowserMessageFilter::OverrideThreadForMessage() -> BrowserMessageFilter::OverrideTaskRunnerForMessage() * CreateSingleThreadTaskRunnerWithTraits() -> CreateSequencedTaskRunnerWithTraits() - * Every CreateSingleThreadTaskRunnerWithTraits() usage should be accompanied - with a comment and ideally a bug to make it sequence when the sequence-unfriendly - dependency is addressed. + * Every CreateSingleThreadTaskRunnerWithTraits() usage, outside of + BrowserThread::UI/IO, should be accompanied with a comment and ideally a + bug to make it sequence when the sequence-unfriendly dependency is + addressed. ### How to ensure mutual exclusion between tasks posted by a component? Create a `SequencedTaskRunner` using `CreateSequencedTaskRunnerWithTraits()` and store it on an object that can be accessed from all the PostTask() call sites -that require mutual exclusion. If there isn't a shared object that can own +that require mutual exclusion. If there isn't a shared object that can own a common `SequencedTaskRunner`, use `Lazy(Sequenced|SingleThread|COMSTA)TaskRunner` in an anonymous namespace. @@ -153,7 +159,7 @@ If the test uses `BrowserThread::UI/IO`, instantiate a `content::TestBrowserThreadBundle` for the scope of the test. Call -`content::RunAllTasksUntilIdle()` to wait until all tasks have run. +`TestBrowserThreadBundle::RunUntilIdle()` to wait until all tasks have run. If the test doesn't use `BrowserThread::UI/IO`, instantiate a `base::test::ScopedTaskEnvironment` for the scope of the test. Call @@ -182,5 +188,6 @@ ## Your question hasn't been answered? -Ping + 1. Check the main [Threading and Tasks](threading_and_tasks.md) docs. + 2. Ping [scheduler-dev@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/scheduler-dev).
diff --git a/extensions/common/extension_message_generator.cc b/extensions/common/extension_message_generator.cc index b066c4f..b5108cc8 100644 --- a/extensions/common/extension_message_generator.cc +++ b/extensions/common/extension_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "extensions/common/extension_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "extensions/common/extension_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/gpu/ipc/common/gpu_message_generator.cc b/gpu/ipc/common/gpu_message_generator.cc index ab8f4890..46a6fb69 100644 --- a/gpu/ipc/common/gpu_message_generator.cc +++ b/gpu/ipc/common/gpu_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "gpu/ipc/common/gpu_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "gpu/ipc/common/gpu_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index b11544c..90c49730 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc
@@ -60,17 +60,6 @@ if (!success) LOG(ERROR) << "gpu::CollectGraphicsInfo failed."; -#if defined(OS_WIN) - if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) { - gpu_info->direct_composition = - DirectCompositionSurfaceWin::IsDirectCompositionSupported(); - gpu_info->supports_overlays = - DirectCompositionSurfaceWin::AreOverlaysSupported(); - gpu_info->overlay_capabilities = - DirectCompositionSurfaceWin::GetOverlayCapabilities(); - } -#endif // defined(OS_WIN) - if (success) { base::TimeDelta collect_context_time = base::TimeTicks::Now() - before_collect_context_graphics_info; @@ -79,6 +68,25 @@ return success; } +#if defined(OS_WIN) +// This has to be called after a context is created, active GPU is identified, +// and GPU driver bug workarounds are computed again. Otherwise the workaround +// |disable_direct_composition| may not be correctly applied. +// Also, this has to be called after falling back to SwiftShader decision is +// finalized because this function depends on GL is ANGLE's GLES or not. +void InitializeDirectCompositionOverlaySupport(GPUInfo* gpu_info) { + if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) { + DCHECK(gpu_info); + gpu_info->direct_composition = + DirectCompositionSurfaceWin::IsDirectCompositionSupported(); + gpu_info->supports_overlays = + DirectCompositionSurfaceWin::AreOverlaysSupported(); + gpu_info->overlay_capabilities = + DirectCompositionSurfaceWin::GetOverlayCapabilities(); + } +} +#endif // defined(OS_WIN) + #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(IS_CHROMECAST) bool CanAccessNvidiaDeviceFile() { bool res = true; @@ -285,6 +293,10 @@ } } +#if defined(OS_WIN) + InitializeDirectCompositionOverlaySupport(&gpu_info_); +#endif + #if defined(OS_LINUX) // Driver may create a compatibility profile context when collect graphics // information on Linux platform. Try to collect graphics information @@ -466,6 +478,10 @@ } } +#if defined(OS_WIN) + InitializeDirectCompositionOverlaySupport(&gpu_info_); +#endif + #if defined(OS_LINUX) // Driver may create a compatibility profile context when collect graphics // information on Linux platform. Try to collect graphics information
diff --git a/headless/lib/utility/headless_content_utility_client.cc b/headless/lib/utility/headless_content_utility_client.cc index d3911cd..3703a36 100644 --- a/headless/lib/utility/headless_content_utility_client.cc +++ b/headless/lib/utility/headless_content_utility_client.cc
@@ -32,14 +32,18 @@ HeadlessContentUtilityClient::~HeadlessContentUtilityClient() = default; -void HeadlessContentUtilityClient::RegisterServices( - HeadlessContentUtilityClient::StaticServiceMap* services) { +std::unique_ptr<service_manager::Service> +HeadlessContentUtilityClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { #if BUILDFLAG(ENABLE_PRINTING) && !defined(CHROME_MULTIPLE_DLL_BROWSER) - service_manager::EmbeddedServiceInfo pdf_compositor_info; - pdf_compositor_info.factory = - base::Bind(&printing::CreatePdfCompositorService, user_agent_); - services->emplace(printing::mojom::kServiceName, pdf_compositor_info); + if (service_name == printing::mojom::kServiceName) { + return printing::CreatePdfCompositorService(user_agent_, + std::move(request)); + } #endif + + return nullptr; } void HeadlessContentUtilityClient::RegisterNetworkBinders(
diff --git a/headless/lib/utility/headless_content_utility_client.h b/headless/lib/utility/headless_content_utility_client.h index 5e2e642..3d51191f 100644 --- a/headless/lib/utility/headless_content_utility_client.h +++ b/headless/lib/utility/headless_content_utility_client.h
@@ -26,7 +26,9 @@ ~HeadlessContentUtilityClient() override; // content::ContentUtilityClient: - void RegisterServices(StaticServiceMap* services) override; + std::unique_ptr<service_manager::Service> HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; void RegisterNetworkBinders( service_manager::BinderRegistry* registry) override;
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm index 1783bbe4..7fa79411 100644 --- a/ios/chrome/browser/autofill/form_structure_browsertest.mm +++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -165,7 +165,7 @@ void FormStructureBrowserTest::GenerateResults(const std::string& input, std::string* output) { - ASSERT_TRUE(LoadHtml(input)); + ASSERT_TRUE(LoadHtmlWithoutSubresources(input)); base::TaskScheduler::GetInstance()->FlushForTesting(); web::WebFrame* frame = web::GetMainWebFrame(web_state()); AutofillManager* autofill_manager =
diff --git a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm index bcd29d2..ff5635c1 100644 --- a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm +++ b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm
@@ -35,8 +35,8 @@ NSString* kJavaScriptGoPrev = @"__gCrWeb.findInPage.goPrev()"; // JavaScript variables accessed by the tests. -NSString* kJavaScriptIndex = @"__gCrWeb.findInPage.index"; -NSString* kJavaScriptSpansLength = @"__gCrWeb.findInPage.spans.length"; +NSString* kJavaScriptIndex = @"__gCrWeb.findInPage.selectedMatchIndex"; +NSString* kJavaScriptSpansLength = @"__gCrWeb.findInPage.matches.length"; // HTML that contains several occurrences of the string 'foo', some visible and // some not visible (the first 'foo' is hidden, the next is visible, the next is @@ -229,9 +229,8 @@ } TEST_F(FindInPageJsTest, SearchForWhitespace) { - LoadHtml( - @"<html><body> <div> </div> <h1> </h1><p> <span> </span> </p> " - @"</body></html>"); + LoadHtml(@"<html><body> <div> </div> <h1> </h1><p> <span> </span> </p> " + @"</body></html>"); // Assert the index and span count contain their initialized values. AssertJavaScriptValue(kJavaScriptIndex, -1); AssertJavaScriptValue(kJavaScriptSpansLength, 0);
diff --git a/ios/chrome/browser/find_in_page/resources/find_in_page.js b/ios/chrome/browser/find_in_page/resources/find_in_page.js index 96ead9f..9b4e639 100644 --- a/ios/chrome/browser/find_in_page/resources/find_in_page.js +++ b/ios/chrome/browser/find_in_page/resources/find_in_page.js
@@ -16,19 +16,65 @@ __gCrWeb.findInPage = {}; /** + * A Match represents a match result in the document. |this.nodes| stores all + * the <chrome_find> Nodes created for highlighting the matched text. If it + * contains only one Node, it means the match is found within one HTML TEXT + * Node, otherwise the match involves multiple HTML TEXT Nodes. + */ +class Match { + constructor(nodes) { + this.nodes = nodes; + } + + /** + * Returns if all <chrome_find> Nodes of this match are visible. + * @return {Boolean} If the Match is visible. + */ + visible() { + for (let i = 0; i < this.nodes.length; ++i) { + if (!isElementVisible_(this.nodes[i])) + return false; + } + return true; + } + + /** + * Adds orange color highlight for "selected match result", over the yellow + * color highlight for "normal match result". + * @return {undefined} + */ + addSelectHighlight() { + for (let i = 0; i < this.nodes.length; ++i) { + this.nodes[i].className = (this.nodes[i].className || '') + ' findysel'; + } + } + + /** + * Clears the orange color highlight. + * @return {undefined} + */ + removeSelectHighlight() { + for (let i = 0; i < this.nodes.length; ++i) { + this.nodes[i].className = + (this.nodes[i].className || '').replace(/\sfindysel/g, ''); + } + } +} + +/** + * The list of all the matches in current page. + * @type {Array<Match>} + */ +__gCrWeb.findInPage.matches = []; + +/** * Index of the current highlighted choice. -1 means none. * @type {number} */ -__gCrWeb.findInPage.index = -1; +__gCrWeb.findInPage.selectedMatchIndex = -1; /** - * The list of found searches in span form. - * @type {Array<Element>} - */ -__gCrWeb.findInPage.spans = []; - -/** - * A replacement represents a DOM operation that swaps |oldNode| with |newNodes| + * A Replacement represents a DOM operation that swaps |oldNode| with |newNodes| * under the parent of |oldNode| to highlight the match result inside |oldNode|. * |newNodes| may contain plain TEXT Nodes for unhighlighted parts and * <chrome_find> nodes for highlighted parts. This operation will be executed @@ -160,8 +206,8 @@ */ const REGEX_ESCAPER = /([.?*+^$[\]\\(){}|-])/g; -function getCurrentSpan_() { - return __gCrWeb.findInPage.spans[__gCrWeb.findInPage.index]; +function getCurrentSelectedMatch_() { + return __gCrWeb.findInPage.matches[__gCrWeb.findInPage.selectedMatchIndex]; }; /** @@ -201,7 +247,7 @@ [highlightedWordsCount, [index, pageLocationX, pageLocationY]]. */ __gCrWeb.findInPage.highlightWord = function(findText, timeout) { - if (__gCrWeb.findInPage.spans && __gCrWeb.findInPage.spans.length) { + if (__gCrWeb.findInPage.matches && __gCrWeb.findInPage.matches.length) { // Clean up a previous run. clearHighlight_(); } @@ -285,6 +331,7 @@ element.setAttribute('class', CSS_CLASS_NAME); element.innerHTML = escapeHTML_(matchText); nodes.push(element); + __gCrWeb.findInPage.matches.push(new Match([element])); strIndex = match.index + matchText.length; } catch (e) { @@ -322,13 +369,11 @@ replacements_[i].doSwap(); } - __gCrWeb.findInPage.spans = getAllElementsByClassName_(CSS_CLASS_NAME); - // Count visible elements. - let max = __gCrWeb.findInPage.spans.length; + let max = __gCrWeb.findInPage.matches.length; let maxVisible = MAX_VISIBLE_ELEMENTS; for (let index = __gCrWeb.findInPage.visibleIndex; index < max; index++) { - let elem = __gCrWeb.findInPage.spans[index]; + let match = __gCrWeb.findInPage.matches[index]; if (__gCrWeb.findInPage.overTime()) { __gCrWeb.findInPage.visibleIndex = index; return __gCrWeb.stringify([false]); @@ -336,14 +381,13 @@ // Stop after |maxVisible| elements. if (__gCrWeb.findInPage.visibleFound > maxVisible) { - __gCrWeb.findInPage.spans[index].visibleIndex = maxVisible; + match.visibleIndex = maxVisible; continue; } - if (isVisible_(elem)) { + if (match.visible()) { __gCrWeb.findInPage.visibleFound++; - __gCrWeb.findInPage.spans[index].visibleIndex = - __gCrWeb.findInPage.visibleFound; + match.visibleIndex = __gCrWeb.findInPage.visibleFound; } } @@ -358,35 +402,7 @@ }; /** - * Converts a node list to an array. - * @param {NodeList} nodeList DOM node list. - * @return {Array<Node>} array. - */ -function toArray_(nodeList) { - let array = []; - for (let i = 0; i < nodeList.length; i++) - array[i] = nodeList[i]; - return array; -}; - -/** - * Return all elements of class name, spread out over letious frames. - * @param {string} name of class. - * @return {Array<Node>} array of elements matching class name. - */ -function getAllElementsByClassName_(name) { - let nodeList = document.getElementsByClassName(name); - let elements = toArray_(nodeList); - for (let i = frameDocs_.length - 1; i >= 0; i--) { - let doc = frameDocs_[i]; - nodeList = doc.getElementsByClassName(name); - elements = elements.concat(toArray_(nodeList)); - } - return elements; -}; - -/** - * Removes all currently highlighted spans. + * Removes all currently highlighted matches. * Note: It does not restore previous state, just removes the class name. */ function clearHighlight_() { @@ -395,19 +411,20 @@ } replacements_ = []; replacementsIndex_ = 0; - __gCrWeb.findInPage.spans = []; - __gCrWeb.findInPage.index = -1; + __gCrWeb.findInPage.matches = []; + __gCrWeb.findInPage.selectedMatchIndex = -1; }; /** - * Increments the index of the current highlighted span or, if the index is - * already at the end, sets it to the index of the first span in the page. + * Increments the index of the current selected Match or, if the index is + * already at the end, sets it to the index of the first Match in the page. */ __gCrWeb.findInPage.incrementIndex = function() { - if (__gCrWeb.findInPage.index >= __gCrWeb.findInPage.spans.length - 1) { - __gCrWeb.findInPage.index = 0; + if (__gCrWeb.findInPage.selectedMatchIndex >= + __gCrWeb.findInPage.matches.length - 1) { + __gCrWeb.findInPage.selectedMatchIndex = 0; } else { - __gCrWeb.findInPage.index++; + __gCrWeb.findInPage.selectedMatchIndex++; } }; @@ -417,25 +434,25 @@ * nothing happened. */ __gCrWeb.findInPage.goNext = function() { - if (!__gCrWeb.findInPage.spans || __gCrWeb.findInPage.spans.length == 0) { + if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { return ''; } - if (__gCrWeb.findInPage.index >= 0) { + if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { // Remove previous highlight. - removeSelectHighlight_(getCurrentSpan_()); + getCurrentSelectedMatch_().removeSelectHighlight(); } // Iterate through to the next index, but because they might not be visible, // keep trying until you find one that is. Make sure we don't loop forever by // stopping on what we are currently highlighting. - let oldIndex = __gCrWeb.findInPage.index; + let oldIndex = __gCrWeb.findInPage.selectedMatchIndex; __gCrWeb.findInPage.incrementIndex(); - while (!isVisible_(getCurrentSpan_())) { - if (oldIndex === __gCrWeb.findInPage.index) { - // Checked all spans but didn't find anything else visible. + while (!getCurrentSelectedMatch_().visible()) { + if (oldIndex === __gCrWeb.findInPage.selectedMatchIndex) { + // Checked all matches but didn't find anything else visible. return ''; } __gCrWeb.findInPage.incrementIndex(); - if (0 === __gCrWeb.findInPage.index && oldIndex < 0) { + if (0 === __gCrWeb.findInPage.selectedMatchIndex && oldIndex < 0) { // Didn't find anything visible and haven't highlighted anything yet. return ''; } @@ -445,14 +462,15 @@ }; /** - * Decrements the index of the current highlighted span or, if the index is - * already at the beginning, sets it to the index of the last span in the page. + * Decrements the index of the current selected Match or, if the index is + * already at the beginning, sets it to the index of the last Match in the page. */ __gCrWeb.findInPage.decrementIndex = function() { - if (__gCrWeb.findInPage.index <= 0) { - __gCrWeb.findInPage.index = __gCrWeb.findInPage.spans.length - 1; + if (__gCrWeb.findInPage.selectedMatchIndex <= 0) { + __gCrWeb.findInPage.selectedMatchIndex = + __gCrWeb.findInPage.matches.length - 1; } else { - __gCrWeb.findInPage.index--; + __gCrWeb.findInPage.selectedMatchIndex--; } }; @@ -462,22 +480,22 @@ * nothing happened. */ __gCrWeb.findInPage.goPrev = function() { - if (!__gCrWeb.findInPage.spans || __gCrWeb.findInPage.spans.length == 0) { + if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { return ''; } - if (__gCrWeb.findInPage.index >= 0) { + if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { // Remove previous highlight. - removeSelectHighlight_(getCurrentSpan_()); + getCurrentSelectedMatch_().removeSelectHighlight(); } // Iterate through to the next index, but because they might not be visible, // keep trying until you find one that is. Make sure we don't loop forever by // stopping on what we are currently highlighting. - let old = __gCrWeb.findInPage.index; + let old = __gCrWeb.findInPage.selectedMatchIndex; __gCrWeb.findInPage.decrementIndex(); - while (!isVisible_(getCurrentSpan_())) { + while (!getCurrentSelectedMatch_().visible()) { __gCrWeb.findInPage.decrementIndex(); - if (old == __gCrWeb.findInPage.index) { - // Checked all spans but didn't find anything. + if (old == __gCrWeb.findInPage.selectedMatchIndex) { + // Checked all matches but didn't find anything. return ''; } } @@ -487,34 +505,6 @@ }; /** - * Adds the special highlighting to the result at the index. - * @param {number=} opt_index Index to replace __gCrWeb.findInPage.index - * with. - */ -function addHighlightToIndex_(opt_index) { - if (opt_index !== undefined) { - __gCrWeb.findInPage.index = opt_index; - } - addSelectHighlight_(getCurrentSpan_()); -}; - -/** - * Adds selected highlight style to the specified element. - * @param {Element} element Element to highlight. - */ -function addSelectHighlight_(element) { - element.className = (element.className || '') + ' findysel'; -}; - -/** - * Removes selected highlight style from the specified element. - * @param {Element} element Element to remove highlighting from. - */ -function removeSelectHighlight_(element) { - element.className = (element.className || '').replace(/\sfindysel/g, ''); -}; - -/** * Normalize coordinates according to the current document dimensions. Don't go * too far off the screen in either direction. Try to center if possible. * @param {Element} elem Element to find normalized coordinates for. @@ -547,18 +537,14 @@ /** * Finds the position of the result and scrolls to it. - * @param {number=} opt_index Index to replace __gCrWeb.findInPage.index with. * @return {string} JSON encoded array of the scroll coordinates "[x, y]". */ -function findScrollDimensions_(opt_index) { - if (opt_index !== undefined) { - __gCrWeb.findInPage.index = opt_index; - } - let elem = getCurrentSpan_(); - if (!elem) { +function findScrollDimensions_() { + let match = getCurrentSelectedMatch_(); + if (!match) { return ''; } - let normalized = getNormalizedCoordinates_(elem); + let normalized = getNormalizedCoordinates_(match.nodes[0]); let xPos = normalized[0]; let yPos = normalized[1]; @@ -571,12 +557,12 @@ yPos >= (window.pageYOffset + window.innerHeight)) { // If it's off the screen. Wait a bit to start the highlight animation so // that scrolling can get there first. - window.setTimeout(addHighlightToIndex_, 250); + window.setTimeout(() => match.addSelectHighlight(), 250); } else { - addHighlightToIndex_(); + match.addSelectHighlight(); } let scaled = scaleCoordinates_(normalized); - let index = getCurrentSpan_().visibleIndex; + let index = match.visibleIndex; scaled.unshift(index); return __gCrWeb.stringify(scaled); }; @@ -720,7 +706,7 @@ * @param {Element} elem Element to check. * @return {boolean} Whether elem is visible or not. */ -function isVisible_(elem) { +function isElementVisible_(elem) { if (!elem) { return false; } @@ -846,5 +832,4 @@ }; window.addEventListener('pagehide', __gCrWeb.findInPage.disable); - })();
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index aaa768a..b7b14d7 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -10,6 +10,8 @@ "UIView+SizeClassSupport.mm", "background_generator.h", "background_generator.mm", + "chrome_load_params.h", + "chrome_load_params.mm", "file_locations.h", "file_locations.mm", "native_content_controller.h",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm index 7a29c9c..8eebffd 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm
@@ -200,6 +200,8 @@ FormInputAccessoryViewHandler* handler = [[FormInputAccessoryViewHandler alloc] init]; handler.JSSuggestionManager = self.suggestionManager; + [handler setLastFocusFormActivityWebFrameID: + base::SysUTF8ToNSString(self.lastFocusedElementFrameIdentifier)]; [handler selectNextElementWithoutButtonPress]; }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index 5aeaacec..95592cf6 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -1078,7 +1078,8 @@ base::UserMetricsAction("MobileBookmarkManagerEntryOpened")); web::NavigationManager::WebLoadParams params(url); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - [self.loader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.loader loadURLWithParams:chromeParams]; } - (void)addNewFolder {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm index 4330c671..c2a7a7c 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -540,7 +540,8 @@ } web::NavigationManager::WebLoadParams params(url); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - [_loader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [_loader loadURLWithParams:chromeParams]; } - (void)openURLInNewTab:(const GURL&)url
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index e7aaa08..e1cbd2a1 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -3408,7 +3408,7 @@ title = l10n_util::GetNSStringWithFixup(IDS_IOS_CONTENT_CONTEXT_OPENIMAGE); action = ^{ Record(ACTION_OPEN_IMAGE, isImage, isLink); - web::NavigationManager::WebLoadParams params(imageUrl); + ChromeLoadParams params(imageUrl); [weakSelf loadURLWithParams:params]; }; [_contextMenuCoordinator addItemWithTitle:title action:action]; @@ -4067,7 +4067,8 @@ #pragma mark - UrlLoader (Public) -- (void)loadURLWithParams:(const web::NavigationManager::WebLoadParams&)params { +- (void)loadURLWithParams:(const ChromeLoadParams&)chromeParams { + web::NavigationManager::WebLoadParams params = chromeParams.web_params; [[OmniboxGeolocationController sharedInstance] locationBarDidSubmitURL:params.url transition:params.transition_type @@ -4571,7 +4572,7 @@ - (void)navigateToMemexTabSwitcher { // TODO(crbug.com/799601): Delete this once its not needed. const GURL memexURL("https://chrome-memex.appspot.com"); - web::NavigationManager::WebLoadParams params(memexURL); + ChromeLoadParams params(memexURL); [self loadURLWithParams:params]; }
diff --git a/ios/chrome/browser/ui/chrome_load_params.h b/ios/chrome/browser/ui/chrome_load_params.h new file mode 100644 index 0000000..2ae3c278 --- /dev/null +++ b/ios/chrome/browser/ui/chrome_load_params.h
@@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_CHROME_LOAD_PARAMS_H_ +#define IOS_CHROME_BROWSER_UI_CHROME_LOAD_PARAMS_H_ + +#import "ios/web/public/navigation_manager.h" +#include "ui/base/window_open_disposition.h" + +// Chrome wrapper around web::NavigationManager::WebLoadParams to add the +// parameters needed by chrome. This is used when a URL is opened. +struct ChromeLoadParams { + public: + // The wrapped params. + web::NavigationManager::WebLoadParams web_params; + + // The disposition of the URL being opened. + WindowOpenDisposition disposition; + + explicit ChromeLoadParams( + const web::NavigationManager::WebLoadParams& web_params); + explicit ChromeLoadParams(const GURL& url); + ~ChromeLoadParams(); + + // Allow copying ChromeLoadParams. + ChromeLoadParams(const ChromeLoadParams& other); + ChromeLoadParams& operator=(const ChromeLoadParams& other); +}; + +#endif // IOS_CHROME_BROWSER_UI_CHROME_LOAD_PARAMS_H_
diff --git a/ios/chrome/browser/ui/chrome_load_params.mm b/ios/chrome/browser/ui/chrome_load_params.mm new file mode 100644 index 0000000..528ed962 --- /dev/null +++ b/ios/chrome/browser/ui/chrome_load_params.mm
@@ -0,0 +1,28 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/chrome_load_params.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +ChromeLoadParams::ChromeLoadParams( + const web::NavigationManager::WebLoadParams& web_params) + : web_params(web_params), disposition(WindowOpenDisposition::CURRENT_TAB) {} + +ChromeLoadParams::ChromeLoadParams(const GURL& url) + : web_params(url), disposition(WindowOpenDisposition::CURRENT_TAB) {} + +ChromeLoadParams::~ChromeLoadParams() {} + +ChromeLoadParams::ChromeLoadParams(const ChromeLoadParams& other) + : web_params(other.web_params), disposition(other.disposition) {} + +ChromeLoadParams& ChromeLoadParams::operator=(const ChromeLoadParams& other) { + web_params = other.web_params; + disposition = other.disposition; + + return *this; +}
diff --git a/ios/chrome/browser/ui/commands/application_commands.h b/ios/chrome/browser/ui/commands/application_commands.h index 862c4b0..4d22828 100644 --- a/ios/chrome/browser/ui/commands/application_commands.h +++ b/ios/chrome/browser/ui/commands/application_commands.h
@@ -97,6 +97,8 @@ (UIViewController*)baseViewController; // Opens the |command| URL in a new tab. +// TODO(crbug.com/907527): Check if it is possible to merge it with the +// URLLoader methods. - (void)openURLInNewTab:(OpenNewTabCommand*)command; // TODO(crbug.com/779791) : Do not pass baseViewController through dispatcher.
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm index 75128f879..37ab0e7 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -224,7 +224,8 @@ web::Referrer(GURL(ntp_snippets::GetContentSuggestionsReferrerURL()), web::ReferrerPolicyDefault); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - [self.dispatcher loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.dispatcher loadURLWithParams:chromeParams]; [self.NTPMetrics recordAction:new_tab_page_uma::ACTION_OPENED_SUGGESTION]; } @@ -262,7 +263,8 @@ web::NavigationManager::WebLoadParams params(mostVisitedItem.URL); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - [self.dispatcher loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.dispatcher loadURLWithParams:chromeParams]; } - (void)displayContextMenuForSuggestion:(CollectionViewItem*)item @@ -345,7 +347,7 @@ - (void)handleLearnMoreTapped { GURL URL(kNTPHelpURL); - web::NavigationManager::WebLoadParams params(URL); + ChromeLoadParams params(URL); [self.dispatcher loadURLWithParams:params]; [self.NTPMetrics recordAction:new_tab_page_uma::ACTION_OPENED_LEARN_MORE]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator_unittest.mm index 504b105..5f4df7e 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator_unittest.mm
@@ -255,7 +255,9 @@ OCMStub([model itemAtIndexPath:indexPath]).andReturn(item); web::NavigationManager::WebLoadParams params(url); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - OCMExpect([[dispatcher_ ignoringNonObjectArgs] loadURLWithParams:params]); + ChromeLoadParams chromeParams(params); + OCMExpect( + [[dispatcher_ ignoringNonObjectArgs] loadURLWithParams:chromeParams]); // Action. [mediator_ openPageForItemAtIndexPath:indexPath]; @@ -274,7 +276,9 @@ item.URL = url; web::NavigationManager::WebLoadParams params(url); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - OCMExpect([[dispatcher_ ignoringNonObjectArgs] loadURLWithParams:params]); + ChromeLoadParams chromeParams(params); + OCMExpect( + [[dispatcher_ ignoringNonObjectArgs] loadURLWithParams:chromeParams]); // Action. [mediator_ openMostVisitedItem:item atIndex:0];
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm index d1db90c..c288060 100644 --- a/ios/chrome/browser/ui/history/history_table_view_controller.mm +++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -1070,8 +1070,9 @@ new_tab_page_uma::ACTION_OPENED_HISTORY_ENTRY); web::NavigationManager::WebLoadParams params(URL); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; + ChromeLoadParams chromeParams(params); [self.localDispatcher dismissHistoryWithCompletion:^{ - [self.loader loadURLWithParams:params]; + [self.loader loadURLWithParams:chromeParams]; [self.presentationDelegate showActiveRegularTabFromHistory]; }]; }
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index 2790bcfc..fef122a2 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -235,7 +235,8 @@ web::NavigationManager::WebLoadParams params(url); params.transition_type = transition; params.extra_headers = [self variationHeadersForURL:url]; - [self.URLLoader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.URLLoader loadURLWithParams:chromeParams]; if (google_util::IsGoogleSearchUrl(url)) { UMA_HISTOGRAM_ENUMERATION( @@ -370,7 +371,8 @@ web::NavigationManager::WebLoadParams params(searchURL); params.transition_type = ui::PageTransitionFromInt( ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); - [self.URLLoader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.URLLoader loadURLWithParams:chromeParams]; } }
diff --git a/ios/chrome/browser/ui/ntp/incognito_view.mm b/ios/chrome/browser/ui/ntp/incognito_view.mm index 9695b1e8..5e01a5f 100644 --- a/ios/chrome/browser/ui/ntp/incognito_view.mm +++ b/ios/chrome/browser/ui/ntp/incognito_view.mm
@@ -345,8 +345,7 @@ // Triggers a navigation to the help page. - (void)learnMoreButtonPressed { - web::NavigationManager::WebLoadParams params( - GetUrlWithLang(GURL(kLearnMoreIncognitoUrl))); + ChromeLoadParams params(GetUrlWithLang(GURL(kLearnMoreIncognitoUrl))); [_loader loadURLWithParams:params]; }
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm index 9ad61ae..8be3ab01 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm
@@ -104,7 +104,8 @@ - (void)openMostVisitedItem:(ShortcutsMostVisitedItem*)item { web::NavigationManager::WebLoadParams params(item.URL); params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - [self.dispatcher loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.dispatcher loadURLWithParams:chromeParams]; [self.dispatcher cancelOmniboxEdit]; }
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm index 83a56ea..ac3dd6f 100644 --- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller_egtest.mm
@@ -418,7 +418,8 @@ ui::PageTransition transition) { web::NavigationManager::WebLoadParams params(replacementURL); params.transition_type = transition; - [self.URLLoader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.URLLoader loadURLWithParams:chromeParams]; [self cancelOmniboxEdit]; }; load_GURL_from_location_bar_swizzler_.reset(
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index b9d17c3..ac70e21 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -381,7 +381,8 @@ params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; params.referrer = web::Referrer(GURL(kReadingListReferrerURL), web::ReferrerPolicyDefault); - [self.loader loadURLWithParams:params]; + ChromeLoadParams chromeParams(params); + [self.loader loadURLWithParams:chromeParams]; } [self stop];
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index 037f5aa..d54fa3d 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -91,6 +91,11 @@ textItem.textColor = [UIColor blackColor]; [model addItem:textItem toSectionWithIdentifier:SectionIdentifierText]; + textItem = [[TableViewTextItem alloc] initWithType:ItemTypeText]; + textItem.text = @"1234"; + textItem.masked = YES; + [model addItem:textItem toSectionWithIdentifier:SectionIdentifierText]; + TableViewAccessoryItem* textAccessoryItem = [[TableViewAccessoryItem alloc] initWithType:ItemTypeTextAccessoryImage]; textAccessoryItem.title = @"Text Accessory with History Image";
diff --git a/ios/chrome/browser/ui/static_content/static_html_native_content.h b/ios/chrome/browser/ui/static_content/static_html_native_content.h index ff9da3f9..b420152b 100644 --- a/ios/chrome/browser/ui/static_content/static_html_native_content.h +++ b/ios/chrome/browser/ui/static_content/static_html_native_content.h
@@ -43,9 +43,6 @@ - (instancetype)init NS_UNAVAILABLE; -// Loads a new url. -- (void)loadURLWithParams:(const web::NavigationManager::WebLoadParams&)params; - // The scrollview of the native view. - (UIScrollView*)scrollView;
diff --git a/ios/chrome/browser/ui/static_content/static_html_native_content.mm b/ios/chrome/browser/ui/static_content/static_html_native_content.mm index a760841..167ca0150 100644 --- a/ios/chrome/browser/ui/static_content/static_html_native_content.mm +++ b/ios/chrome/browser/ui/static_content/static_html_native_content.mm
@@ -74,10 +74,6 @@ [[self scrollView] setDelegate:nil]; } -- (void)loadURLWithParams:(const web::NavigationManager::WebLoadParams&)params { - [_loader loadURLWithParams:params]; -} - - (OverscrollActionsController*)overscrollActionsController { return _overscrollActionsController; }
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm index a421845..cef4375 100644 --- a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm +++ b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
@@ -243,8 +243,7 @@ // if they are issued by the main frame. if (loader_ && fromMainFrame) { dispatch_async(dispatch_get_main_queue(), ^{ - web::NavigationManager::WebLoadParams params( - net::GURLWithNSURL([request URL])); + ChromeLoadParams params(net::GURLWithNSURL([request URL])); [loader_ loadURLWithParams:params]; }); }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_url_loader.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_url_loader.mm index 32dd7af..e23f68c 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_url_loader.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_url_loader.mm
@@ -97,12 +97,11 @@ // Opens |loadParams| in a new regular tab, rather than replacing the active // tab. -- (void)loadURLWithParams: - (const web::NavigationManager::WebLoadParams&)loadParams { +- (void)loadURLWithParams:(const ChromeLoadParams&)loadParams { DCHECK(self.regularBrowserState); web::WebState::CreateParams params(self.regularBrowserState); std::unique_ptr<web::WebState> webState = web::WebState::Create(params); - webState->GetNavigationManager()->LoadURLWithParams(loadParams); + webState->GetNavigationManager()->LoadURLWithParams(loadParams.web_params); AppendAndActivateWebState(self.regularWebStateList, std::move(webState)); }
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h index 20e9c93..6729b2f 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h
@@ -39,4 +39,7 @@ // Hex Value for the tint color for switches. extern const int kTableViewSwitchTintColor; +// A masked password string(e.g. "••••••••"). +extern NSString* const kMaskedPassword; + #endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_CELLS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm index e5ff911..ac77aea 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm
@@ -19,3 +19,5 @@ const int kTableViewTextLabelColorLightGrey = 0x6D6D72; const int kTableViewSecondaryLabelLightGrayTextColor = 0x8E8E93; const int kTableViewSwitchTintColor = 0x1A73E8; + +NSString* const kMaskedPassword = @"••••••••";
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h index c9d9663..8768ff1 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h
@@ -20,7 +20,10 @@ // takes precedence over the default color, but not over |textColor|. @property(nonatomic, assign) UIColor* textColor; -@property(nonatomic, readwrite, strong) NSString* text; +@property(nonatomic, strong) NSString* text; + +// If set to YES, |text| will be shown as "••••••" with fixed length. +@property(nonatomic, assign) BOOL masked; @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm index 5767ee5..3ca1871 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
@@ -21,9 +21,6 @@ #pragma mark - TableViewTextItem @implementation TableViewTextItem -@synthesize text = _text; -@synthesize textAlignment = _textAlignment; -@synthesize textColor = _textColor; - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; @@ -38,10 +35,17 @@ [super configureCell:tableCell withStyler:styler]; TableViewTextCell* cell = base::mac::ObjCCastStrict<TableViewTextCell>(tableCell); - cell.textLabel.text = self.text; - cell.textLabel.backgroundColor = styler.tableViewBackgroundColor; - // This item's text color takes precedence over the global styler. - // TODO(crbug.com/854249): redo the logic for this convoluted if clause. + cell.textLabel.text = self.masked ? kMaskedPassword : self.text; + // Decide cell.textLabel.backgroundColor in order: + // 1. styler.cellBackgroundColor; + // 2. styler.tableViewBackgroundColor. + cell.textLabel.backgroundColor = styler.cellBackgroundColor + ? styler.cellBackgroundColor + : styler.tableViewBackgroundColor; + // Decide cell.textLabel.textColor in order: + // 1. this.textColor; + // 2. styler.cellTitleColor; + // 3. kTableViewTextLabelColorLightGrey. if (self.textColor) { cell.textLabel.textColor = self.textColor; } else if (styler.cellTitleColor) {
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item_unittest.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_item_unittest.mm index 9c59735..b2395881 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item_unittest.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item_unittest.mm
@@ -39,6 +39,27 @@ EXPECT_NSEQ(text, textCell.textLabel.text); } +// Tests that item's text is shown as masked string in UILabel after a call to +// |configureCell:| with item.masked set to YES. +TEST_F(TableViewTextItemTest, MaskedTextLabels) { + NSString* text = @"Cell text"; + + TableViewTextItem* item = [[TableViewTextItem alloc] initWithType:0]; + item.text = text; + item.masked = YES; + + id cell = [[[item cellClass] alloc] init]; + ASSERT_TRUE([cell isMemberOfClass:[TableViewTextCell class]]); + + TableViewTextCell* textCell = + base::mac::ObjCCastStrict<TableViewTextCell>(cell); + EXPECT_FALSE(textCell.textLabel.text); + + ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; + [item configureCell:textCell withStyler:styler]; + EXPECT_NSEQ(kMaskedPassword, textCell.textLabel.text); +} + TEST_F(TableViewTextItemTest, ConfigureCellWithStyler) { TableViewTextItem* item = [[TableViewTextItem alloc] initWithType:0]; TableViewTextCell* cell = [[[item cellClass] alloc] init];
diff --git a/ios/chrome/browser/ui/url_loader.h b/ios/chrome/browser/ui/url_loader.h index 43c6507..f74717f2 100644 --- a/ios/chrome/browser/ui/url_loader.h +++ b/ios/chrome/browser/ui/url_loader.h
@@ -9,7 +9,7 @@ #include "base/strings/string16.h" #include "components/sessions/core/session_id.h" -#import "ios/web/public/navigation_manager.h" +#import "ios/chrome/browser/ui/chrome_load_params.h" @class OpenNewTabCommand; @@ -20,12 +20,16 @@ @protocol UrlLoader<NSObject> // Load a new request. -- (void)loadURLWithParams:(const web::NavigationManager::WebLoadParams&)params; +// TODO(crbug.com/907527): Check if it is possible to merge with the other way +// of loading a URL. +- (void)loadURLWithParams:(const ChromeLoadParams&)params; // Load a new URL on a new page/tab. The |referrer| is optional. The tab will be // placed in the model according to |appendTo|. |originPoint| is used when the // tab is opened in background as the origin point for the animation, it is not // used if the tab is opened in foreground. +// TODO(crbug.com/907527): Check if it is possible to merge with the other way +// of loading a URL. - (void)webPageOrderedOpen:(OpenNewTabCommand*)command; // Load a tab with the given session.
diff --git a/ios/chrome/test/fakes/fake_url_loader.mm b/ios/chrome/test/fakes/fake_url_loader.mm index f47749c7..8ad5db7 100644 --- a/ios/chrome/test/fakes/fake_url_loader.mm +++ b/ios/chrome/test/fakes/fake_url_loader.mm
@@ -28,7 +28,8 @@ @synthesize inIncognito = _inIncognito; @synthesize extraHeaders = _extraHeaders; -- (void)loadURLWithParams:(const web::NavigationManager::WebLoadParams&)params { +- (void)loadURLWithParams:(const ChromeLoadParams&)chromeParams { + web::NavigationManager::WebLoadParams params = chromeParams.web_params; _url = params.url; _referrer = params.referrer; self.transition = params.transition_type;
diff --git a/ios/web/public/test/web_test_with_web_state.h b/ios/web/public/test/web_test_with_web_state.h index 0e5a0ba..bb08f641 100644 --- a/ios/web/public/test/web_test_with_web_state.h +++ b/ios/web/public/test/web_test_with_web_state.h
@@ -47,6 +47,11 @@ void LoadHtml(NSString* html); // Loads the specified HTML content into the WebState, using test url name. bool LoadHtml(const std::string& html) WARN_UNUSED_RESULT; + // Loads the specified HTML content with URL into the WebState. None of the + // subresources will be fetched. + // This function is only supported on iOS11+. On iOS10, this function simply + // calls |LoadHtml|. + bool LoadHtmlWithoutSubresources(const std::string& html); // Blocks until both known NSRunLoop-based and known message-loop-based // background tasks have completed void WaitForBackgroundTasks();
diff --git a/ios/web/public/test/web_test_with_web_state.mm b/ios/web/public/test/web_test_with_web_state.mm index b47b23d4..6c85ea63 100644 --- a/ios/web/public/test/web_test_with_web_state.mm +++ b/ios/web/public/test/web_test_with_web_state.mm
@@ -4,6 +4,7 @@ #import "ios/web/public/test/web_test_with_web_state.h" +#include "base/ios/ios_util.h" #include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "base/scoped_observer.h" @@ -15,6 +16,7 @@ #include "ios/web/public/web_state/url_verification_constants.h" #include "ios/web/public/web_state/web_state_observer.h" #import "ios/web/web_state/ui/crw_web_controller.h" +#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" #import "ios/web/web_state/web_state_impl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -22,6 +24,7 @@ #endif using base::test::ios::WaitUntilConditionOrTimeout; +using base::test::ios::kWaitForActionTimeout; using base::test::ios::kWaitForJSCompletionTimeout; using base::test::ios::kWaitForPageLoadTimeout; @@ -75,6 +78,55 @@ .AddTransientItem(url); } +bool WebTestWithWebState::LoadHtmlWithoutSubresources(const std::string& html) { + if (@available(iOS 11, *)) { + NSString* block_all = @"[{" + " \"trigger\": {" + " \"url-filter\": \".*\"" + " }," + " \"action\": {" + " \"type\": \"block\"" + " }" + "}]"; + __block WKContentRuleList* content_rule_list = nil; + __block NSError* error = nil; + __block BOOL rule_compilation_completed = NO; + [WKContentRuleListStore.defaultStore + compileContentRuleListForIdentifier:@"block_everything" + encodedContentRuleList:block_all + completionHandler:^(WKContentRuleList* rule_list, + NSError* err) { + error = err; + content_rule_list = rule_list; + rule_compilation_completed = YES; + }]; + + bool success = WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^bool { + return rule_compilation_completed; + }); + if (!success) { + DLOG(WARNING) << "ContentRuleList compilation timed out."; + return false; + } + if (error) { + DLOG(WARNING) << "ContentRuleList compilation failed with error: " + << base::SysNSStringToUTF8(error.description); + return false; + } + DCHECK(content_rule_list); + WKWebViewConfigurationProvider& configuration_provider = + WKWebViewConfigurationProvider::FromBrowserState(GetBrowserState()); + WKWebViewConfiguration* configuration = + configuration_provider.GetWebViewConfiguration(); + [configuration.userContentController addContentRuleList:content_rule_list]; + bool result = LoadHtml(html); + [configuration.userContentController + removeContentRuleList:content_rule_list]; + return result; + } + return LoadHtml(html); +} + void WebTestWithWebState::LoadHtml(NSString* html, const GURL& url) { // Sets MIME type to "text/html" once navigation is committed. class MimeTypeUpdater : public WebStateObserver {
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index ebe405fd..b5682e3 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn
@@ -29,7 +29,6 @@ "param_traits_read_macros.h", "param_traits_write_macros.h", "struct_constructor_macros.h", - "struct_destructor_macros.h", ] if (!is_ios) {
diff --git a/ipc/ipc_channel_proxy_unittest.cc b/ipc/ipc_channel_proxy_unittest.cc index 2bf18d4..6f6a435 100644 --- a/ipc/ipc_channel_proxy_unittest.cc +++ b/ipc/ipc_channel_proxy_unittest.cc
@@ -24,10 +24,6 @@ #include "ipc/struct_constructor_macros.h" #include "ipc/ipc_channel_proxy_unittest_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "ipc/ipc_channel_proxy_unittest_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h index b9e5b91..e0e256e 100644 --- a/ipc/ipc_message_macros.h +++ b/ipc/ipc_message_macros.h
@@ -42,9 +42,6 @@ // // Generate constructors. // #include "ipc/struct_constructor_macros.h" // #include "path/to/YYY_message_generator.h" -// // Generate destructors. -// #include "ipc/struct_destructor_macros.h" -// #include "path/to/YYY_message_generator.h" // // Generate param traits write methods. // #include "ipc/param_traits_write_macros.h" // namespace IPC { @@ -217,12 +214,7 @@ IPC_STRUCT_TRAITS_BEGIN(struct_name) \ IPC_STRUCT_TRAITS_END() \ struct IPC_MESSAGE_EXPORT struct_name : parent { \ - struct_name(); \ - struct_name(const struct_name&) = default; \ - struct_name(struct_name&&) = default; \ - struct_name& operator=(const struct_name&) = default; \ - struct_name& operator=(struct_name&&) = default; \ - ~struct_name(); + struct_name(); // Optional variadic parameters specify the default value for this struct // member. They are passed through to the constructor for |type|. #define IPC_STRUCT_MEMBER(type, name, ...) type name;
diff --git a/ipc/ipc_test_message_generator.cc b/ipc/ipc_test_message_generator.cc index c0e9c03..976ffae 100644 --- a/ipc/ipc_test_message_generator.cc +++ b/ipc/ipc_test_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "ipc/ipc_test_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "ipc/ipc_test_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/ipc/run_all_unittests.cc b/ipc/run_all_unittests.cc index bca29c6..2dd746f 100644 --- a/ipc/run_all_unittests.cc +++ b/ipc/run_all_unittests.cc
@@ -12,7 +12,7 @@ #include "mojo/core/embedder/scoped_ipc_support.h" #if defined(OS_MACOSX) && !defined(OS_IOS) -#include "base/mac/mach_port_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif int main(int argc, char** argv) { @@ -24,9 +24,8 @@ mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN); #if defined(OS_MACOSX) && !defined(OS_IOS) - base::MachPortBroker mach_broker("mojo_test"); - CHECK(mach_broker.Init()); - mojo::core::SetMachPortProvider(&mach_broker); + mojo::core::SetMachPortProvider( + mojo::core::DefaultMachBroker::Get()->port_provider()); #endif return base::LaunchUnitTests(
diff --git a/ipc/struct_destructor_macros.h b/ipc/struct_destructor_macros.h deleted file mode 100644 index ccb46f94..0000000 --- a/ipc/struct_destructor_macros.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright (c) 2011 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 IPC_STRUCT_DESTRUCTOR_MACROS_H_ -#define IPC_STRUCT_DESTRUCTOR_MACROS_H_ - -// Null out all the macros that need nulling. -#include "ipc/ipc_message_null_macros.h" - -// Set up so next include will generate destructors. -#undef IPC_STRUCT_BEGIN_WITH_PARENT -#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \ - struct_name::~struct_name() {} - -#endif // IPC_STRUCT_DESTRUCTOR_MACROS_H_ -
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc index d32bfec..5e9b952 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.cc +++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -153,9 +153,6 @@ ~InputBuffer() { CallDecodeCallbackIfAny(DecodeStatus::ABORTED); } - InputBuffer(InputBuffer&& other) = default; - InputBuffer& operator=(InputBuffer&& other) = default; - bool Initialize( const fuchsia::mediacodec::CodecBufferConstraints& constraints) { return buffer_.Initialize(constraints); @@ -218,9 +215,6 @@ public: OutputBuffer() = default; - OutputBuffer(OutputBuffer&& other) = default; - OutputBuffer& operator=(OutputBuffer&& other) = default; - bool Initialize( const fuchsia::mediacodec::CodecBufferConstraints& constraints) { if (!buffer_.Initialize(constraints)) {
diff --git a/media/gpu/ipc/common/media_message_generator.cc b/media/gpu/ipc/common/media_message_generator.cc index 9f3c3ab..3ad7518 100644 --- a/media/gpu/ipc/common/media_message_generator.cc +++ b/media/gpu/ipc/common/media_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "media/gpu/ipc/common/media_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "media/gpu/ipc/common/media_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/media/midi/midi_manager_unittest.cc b/media/midi/midi_manager_unittest.cc index 06d5a9a7..8bf2362 100644 --- a/media/midi/midi_manager_unittest.cc +++ b/media/midi/midi_manager_unittest.cc
@@ -14,9 +14,9 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/system/system_monitor.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "media/midi/midi_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -144,7 +144,7 @@ class MidiManagerTest : public ::testing::Test { public: - MidiManagerTest() : message_loop_(std::make_unique<base::MessageLoop>()) { + MidiManagerTest() { std::unique_ptr<FakeMidiManagerFactory> factory = std::make_unique<FakeMidiManagerFactory>(); factory_ = factory->GetWeakPtr(); @@ -217,7 +217,7 @@ base::WeakPtr<FakeMidiManagerFactory> factory() { return factory_; } private: - std::unique_ptr<base::MessageLoop> message_loop_; + base::test::ScopedTaskEnvironment env_; base::WeakPtr<FakeMidiManagerFactory> factory_; std::unique_ptr<MidiService> service_;
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 5469bf9..fb4d010 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn
@@ -7,7 +7,6 @@ import("//services/catalog/public/tools/catalog.gni") import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") -import("//services/service_manager/public/tools/test/service_test.gni") import("//testing/test.gni") jumbo_component("services") { @@ -225,7 +224,7 @@ ] } -service_test("media_service_unittests") { +test("media_service_unittests") { testonly = true sources = [ @@ -236,18 +235,19 @@ sources += [ "cdm_service_unittest.cc" ] } - catalog = ":service_tests_catalog" - deps = [ + ":service_tests_catalog_source", ":services", "//base", + "//base/test:test_support", "//media:test_support", "//media/cdm:cdm_paths", "//media/mojo/clients", "//media/mojo/common", "//media/mojo/interfaces", "//media/mojo/interfaces:constants", - "//services/service_manager/public/cpp:service_test_support", + "//mojo/core/test:run_all_unittests", + "//services/service_manager/public/cpp/test:test_support", "//testing/gmock", "//testing/gtest", ] @@ -262,39 +262,25 @@ source = "test_manifest.json" } -catalog("media_service_unittest_catalog") { +catalog("service_tests_catalog") { testonly = true embedded_services = [ ":media_service_unittest_manifest" ] standalone_services = [ ":media_manifest" ] } -service_manifest("cdm_service_unittest_manifest") { - name = "cdm_service_unittest" - source = "cdm_service_unittest_manifest.json" - packaged_services = [ ":cdm_manifest" ] -} - -catalog("cdm_service_unittest_catalog") { +catalog_cpp_source("service_tests_catalog_source") { testonly = true - embedded_services = [ ":cdm_service_unittest_manifest" ] -} - -catalog("service_tests_catalog") { - testonly = true - catalog_deps = [ - ":cdm_service_unittest_catalog", - ":media_service_unittest_catalog", - ] + catalog = ":service_tests_catalog" + generated_function_name = "media::test::CreateServiceTestCatalog" } # media_pipeline_integration_unittests is out of date and disabled by default. -service_test("media_pipeline_integration_unittests") { +test("media_pipeline_integration_unittests") { testonly = true - catalog = ":media_pipeline_integration_unittests_catalog" - deps = [ "//media/test:mojo_pipeline_integration_tests", + "//mojo/core/test:run_all_unittests", ] data_deps = [ @@ -311,3 +297,9 @@ embedded_services = [ ":pipeline_test_manifest" ] standalone_services = [ ":media_manifest" ] } + +catalog_cpp_source("media_pipeline_integration_unittests_catalog_source") { + testonly = true + catalog = ":media_pipeline_integration_unittests_catalog" + generated_function_name = "media::test::CreatePipelineIntegrationTestCatalog" +}
diff --git a/media/mojo/services/OWNERS b/media/mojo/services/OWNERS index da9d4b5c..5faebda 100644 --- a/media/mojo/services/OWNERS +++ b/media/mojo/services/OWNERS
@@ -1,9 +1,6 @@ per-file cdm_manifest.json=set noparent per-file cdm_manifest.json=file://ipc/SECURITY_OWNERS -per-file cdm_service_unittest_manifest.json=set noparent -per-file cdm_service_unittest_manifest.json=file://ipc/SECURITY_OWNERS - per-file media_manifest.json=set noparent per-file media_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/media/mojo/services/cdm_service.cc b/media/mojo/services/cdm_service.cc index 1fdc540..50d3439 100644 --- a/media/mojo/services/cdm_service.cc +++ b/media/mojo/services/cdm_service.cc
@@ -11,7 +11,6 @@ #include "media/mojo/services/mojo_cdm_service.h" #include "media/mojo/services/mojo_cdm_service_context.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/service_context.h" #if defined(OS_MACOSX) #include <vector> @@ -22,54 +21,11 @@ namespace { -using service_manager::ServiceContextRef; +using service_manager::ServiceKeepaliveRef; -constexpr base::TimeDelta kServiceContextRefReleaseDelay = +constexpr base::TimeDelta kKeepaliveIdleTimeout = base::TimeDelta::FromSeconds(5); -void DeleteServiceContextRef(ServiceContextRef* ref) { - delete ref; -} - -// Starting a new process and loading the library CDM could be expensive. This -// class helps delay the release of ServiceContextRef by -// |kServiceContextRefReleaseDelay|, which will ultimately delay CdmService -// destruction by the same delay as well. This helps reduce the chance of -// destroying the CdmService and immediately creates it (in another process) in -// cases like navigation, which could cause long service connection delays. -class DelayedReleaseServiceContextRef : public ServiceContextRef { - public: - DelayedReleaseServiceContextRef(std::unique_ptr<ServiceContextRef> ref, - base::TimeDelta delay) - : ref_(std::move(ref)), - delay_(delay), - task_runner_(base::ThreadTaskRunnerHandle::Get()) { - DCHECK_GT(delay_, base::TimeDelta()); - } - - ~DelayedReleaseServiceContextRef() override { - service_manager::ServiceContextRef* ref_ptr = ref_.release(); - if (!task_runner_->PostNonNestableDelayedTask( - FROM_HERE, base::BindOnce(&DeleteServiceContextRef, ref_ptr), - delay_)) { - DeleteServiceContextRef(ref_ptr); - } - } - - // ServiceContextRef implementation. - std::unique_ptr<ServiceContextRef> Clone() override { - NOTIMPLEMENTED(); - return nullptr; - } - - private: - std::unique_ptr<ServiceContextRef> ref_; - base::TimeDelta delay_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - DISALLOW_COPY_AND_ASSIGN(DelayedReleaseServiceContextRef); -}; - // Implementation of mojom::CdmFactory that creates and hosts MojoCdmServices // which then host CDMs created by the media::CdmFactory provided by the // CdmService::Client. @@ -77,12 +33,12 @@ // Lifetime Note: // 1. CdmFactoryImpl instances are owned by a DeferredDestroyStrongBindingSet // directly, which is owned by CdmService. -// 2. Note that CdmFactoryImpl also holds a ServiceContextRef to the CdmService. +// 2. Note that CdmFactoryImpl also holds a ServiceKeepaliveRef tied to the +// CdmService. // 3. CdmFactoryImpl is destroyed in any of the following two cases: // - CdmService is destroyed. Because of (2) this should not happen except for -// during browser shutdown, when the ServiceContext could be destroyed -// directly which will then destroy CdmService, ignoring any outstanding -// ServiceContextRefs. +// during browser shutdown, when the Cdservice could be destroyed directly, +// ignoring any outstanding ServiceKeepaliveRefs. // - mojo::CdmFactory connection error happens, AND CdmFactoryImpl doesn't own // any CDMs (|cdm_bindings_| is empty). This is to prevent destroying the // CDMs too early (e.g. during page navigation) which could cause errors @@ -92,10 +48,10 @@ public: CdmFactoryImpl(CdmService::Client* client, service_manager::mojom::InterfaceProviderPtr interfaces, - std::unique_ptr<ServiceContextRef> service_context_ref) + std::unique_ptr<ServiceKeepaliveRef> keepalive_ref) : client_(client), interfaces_(std::move(interfaces)), - service_context_ref_(std::move(service_context_ref)) { + keepalive_ref_(std::move(keepalive_ref)) { DVLOG(1) << __func__; // base::Unretained is safe because |cdm_bindings_| is owned by |this|. If @@ -151,7 +107,7 @@ CdmService::Client* client_; service_manager::mojom::InterfaceProviderPtr interfaces_; mojo::StrongBindingSet<mojom::ContentDecryptionModule> cdm_bindings_; - std::unique_ptr<ServiceContextRef> service_context_ref_; + std::unique_ptr<ServiceKeepaliveRef> keepalive_ref_; std::unique_ptr<media::CdmFactory> cdm_factory_; base::OnceClosure destroy_cb_; @@ -160,9 +116,13 @@ } // namespace -CdmService::CdmService(std::unique_ptr<Client> client) - : client_(std::move(client)), - service_release_delay_(kServiceContextRefReleaseDelay) { +CdmService::CdmService(std::unique_ptr<Client> client, + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), + keepalive_(std::make_unique<service_manager::ServiceKeepalive>( + &service_binding_, + kKeepaliveIdleTimeout)), + client_(std::move(client)) { DVLOG(1) << __func__; DCHECK(client_); registry_.AddInterface<mojom::CdmService>( @@ -173,11 +133,14 @@ DVLOG(1) << __func__; } +void CdmService::SetServiceReleaseDelayForTesting(base::TimeDelta delay) { + DCHECK(keepalive_->HasNoRefs()); + keepalive_ = std::make_unique<service_manager::ServiceKeepalive>( + &service_binding_, delay); +} + void CdmService::OnStart() { DVLOG(1) << __func__; - - ref_factory_.reset(new service_manager::ServiceContextRefFactory( - context()->CreateQuitClosure())); } void CdmService::OnBindInterface( @@ -189,10 +152,10 @@ registry_.BindInterface(interface_name, std::move(interface_pipe)); } -bool CdmService::OnServiceManagerConnectionLost() { +void CdmService::OnDisconnected() { cdm_factory_bindings_.CloseAllBindings(); client_.reset(); - return true; + Terminate(); } void CdmService::Create(mojom::CdmServiceRequest request) { @@ -265,16 +228,9 @@ if (!client_) return; - std::unique_ptr<ServiceContextRef> service_context_ref = - service_release_delay_ > base::TimeDelta() - ? std::make_unique<DelayedReleaseServiceContextRef>( - ref_factory_->CreateRef(), service_release_delay_) - : ref_factory_->CreateRef(); - cdm_factory_bindings_.AddBinding( - std::make_unique<CdmFactoryImpl>(client_.get(), - std::move(host_interfaces), - std::move(service_context_ref)), + std::make_unique<CdmFactoryImpl>( + client_.get(), std::move(host_interfaces), keepalive_->CreateRef()), std::move(request)); }
diff --git a/media/mojo/services/cdm_service.h b/media/mojo/services/cdm_service.h index 6777156..d6d16d4d 100644 --- a/media/mojo/services/cdm_service.h +++ b/media/mojo/services/cdm_service.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/macros.h" #include "build/build_config.h" #include "media/media_buildflags.h" #include "media/mojo/interfaces/cdm_service.mojom.h" @@ -16,7 +17,9 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/service_keepalive.h" +#include "services/service_manager/public/mojom/service.mojom.h" #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) #include "media/cdm/cdm_host_file.h" @@ -50,14 +53,13 @@ #endif // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) }; - explicit CdmService(std::unique_ptr<Client> client); + CdmService(std::unique_ptr<Client> client, + service_manager::mojom::ServiceRequest request); ~CdmService() final; // By default CdmService release is delayed. Overrides the delay with |delay|. // If |delay| is 0, delayed service release will be disabled. - void SetServiceReleaseDelayForTesting(base::TimeDelta delay) { - service_release_delay_ = delay; - } + void SetServiceReleaseDelayForTesting(base::TimeDelta delay); size_t BoundCdmFactorySizeForTesting() const { return cdm_factory_bindings_.size(); @@ -73,7 +75,7 @@ void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; - bool OnServiceManagerConnectionLost() final; + void OnDisconnected() final; void Create(mojom::CdmServiceRequest request); @@ -88,13 +90,15 @@ mojom::CdmFactoryRequest request, service_manager::mojom::InterfaceProviderPtr host_interfaces) final; - std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; + service_manager::ServiceBinding service_binding_; + std::unique_ptr<service_manager::ServiceKeepalive> keepalive_; std::unique_ptr<Client> client_; std::unique_ptr<CdmFactory> cdm_factory_; DeferredDestroyStrongBindingSet<mojom::CdmFactory> cdm_factory_bindings_; service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::CdmService> bindings_; - base::TimeDelta service_release_delay_; + + DISALLOW_COPY_AND_ASSIGN(CdmService); }; } // namespace media
diff --git a/media/mojo/services/cdm_service_unittest.cc b/media/mojo/services/cdm_service_unittest.cc index 90a9e99..158b08fc 100644 --- a/media/mojo/services/cdm_service_unittest.cc +++ b/media/mojo/services/cdm_service_unittest.cc
@@ -4,22 +4,17 @@ #include <memory> -#include "base/callback.h" +#include "base/bind.h" #include "base/files/file_path.h" -#include "base/path_service.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "media/cdm/default_cdm_factory.h" #include "media/media_buildflags.h" #include "media/mojo/interfaces/constants.mojom.h" #include "media/mojo/services/cdm_service.h" #include "media/mojo/services/media_interface_provider.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" -#include "services/service_manager/public/mojom/service_factory.mojom.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -59,90 +54,32 @@ #endif // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) }; -class ServiceTestClient : public service_manager::test::ServiceTestClient, - public service_manager::mojom::ServiceFactory { +class CdmServiceTest : public testing::Test { public: - explicit ServiceTestClient(service_manager::test::ServiceTest* test) - : service_manager::test::ServiceTestClient(test) { - registry_.AddInterface<service_manager::mojom::ServiceFactory>( - base::BindRepeating(&ServiceTestClient::Create, - base::Unretained(this))); - } - ~ServiceTestClient() override {} + CdmServiceTest() : connector_(test_connector_factory_.CreateConnector()) {} + ~CdmServiceTest() override = default; - // service_manager::Service implementation. - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override { - registry_.BindInterface(interface_name, std::move(interface_pipe)); - } - - // service_manager::mojom::ServiceFactory implementation. - void CreateService( - service_manager::mojom::ServiceRequest request, - const std::string& name, - service_manager::mojom::PIDReceiverPtr pid_receiver) override { - if (name != mojom::kCdmServiceName) - return; - - auto mock_cdm_service_client = std::make_unique<MockCdmServiceClient>(); - mock_cdm_service_client_ = mock_cdm_service_client.get(); - - auto cdm_service = - std::make_unique<CdmService>(std::move(mock_cdm_service_client)); - cdm_service_ = cdm_service.get(); - - cdm_service_->SetServiceReleaseDelayForTesting(service_release_delay_); - - service_context_ = std::make_unique<service_manager::ServiceContext>( - std::move(cdm_service), std::move(request)); - service_context_->SetQuitClosure(base::BindRepeating( - &ServiceTestClient::DestroyService, base::Unretained(this))); - } - - void SetServiceReleaseDelay(base::TimeDelta delay) { - service_release_delay_ = delay; - } - - void DestroyService() { service_context_.reset(); } - - MockCdmServiceClient* mock_cdm_service_client() { - return mock_cdm_service_client_; - } - - CdmService* cdm_service() { return cdm_service_; } - - private: - void Create(service_manager::mojom::ServiceFactoryRequest request) { - service_factory_bindings_.AddBinding(this, std::move(request)); - } - - // Delayed service release involves a posted delayed task which will not - // block *.RunUntilIdle() and hence cause a memory leak in the test. So by - // default use a zero value delay to disable the delay. - base::TimeDelta service_release_delay_; - - service_manager::BinderRegistry registry_; - mojo::BindingSet<service_manager::mojom::ServiceFactory> - service_factory_bindings_; - std::unique_ptr<service_manager::ServiceContext> service_context_; - CdmService* cdm_service_ = nullptr; - MockCdmServiceClient* mock_cdm_service_client_ = nullptr; -}; - -class CdmServiceTest : public service_manager::test::ServiceTest { - public: - CdmServiceTest() : ServiceTest("cdm_service_unittest") {} - ~CdmServiceTest() override {} + service_manager::Connector* connector() const { return connector_.get(); } MOCK_METHOD0(CdmServiceConnectionClosed, void()); MOCK_METHOD0(CdmFactoryConnectionClosed, void()); MOCK_METHOD0(CdmConnectionClosed, void()); void Initialize() { + auto mock_cdm_service_client = std::make_unique<MockCdmServiceClient>(); + mock_cdm_service_client_ = mock_cdm_service_client.get(); + + service_ = + std::make_unique<CdmService>(std::move(mock_cdm_service_client), + test_connector_factory_.RegisterInstance( + media::mojom::kCdmServiceName)); + service_->SetServiceReleaseDelayForTesting(service_release_delay_); + service_->set_termination_closure(base::BindOnce( + &CdmServiceTest::DestroyService, base::Unretained(this))); + connector()->BindInterface(media::mojom::kCdmServiceName, &cdm_service_ptr_); - cdm_service_ptr_.set_connection_error_handler(base::BindRepeating( + cdm_service_ptr_.set_connection_error_handler(base::BindOnce( &CdmServiceTest::CdmServiceConnectionClosed, base::Unretained(this))); service_manager::mojom::InterfaceProviderPtr interfaces; @@ -154,12 +91,12 @@ std::move(interfaces)); cdm_service_ptr_.FlushForTesting(); ASSERT_TRUE(cdm_factory_ptr_); - cdm_factory_ptr_.set_connection_error_handler(base::BindRepeating( + cdm_factory_ptr_.set_connection_error_handler(base::BindOnce( &CdmServiceTest::CdmFactoryConnectionClosed, base::Unretained(this))); } void InitializeWithServiceReleaseDelay(base::TimeDelta delay) { - service_test_client_->SetServiceReleaseDelay(delay); + service_release_delay_ = delay; Initialize(); } @@ -171,30 +108,42 @@ void InitializeCdm(const std::string& key_system, bool expected_result) { base::RunLoop run_loop; cdm_factory_ptr_->CreateCdm(key_system, mojo::MakeRequest(&cdm_ptr_)); - cdm_ptr_.set_connection_error_handler(base::BindRepeating( + cdm_ptr_.set_connection_error_handler(base::BindOnce( &CdmServiceTest::CdmConnectionClosed, base::Unretained(this))); EXPECT_CALL(*this, OnCdmInitialized(MatchesResult(expected_result), _, _)) .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); cdm_ptr_->Initialize(key_system, url::Origin::Create(GURL(kSecurityOrigin)), CdmConfig(), - base::BindRepeating(&CdmServiceTest::OnCdmInitialized, - base::Unretained(this))); + base::BindOnce(&CdmServiceTest::OnCdmInitialized, + base::Unretained(this))); run_loop.Run(); } - // service_manager::test::ServiceTest implementation. - std::unique_ptr<service_manager::Service> CreateService() override { - auto service_test_client = std::make_unique<ServiceTestClient>(this); - service_test_client_ = service_test_client.get(); - return service_test_client; + void DestroyService() { service_.reset(); } + + MockCdmServiceClient* mock_cdm_service_client() { + return mock_cdm_service_client_; } + CdmService* cdm_service() { return service_.get(); } + + base::test::ScopedTaskEnvironment task_environment_; mojom::CdmServicePtr cdm_service_ptr_; mojom::CdmFactoryPtr cdm_factory_ptr_; mojom::ContentDecryptionModulePtr cdm_ptr_; - ServiceTestClient* service_test_client_; private: + service_manager::TestConnectorFactory test_connector_factory_; + std::unique_ptr<service_manager::Connector> connector_; + + // Delayed service release involves a posted delayed task which will not + // block *.RunUntilIdle() and hence cause a memory leak in the test. So by + // default use a zero value delay to disable the delay. + base::TimeDelta service_release_delay_; + + std::unique_ptr<CdmService> service_; + MockCdmServiceClient* mock_cdm_service_client_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(CdmServiceTest); }; @@ -205,8 +154,7 @@ // Even with a dummy path where the CDM cannot be loaded, EnsureSandboxed() // should still be called to ensure the process is sandboxed. - EXPECT_CALL(*service_test_client_->mock_cdm_service_client(), - EnsureSandboxed()); + EXPECT_CALL(*mock_cdm_service_client(), EnsureSandboxed()); base::FilePath cdm_path(FILE_PATH_LITERAL("dummy path")); #if defined(OS_MACOSX) @@ -240,7 +188,7 @@ // destroyed after |cdm_ptr_| is reset. TEST_F(CdmServiceTest, DestroyCdmFactory) { Initialize(); - auto* service = service_test_client_->cdm_service(); + auto* service = cdm_service(); InitializeCdm(kClearKeyKeySystem, true); EXPECT_EQ(service->BoundCdmFactorySizeForTesting(), 1u); @@ -253,8 +201,9 @@ cdm_ptr_.reset(); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(service->BoundCdmFactorySizeForTesting(), 0u); - EXPECT_EQ(service->UnboundCdmFactorySizeForTesting(), 0u); + + // The service should be destroyed by the time we get here. + EXPECT_FALSE(cdm_service()); } // Same as DestroyCdmFactory test, but do not disable delayed service release. @@ -263,9 +212,9 @@ // the delay in the test. But currently FastForwardBy() doesn't support delayed // task yet. TEST_F(CdmServiceTest, DestroyCdmFactory_DelayedServiceRelease) { - constexpr base::TimeDelta kServiceContextRefReleaseDelay = + constexpr base::TimeDelta kKeepaliveIdleTimeout = base::TimeDelta::FromSeconds(1); - InitializeWithServiceReleaseDelay(kServiceContextRefReleaseDelay); + InitializeWithServiceReleaseDelay(kKeepaliveIdleTimeout); InitializeCdm(kClearKeyKeySystem, true); cdm_factory_ptr_.reset(); @@ -278,7 +227,7 @@ .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)); run_loop.Run(); auto time_passed = base::Time::Now() - start_time; - EXPECT_GE(time_passed, kServiceContextRefReleaseDelay); + EXPECT_GE(time_passed, kKeepaliveIdleTimeout); } // Destroy service will destroy the CdmFactory and all CDMs. @@ -293,7 +242,7 @@ EXPECT_CALL(*this, CdmFactoryConnectionClosed()); EXPECT_CALL(*this, CdmConnectionClosed()) .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)); - service_test_client_->DestroyService(); + DestroyService(); run_loop.Run(); }
diff --git a/media/mojo/services/cdm_service_unittest_manifest.json b/media/mojo/services/cdm_service_unittest_manifest.json deleted file mode 100644 index 9440910..0000000 --- a/media/mojo/services/cdm_service_unittest_manifest.json +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "name": "cdm_service_unittest", - "display_name": "CDM Service Unittest", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "service_manager:service_factory": [ - "service_manager.mojom.ServiceFactory" - ] - }, - "requires": { - "*": [ "app" ], - "cdm": [ "media:cdm" ] - } - } - } -}
diff --git a/media/mojo/services/interface_factory_impl.cc b/media/mojo/services/interface_factory_impl.cc index c1416ae..a2a103e 100644 --- a/media/mojo/services/interface_factory_impl.cc +++ b/media/mojo/services/interface_factory_impl.cc
@@ -44,7 +44,7 @@ InterfaceFactoryImpl::InterfaceFactoryImpl( service_manager::mojom::InterfaceProviderPtr interfaces, MediaLog* media_log, - std::unique_ptr<service_manager::ServiceContextRef> connection_ref, + std::unique_ptr<service_manager::ServiceKeepaliveRef> keepalive_ref, MojoMediaClient* mojo_media_client) : #if BUILDFLAG(ENABLE_MOJO_RENDERER) @@ -53,7 +53,7 @@ #if BUILDFLAG(ENABLE_MOJO_CDM) interfaces_(std::move(interfaces)), #endif - connection_ref_(std::move(connection_ref)), + keepalive_ref_(std::move(keepalive_ref)), mojo_media_client_(mojo_media_client) { DVLOG(1) << __func__; DCHECK(mojo_media_client_);
diff --git a/media/mojo/services/interface_factory_impl.h b/media/mojo/services/interface_factory_impl.h index 4de27e8..1de15a9 100644 --- a/media/mojo/services/interface_factory_impl.h +++ b/media/mojo/services/interface_factory_impl.h
@@ -14,7 +14,7 @@ #include "media/mojo/services/mojo_cdm_service_context.h" #include "mojo/public/cpp/bindings/strong_binding_set.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/service_manager/public/cpp/service_keepalive.h" namespace media { @@ -27,7 +27,7 @@ InterfaceFactoryImpl( service_manager::mojom::InterfaceProviderPtr interfaces, MediaLog* media_log, - std::unique_ptr<service_manager::ServiceContextRef> connection_ref, + std::unique_ptr<service_manager::ServiceKeepaliveRef> keepalive_ref, MojoMediaClient* mojo_media_client); ~InterfaceFactoryImpl() final; @@ -88,7 +88,7 @@ mojo::StrongBindingSet<mojom::Decryptor> decryptor_bindings_; - std::unique_ptr<service_manager::ServiceContextRef> connection_ref_; + std::unique_ptr<service_manager::ServiceKeepaliveRef> keepalive_ref_; MojoMediaClient* mojo_media_client_; base::OnceClosure destroy_cb_;
diff --git a/media/mojo/services/main.cc b/media/mojo/services/main.cc index d15e78b..1ffad7e 100644 --- a/media/mojo/services/main.cc +++ b/media/mojo/services/main.cc
@@ -2,24 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/at_exit.h" -#include "base/bind.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "media/mojo/services/media_service_factory.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/service_runner.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "media/mojo/services/media_service_factory.h" +#include "services/service_manager/public/mojom/service.mojom.h" -MojoResult ServiceMain(MojoHandle mojo_handle) { - // Enable logging. - service_manager::ServiceRunner::InitBaseCommandLine(); - +MojoResult ServiceMain(MojoHandle service_request_handle) { logging::LoggingSettings settings; settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; logging::InitLogging(settings); + base::MessageLoop message_loop; + base::RunLoop run_loop; std::unique_ptr<service_manager::Service> service = - media::CreateMediaServiceForTesting(); - service_manager::ServiceRunner runner(service.release()); - return runner.Run(mojo_handle, false /* init_base */); + media::CreateMediaServiceForTesting( + service_manager::mojom::ServiceRequest(mojo::ScopedMessagePipeHandle( + mojo::MessagePipeHandle(service_request_handle)))); + service->set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/media/mojo/services/media_service.cc b/media/mojo/services/media_service.cc index d27889d5..59799f9 100644 --- a/media/mojo/services/media_service.cc +++ b/media/mojo/services/media_service.cc
@@ -12,8 +12,11 @@ namespace media { -MediaService::MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client) - : mojo_media_client_(std::move(mojo_media_client)) { +MediaService::MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client, + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), + keepalive_(&service_binding_, base::TimeDelta{}), + mojo_media_client_(std::move(mojo_media_client)) { DCHECK(mojo_media_client_); registry_.AddInterface<mojom::MediaService>( base::Bind(&MediaService::Create, base::Unretained(this))); @@ -24,9 +27,7 @@ void MediaService::OnStart() { DVLOG(1) << __func__; - ref_factory_.reset(new service_manager::ServiceContextRefFactory( - context()->CreateQuitClosure())); - mojo_media_client_->Initialize(context()->connector()); + mojo_media_client_->Initialize(service_binding_.GetConnector()); } void MediaService::OnBindInterface( @@ -38,10 +39,10 @@ registry_.BindInterface(interface_name, std::move(interface_pipe)); } -bool MediaService::OnServiceManagerConnectionLost() { +void MediaService::OnDisconnected() { interface_factory_bindings_.CloseAllBindings(); mojo_media_client_.reset(); - return true; + Terminate(); } void MediaService::Create(mojom::MediaServiceRequest request) { @@ -57,7 +58,7 @@ interface_factory_bindings_.AddBinding( std::make_unique<InterfaceFactoryImpl>( - std::move(host_interfaces), &media_log_, ref_factory_->CreateRef(), + std::move(host_interfaces), &media_log_, keepalive_.CreateRef(), mojo_media_client_.get()), std::move(request)); }
diff --git a/media/mojo/services/media_service.h b/media/mojo/services/media_service.h index 0e4dc375..6a0b93f 100644 --- a/media/mojo/services/media_service.h +++ b/media/mojo/services/media_service.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/macros.h" #include "build/build_config.h" #include "media/base/media_log.h" #include "media/mojo/interfaces/interface_factory.mojom.h" @@ -16,8 +17,9 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/service_keepalive.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace media { @@ -26,7 +28,8 @@ class MEDIA_MOJO_EXPORT MediaService : public service_manager::Service, public mojom::MediaService { public: - explicit MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client); + MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client, + service_manager::mojom::ServiceRequest request); ~MediaService() final; private: @@ -35,7 +38,7 @@ void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; - bool OnServiceManagerConnectionLost() final; + void OnDisconnected() final; void Create(mojom::MediaServiceRequest request); @@ -44,7 +47,8 @@ service_manager::mojom::InterfaceProviderPtr host_interfaces) final; MediaLog media_log_; - std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; + service_manager::ServiceBinding service_binding_; + service_manager::ServiceKeepalive keepalive_; // Note: Since each instance runs on a different thread, do not share a common // MojoMediaClient with other instances to avoid threading issues. Hence using @@ -61,6 +65,8 @@ service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::MediaService> bindings_; + + DISALLOW_COPY_AND_ASSIGN(MediaService); }; } // namespace media
diff --git a/media/mojo/services/media_service_factory.cc b/media/mojo/services/media_service_factory.cc index 15063f7..1b5e95b 100644 --- a/media/mojo/services/media_service_factory.cc +++ b/media/mojo/services/media_service_factory.cc
@@ -17,12 +17,13 @@ namespace media { -std::unique_ptr<service_manager::Service> CreateMediaService() { +std::unique_ptr<service_manager::Service> CreateMediaService( + service_manager::mojom::ServiceRequest request) { #if defined(ENABLE_TEST_MOJO_MEDIA_CLIENT) - return CreateMediaServiceForTesting(); + return CreateMediaServiceForTesting(std::move(request)); #elif defined(OS_ANDROID) - return std::unique_ptr<service_manager::Service>( - new MediaService(std::make_unique<AndroidMojoMediaClient>())); + return std::make_unique<MediaService>( + std::make_unique<AndroidMojoMediaClient>(), std::move(request)); #else NOTREACHED() << "No MediaService implementation available."; return nullptr; @@ -30,6 +31,7 @@ } std::unique_ptr<service_manager::Service> CreateGpuMediaService( + service_manager::mojom::ServiceRequest request, const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, const gpu::GpuFeatureInfo& gpu_feature_info, @@ -37,16 +39,18 @@ base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager, AndroidOverlayMojoFactoryCB android_overlay_factory_cb, CdmProxyFactoryCB cdm_proxy_factory_cb) { - return std::unique_ptr<service_manager::Service>( - new MediaService(std::make_unique<GpuMojoMediaClient>( + return std::make_unique<MediaService>( + std::make_unique<GpuMojoMediaClient>( gpu_preferences, gpu_workarounds, gpu_feature_info, task_runner, media_gpu_channel_manager, std::move(android_overlay_factory_cb), - std::move(cdm_proxy_factory_cb)))); + std::move(cdm_proxy_factory_cb)), + std::move(request)); } -std::unique_ptr<service_manager::Service> CreateMediaServiceForTesting() { - return std::unique_ptr<service_manager::Service>( - new MediaService(std::make_unique<TestMojoMediaClient>())); +std::unique_ptr<service_manager::Service> CreateMediaServiceForTesting( + service_manager::mojom::ServiceRequest request) { + return std::make_unique<MediaService>(std::make_unique<TestMojoMediaClient>(), + std::move(request)); } } // namespace media
diff --git a/media/mojo/services/media_service_factory.h b/media/mojo/services/media_service_factory.h index d1bca61..abe15af8 100644 --- a/media/mojo/services/media_service_factory.h +++ b/media/mojo/services/media_service_factory.h
@@ -17,6 +17,7 @@ #include "media/cdm/cdm_proxy.h" #include "media/mojo/services/media_mojo_export.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace media { @@ -26,7 +27,7 @@ // platform. Uses the TestMojoMediaClient if |enable_test_mojo_media_client| is // true. std::unique_ptr<service_manager::Service> MEDIA_MOJO_EXPORT -CreateMediaService(); +CreateMediaService(service_manager::mojom::ServiceRequest request); // Creates a MediaService instance using the GpuMojoMediaClient. // |media_gpu_channel_manager| must only be used on |task_runner|, which is @@ -35,6 +36,7 @@ // CdmProxy is not supported on the platform. std::unique_ptr<service_manager::Service> MEDIA_MOJO_EXPORT CreateGpuMediaService( + service_manager::mojom::ServiceRequest requset, const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, const gpu::GpuFeatureInfo& gpu_feature_info, @@ -45,7 +47,7 @@ // Creates a MediaService instance using the TestMojoMediaClient. std::unique_ptr<service_manager::Service> MEDIA_MOJO_EXPORT -CreateMediaServiceForTesting(); +CreateMediaServiceForTesting(service_manager::mojom::ServiceRequest request); } // namespace media
diff --git a/media/mojo/services/media_service_unittest.cc b/media/mojo/services/media_service_unittest.cc index 26c2e08..d3c51ce 100644 --- a/media/mojo/services/media_service_unittest.cc +++ b/media/mojo/services/media_service_unittest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/task/post_task.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "media/base/cdm_config.h" #include "media/base/mock_filters.h" @@ -27,10 +28,13 @@ #include "media/mojo/interfaces/media_service.mojom.h" #include "media/mojo/interfaces/renderer.mojom.h" #include "media/mojo/services/media_interface_provider.h" +#include "media/mojo/services/service_tests_catalog_source.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -118,18 +122,20 @@ // TestMojoMediaClient supports CDM creation using DefaultCdmFactory (only // supports Clear Key key system), and Renderer creation using // DefaultRendererFactory that always create media::RendererImpl. -class MediaServiceTest : public service_manager::test::ServiceTest { +class MediaServiceTest : public testing::Test { public: MediaServiceTest() - : ServiceTest("media_service_unittests"), + : test_service_manager_(test::CreateServiceTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "media_service_unittests")), cdm_proxy_client_binding_(&cdm_proxy_client_), renderer_client_binding_(&renderer_client_), video_stream_(DemuxerStream::VIDEO) {} ~MediaServiceTest() override = default; - void SetUp() override { - ServiceTest::SetUp(); + service_manager::Connector* connector() { return test_service_.connector(); } + void SetUp() override { service_manager::mojom::InterfaceProviderPtr host_interfaces; auto provider = std::make_unique<MediaInterfaceProvider>( mojo::MakeRequest(&host_interfaces)); @@ -253,6 +259,10 @@ MOCK_METHOD0(MediaServiceConnectionClosed, void()); protected: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + mojom::MediaServicePtr media_service_; mojom::InterfaceFactoryPtr interface_factory_; mojom::ContentDecryptionModulePtr cdm_;
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn index d19d17f..00f2433 100644 --- a/media/test/BUILD.gn +++ b/media/test/BUILD.gn
@@ -69,7 +69,6 @@ "//base", "//media:test_support", "//media/mojo/clients", - "//services/service_manager/public/cpp:service_test_support", "//third_party/libaom:av1_buildflags", # Needed for the opus_config @@ -77,8 +76,8 @@ "//url", # TODO(dalecurtis): Required since the gmock header is included in the - # header for pipeline_integration_test_base.h. This should be moved into - # the .cc file to avoid the extra dependency here. + # header for pipeline_integration_test_base.h. This should be moved + # into the .cc file to avoid the extra dependency here. "//testing/gmock", ] } @@ -126,7 +125,8 @@ "//media/mojo/clients", "//media/mojo/interfaces", "//media/mojo/services", - "//services/service_manager/public/cpp:service_test_support", + "//media/mojo/services:media_pipeline_integration_unittests_catalog_source", + "//services/service_manager/public/cpp/test:test_support", "//testing/gtest", "//third_party/libaom:av1_buildflags", "//ui/gfx:test_support",
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index 0f438f44..a58f4bc 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -42,8 +42,9 @@ #include "media/mojo/clients/mojo_renderer.h" #include "media/mojo/interfaces/interface_factory.mojom.h" #include "media/mojo/interfaces/renderer.mojom.h" -#include "services/service_manager/public/cpp/connect.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "media/mojo/services/media_pipeline_integration_unittests_catalog_source.h" // nogncheck +#include "services/service_manager/public/cpp/test/test_service.h" // nogncheck +#include "services/service_manager/public/cpp/test/test_service_manager.h" // nogncheck // TODO(dalecurtis): The mojo renderer is in another process, so we have no way // currently to get hashes for video and audio samples. This also means that @@ -411,15 +412,15 @@ // preferably by eliminating multiple inheritance here which is // banned by Google C++ style. #if defined(MOJO_RENDERER) && defined(ENABLE_MOJO_PIPELINE_INTEGRATION_TEST) -class PipelineIntegrationTest : public service_manager::test::ServiceTest, +class PipelineIntegrationTest : public testing::Testing, public PipelineIntegrationTestBase { public: PipelineIntegrationTest() - : service_manager::test::ServiceTest( - "media_pipeline_integration_shelltests") {} + : test_service_manager_(test::CreatePipelineIntegrationTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "media_pipeline_integration_shelltests")) {} void SetUp() override { - ServiceTest::SetUp(); InitializeMediaLibrary(); } @@ -427,7 +428,8 @@ std::unique_ptr<Renderer> CreateRenderer( CreateVideoDecodersCB prepend_video_decoders_cb, CreateAudioDecodersCB prepend_audio_decoders_cb) override { - connector()->BindInterface("media", &media_interface_factory_); + test_service_.connector()->BindInterface("media", + &media_interface_factory_); mojom::RendererPtr mojo_renderer; media_interface_factory_->CreateRenderer(std::string(), @@ -438,6 +440,8 @@ } private: + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; mojom::InterfaceFactoryPtr media_interface_factory_; }; #else
diff --git a/mojo/core/embedder/BUILD.gn b/mojo/core/embedder/BUILD.gn index 47f1c390..774afe4 100644 --- a/mojo/core/embedder/BUILD.gn +++ b/mojo/core/embedder/BUILD.gn
@@ -16,6 +16,11 @@ "scoped_ipc_support.cc", ] + if (is_mac && !is_ios) { + public += [ "default_mach_broker.h" ] + sources += [ "default_mach_broker.cc" ] + } + defines = [ "IS_MOJO_CORE_EMBEDDER_IMPL" ] public_deps = [
diff --git a/mojo/core/embedder/default_mach_broker.cc b/mojo/core/embedder/default_mach_broker.cc new file mode 100644 index 0000000..436917a7 --- /dev/null +++ b/mojo/core/embedder/default_mach_broker.cc
@@ -0,0 +1,45 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/core/embedder/default_mach_broker.h" + +#include "base/logging.h" + +namespace mojo { +namespace core { + +namespace { +const char kBootstrapPortName[] = "mojo_default_mach_broker"; +} + +// static +void DefaultMachBroker::SendTaskPortToParent() { + bool result = + base::MachPortBroker::ChildSendTaskPortToParent(kBootstrapPortName); + DCHECK(result); +} + +// static +DefaultMachBroker* DefaultMachBroker::Get() { + static DefaultMachBroker* broker = new DefaultMachBroker; + return broker; +} + +DefaultMachBroker::DefaultMachBroker() : broker_(kBootstrapPortName) { + bool result = broker_.Init(); + DCHECK(result); +} + +DefaultMachBroker::~DefaultMachBroker() {} + +void DefaultMachBroker::ExpectPid(base::ProcessHandle pid) { + broker_.AddPlaceholderForPid(pid); +} + +void DefaultMachBroker::RemovePid(base::ProcessHandle pid) { + broker_.InvalidatePid(pid); +} + +} // namespace core +} // namespace mojo
diff --git a/mojo/core/embedder/default_mach_broker.h b/mojo/core/embedder/default_mach_broker.h new file mode 100644 index 0000000..2229ec1 --- /dev/null +++ b/mojo/core/embedder/default_mach_broker.h
@@ -0,0 +1,53 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_CORE_EMBEDDER_DEFAULT_MACH_BROKER_H_ +#define MOJO_CORE_EMBEDDER_DEFAULT_MACH_BROKER_H_ + +#include "base/component_export.h" +#include "base/mac/mach_port_broker.h" +#include "base/macros.h" + +namespace mojo { +namespace core { + +// A singleton Mojo embedders can use to manage task port brokering among +// connected processes. +class COMPONENT_EXPORT(MOJO_CORE_EMBEDDER) DefaultMachBroker { + public: + // Sends the task port of the current process to the parent over Mach IPC. + // For use in child processes. + static void SendTaskPortToParent(); + + // Returns the global |DefaultMachBroker|. + static DefaultMachBroker* Get(); + + // Registers |pid| with a MACH_PORT_NULL task port in the port provider. A + // child's pid must be registered before the broker will accept a task port + // from that child. + // + // Callers MUST have the lock acquired (see |GetLock()) while calling this. + void ExpectPid(base::ProcessHandle pid); + + // Removes |pid| from the port provider. + // + // Callers MUST have the lock acquired (see |GetLock()) while calling this. + void RemovePid(base::ProcessHandle pid); + + base::Lock& GetLock() { return broker_.GetLock(); } + base::PortProvider* port_provider() { return &broker_; } + + private: + DefaultMachBroker(); + ~DefaultMachBroker(); + + base::MachPortBroker broker_; + + DISALLOW_COPY_AND_ASSIGN(DefaultMachBroker); +}; + +} // namespace core +} // namespace mojo + +#endif // MOJO_CORE_EMBEDDER_DEFAULT_MACH_BROKER_H_
diff --git a/mojo/core/test/mojo_test_base.cc b/mojo/core/test/mojo_test_base.cc index 53f7101..cf3c7d9 100644 --- a/mojo/core/test/mojo_test_base.cc +++ b/mojo/core/test/mojo_test_base.cc
@@ -21,29 +21,16 @@ #if defined(OS_MACOSX) && !defined(OS_IOS) #include "base/mac/mach_port_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif namespace mojo { namespace core { namespace test { -#if defined(OS_MACOSX) && !defined(OS_IOS) -namespace { -base::MachPortBroker* g_mach_broker = nullptr; -} -#endif +MojoTestBase::MojoTestBase() = default; -MojoTestBase::MojoTestBase() { -#if defined(OS_MACOSX) && !defined(OS_IOS) - if (!g_mach_broker) { - g_mach_broker = new base::MachPortBroker("mojo_test"); - CHECK(g_mach_broker->Init()); - SetMachPortProvider(g_mach_broker); - } -#endif -} - -MojoTestBase::~MojoTestBase() {} +MojoTestBase::~MojoTestBase() = default; MojoTestBase::ClientController& MojoTestBase::StartClient( const std::string& client_name) { @@ -63,11 +50,12 @@ // launched. To prevent a race where the child process sends its task port // before the pid has been registered, the lock needs to be held over both // launch and child pid registration. - base::AutoLock lock(g_mach_broker->GetLock()); + auto* broker = DefaultMachBroker::Get(); + base::AutoLock lock(broker->GetLock()); #endif pipe_ = helper_.StartChild(client_name, launch_type); #if defined(OS_MACOSX) - g_mach_broker->AddPlaceholderForPid(helper_.test_child().Handle()); + broker->ExpectPid(helper_.test_child().Handle()); #endif #endif } @@ -82,8 +70,9 @@ #if !defined(OS_IOS) int retval = helper_.WaitForChildShutdown(); #if defined(OS_MACOSX) - base::AutoLock lock(g_mach_broker->GetLock()); - g_mach_broker->InvalidatePid(helper_.test_child().Handle()); + auto* broker = DefaultMachBroker::Get(); + base::AutoLock lock(broker->GetLock()); + broker->RemovePid(helper_.test_child().Handle()); #endif return retval; #else
diff --git a/mojo/core/test/multiprocess_test_helper.cc b/mojo/core/test/multiprocess_test_helper.cc index 3f5173cc..803a2fa9 100644 --- a/mojo/core/test/multiprocess_test_helper.cc +++ b/mojo/core/test/multiprocess_test_helper.cc
@@ -35,7 +35,7 @@ #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_MACOSX) && !defined(OS_IOS) -#include "base/mac/mach_port_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif #if !defined(OS_FUCHSIA) @@ -249,7 +249,7 @@ bool run_as_broker_client = command_line.HasSwitch(kRunAsBrokerClient); #if defined(OS_MACOSX) && !defined(OS_IOS) if (run_as_broker_client) - CHECK(base::MachPortBroker::ChildSendTaskPortToParent("mojo_test")); + DefaultMachBroker::SendTaskPortToParent(); #endif PlatformChannelEndpoint endpoint;
diff --git a/mojo/core/test/run_all_unittests.cc b/mojo/core/test/run_all_unittests.cc index 974dfde..5bc8ccb 100644 --- a/mojo/core/test/run_all_unittests.cc +++ b/mojo/core/test/run_all_unittests.cc
@@ -18,6 +18,10 @@ #include "mojo/public/tests/test_support_private.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_MACOSX) && !defined(OS_IOS) +#include "mojo/core/embedder/default_mach_broker.h" +#endif + int main(int argc, char** argv) { #if !defined(OS_ANDROID) // Silence death test thread warnings on Linux. We can afford to run our death @@ -38,6 +42,11 @@ mojo::core::Init(); +#if defined(OS_MACOSX) && !defined(OS_IOS) + mojo::core::SetMachPortProvider( + mojo::core::DefaultMachBroker::Get()->port_provider()); +#endif + mojo::test::TestSupport::Init(new mojo::core::test::TestSupportImpl()); base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
diff --git a/ppapi/proxy/ppapi_messages.cc b/ppapi/proxy/ppapi_messages.cc index 8ff3a9dd..a0c0991 100644 --- a/ppapi/proxy/ppapi_messages.cc +++ b/ppapi/proxy/ppapi_messages.cc
@@ -18,14 +18,6 @@ #error "Failed to include ppapi/proxy/ppapi_messages.h" #endif -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#undef PPAPI_PROXY_PPAPI_MESSAGES_H_ -#include "ppapi/proxy/ppapi_messages.h" -#ifndef PPAPI_PROXY_PPAPI_MESSAGES_H_ -#error "Failed to include ppapi/proxy/ppapi_messages.h" -#endif - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/remoting/host/chromoting_messages.cc b/remoting/host/chromoting_messages.cc index 36c3cf4..d966a20 100644 --- a/remoting/host/chromoting_messages.cc +++ b/remoting/host/chromoting_messages.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "remoting/host/chromoting_messages.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "remoting/host/chromoting_messages.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/services/BUILD.gn b/services/BUILD.gn index 4e4c493..7bdb10fc 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -95,7 +95,6 @@ if (!is_ios) { catalog_deps += [ - "//services/audio:tests_catalog", "//services/device:tests_catalog", "//services/preferences:tests_catalog", "//services/resource_coordinator:tests_catalog",
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn index 3e90841..c2afb19 100644 --- a/services/audio/BUILD.gn +++ b/services/audio/BUILD.gn
@@ -178,6 +178,7 @@ deps = [ ":audio", ":lib", + ":tests_catalog_source", "//base/test:test_support", "//media:test_support", "//mojo/core/embedder", @@ -185,7 +186,6 @@ "//services/audio/public/cpp:test_support", "//services/audio/public/mojom", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", "//services/service_manager/public/cpp/test:test_support", "//testing/gmock", "//testing/gtest", @@ -213,6 +213,12 @@ embedded_services = [ ":unittest_manifest" ] } +catalog_cpp_source("tests_catalog_source") { + testonly = true + catalog = ":tests_catalog" + generated_function_name = "audio::CreateUnittestCatalog" +} + # Standalone tests support. if (standalone_supported) { service_manifest("standalone_unittest_manifest") {
diff --git a/services/audio/public/cpp/fake_system_info.cc b/services/audio/public/cpp/fake_system_info.cc index a02af7a..7f2d047 100644 --- a/services/audio/public/cpp/fake_system_info.cc +++ b/services/audio/public/cpp/fake_system_info.cc
@@ -5,8 +5,7 @@ #include "services/audio/public/cpp/fake_system_info.h" #include "services/audio/public/mojom/constants.mojom.h" -#include "services/service_manager/public/cpp/bind_source_info.h" -#include "services/service_manager/public/cpp/service_context.h" +#include "services/service_manager/public/cpp/service_binding.h" namespace audio { @@ -17,16 +16,16 @@ // static void FakeSystemInfo::OverrideGlobalBinderForAudioService( FakeSystemInfo* fake_system_info) { - service_manager::ServiceContext::SetGlobalBinderForTesting( - mojom::kServiceName, mojom::SystemInfo::Name_, + service_manager::ServiceBinding::OverrideInterfaceBinderForTesting( + mojom::kServiceName, base::BindRepeating(&FakeSystemInfo::Bind, base::Unretained(fake_system_info))); } // static void FakeSystemInfo::ClearGlobalBinderForAudioService() { - service_manager::ServiceContext::ClearGlobalBindersForTesting( - mojom::kServiceName); + service_manager::ServiceBinding ::ClearInterfaceBinderOverrideForTesting< + mojom::SystemInfo>(mojom::kServiceName); } void FakeSystemInfo::GetInputStreamParameters( @@ -70,11 +69,8 @@ std::move(callback).Run(base::nullopt, base::nullopt); } -void FakeSystemInfo::Bind(const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle, - const service_manager::BindSourceInfo& source_info) { - DCHECK(interface_name == mojom::SystemInfo::Name_); - bindings_.AddBinding(this, mojom::SystemInfoRequest(std::move(handle))); +void FakeSystemInfo::Bind(mojom::SystemInfoRequest request) { + bindings_.AddBinding(this, std::move(request)); } } // namespace audio
diff --git a/services/audio/public/cpp/fake_system_info.h b/services/audio/public/cpp/fake_system_info.h index 6a75e08b..4f6a341 100644 --- a/services/audio/public/cpp/fake_system_info.h +++ b/services/audio/public/cpp/fake_system_info.h
@@ -12,10 +12,6 @@ #include "mojo/public/cpp/system/message_pipe.h" #include "services/audio/public/mojom/system_info.mojom.h" -namespace service_manager { -struct BindSourceInfo; -} - namespace audio { // An instance of this class can be used to override the global binding for @@ -51,9 +47,7 @@ GetInputDeviceInfoCallback callback) override; private: - void Bind(const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle, - const service_manager::BindSourceInfo& source_info); + void Bind(mojom::SystemInfoRequest request); mojo::BindingSet<mojom::SystemInfo> bindings_; DISALLOW_COPY_AND_ASSIGN(FakeSystemInfo);
diff --git a/services/audio/service.cc b/services/audio/service.cc index 7cb4be0..ef4fb4a8 100644 --- a/services/audio/service.cc +++ b/services/audio/service.cc
@@ -19,8 +19,6 @@ #include "services/audio/log_factory_manager.h" #include "services/audio/service_metrics.h" #include "services/audio/system_info.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_context_ref.h" #if defined(OS_MACOSX) #include "media/audio/mac/audio_device_listener_mac.h" @@ -37,8 +35,10 @@ Service::Service(std::unique_ptr<AudioManagerAccessor> audio_manager_accessor, base::TimeDelta quit_timeout, bool enable_remote_client_support, - std::unique_ptr<service_manager::BinderRegistry> registry) - : quit_timeout_(quit_timeout), + std::unique_ptr<service_manager::BinderRegistry> registry, + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), + keepalive_(&service_binding_, quit_timeout), audio_manager_accessor_(std::move(audio_manager_accessor)), enable_remote_client_support_(enable_remote_client_support), registry_(std::move(registry)) { @@ -66,9 +66,6 @@ metrics_.reset(); g_service_state_for_crashing.Set("destructing - killed metrics"); - // |ref_factory_| may reentrantly call its |quit_closure| when we reset the - // members below. Destroy it ahead of time to prevent this. - ref_factory_.reset(); g_service_state_for_crashing.Set("destructing - killed ref_factory"); // Stop all streams cleanly before shutting down the audio manager. @@ -96,9 +93,6 @@ metrics_ = std::make_unique<ServiceMetrics>(base::DefaultTickClock::GetInstance()); - ref_factory_ = std::make_unique<service_manager::ServiceContextRefFactory>( - base::BindRepeating(&Service::MaybeRequestQuitDelayed, - base::Unretained(this))); registry_->AddInterface<mojom::SystemInfo>(base::BindRepeating( &Service::BindSystemInfoRequest, base::Unretained(this))); registry_->AddInterface<mojom::DebugRecording>(base::BindRepeating( @@ -119,38 +113,30 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); - DCHECK(ref_factory_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); g_service_state_for_crashing.Set("binding " + interface_name); TRACE_EVENT1("audio", "audio::Service::OnBindInterface", "interface", interface_name); - if (ref_factory_->HasNoRefs()) + if (keepalive_.HasNoRefs()) metrics_->HasConnections(); registry_->BindInterface(interface_name, std::move(interface_pipe)); - DCHECK(!ref_factory_->HasNoRefs()); - quit_timer_.AbandonAndStop(); + DCHECK(!keepalive_.HasNoRefs()); + g_service_state_for_crashing.Set("bound " + interface_name); } -bool Service::OnServiceManagerConnectionLost() { +void Service::OnDisconnected() { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); g_service_state_for_crashing.Set("connection lost"); - return true; -} - -void Service::SetQuitClosureForTesting(base::RepeatingClosure quit_closure) { - CHECK_EQ(magic_bytes_, 0x600DC0DEu); - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - quit_closure_ = std::move(quit_closure); + Terminate(); } void Service::BindSystemInfoRequest(mojom::SystemInfoRequest request) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_); if (!system_info_) { system_info_ = std::make_unique<SystemInfo>( @@ -158,14 +144,13 @@ } system_info_->Bind( std::move(request), - TracedServiceRef(ref_factory_->CreateRef(), "audio::SystemInfo Binding")); + TracedServiceRef(keepalive_.CreateRef(), "audio::SystemInfo Binding")); } void Service::BindDebugRecordingRequest(mojom::DebugRecordingRequest request) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_); - TracedServiceRef service_ref(ref_factory_->CreateRef(), + TracedServiceRef service_ref(keepalive_.CreateRef(), "audio::DebugRecording Binding"); // Accept only one bind request at a time. Old request is overwritten. @@ -180,19 +165,17 @@ void Service::BindStreamFactoryRequest(mojom::StreamFactoryRequest request) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_); if (!stream_factory_) stream_factory_.emplace(audio_manager_accessor_->GetAudioManager()); - stream_factory_->Bind(std::move(request), - TracedServiceRef(ref_factory_->CreateRef(), - "audio::StreamFactory Binding")); + stream_factory_->Bind( + std::move(request), + TracedServiceRef(keepalive_.CreateRef(), "audio::StreamFactory Binding")); } void Service::BindDeviceNotifierRequest(mojom::DeviceNotifierRequest request) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_); DCHECK(enable_remote_client_support_); if (!system_monitor_) { @@ -203,7 +186,7 @@ if (!device_notifier_) device_notifier_ = std::make_unique<DeviceNotifier>(); device_notifier_->Bind(std::move(request), - TracedServiceRef(ref_factory_->CreateRef(), + TracedServiceRef(keepalive_.CreateRef(), "audio::DeviceNotifier Binding")); } @@ -211,35 +194,13 @@ mojom::LogFactoryManagerRequest request) { CHECK_EQ(magic_bytes_, 0x600DC0DEu); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_); DCHECK(log_factory_manager_); DCHECK(enable_remote_client_support_); log_factory_manager_->Bind( - std::move(request), TracedServiceRef(ref_factory_->CreateRef(), + std::move(request), TracedServiceRef(keepalive_.CreateRef(), "audio::LogFactoryManager Binding")); } -void Service::MaybeRequestQuitDelayed() { - CHECK_EQ(magic_bytes_, 0x600DC0DEu); - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - metrics_->HasNoConnections(); - if (quit_timeout_ <= base::TimeDelta()) - return; - quit_timer_.Start(FROM_HERE, quit_timeout_, this, &Service::MaybeRequestQuit); -} - -void Service::MaybeRequestQuit() { - CHECK_EQ(magic_bytes_, 0x600DC0DEu); - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ref_factory_ && ref_factory_->HasNoRefs() && - quit_timeout_ > base::TimeDelta()); - TRACE_EVENT0("audio", "audio::Service::MaybeRequestQuit"); - - context()->CreateQuitClosure().Run(); - if (!quit_closure_.is_null()) - quit_closure_.Run(); -} - void Service::InitializeDeviceMonitor() { CHECK_EQ(magic_bytes_, 0x600DC0DEu); #if defined(OS_MACOSX)
diff --git a/services/audio/service.h b/services/audio/service.h index 98aa6f12..67979e3 100644 --- a/services/audio/service.h +++ b/services/audio/service.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/optional.h" #include "base/threading/thread_checker.h" -#include "base/timer/timer.h" #include "build/build_config.h" #include "services/audio/public/mojom/debug_recording.mojom.h" #include "services/audio/public/mojom/device_notifications.mojom.h" @@ -22,6 +21,9 @@ #include "services/audio/stream_factory.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/service_keepalive.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace base { class SystemMonitor; @@ -33,10 +35,6 @@ class AudioLogFactory; } // namespace media -namespace service_manager { -class ServiceContextRefFactory; -} - namespace audio { class DebugRecording; class DeviceNotifier; @@ -74,7 +72,8 @@ Service(std::unique_ptr<AudioManagerAccessor> audio_manager_accessor, base::TimeDelta quit_timeout, bool enable_remote_client_support, - std::unique_ptr<service_manager::BinderRegistry> registry); + std::unique_ptr<service_manager::BinderRegistry> registry, + service_manager::mojom::ServiceRequest request); ~Service() final; // service_manager::Service implementation. @@ -82,9 +81,7 @@ void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) final; - bool OnServiceManagerConnectionLost() final; - - void SetQuitClosureForTesting(base::RepeatingClosure quit_closure); + void OnDisconnected() final; private: void BindSystemInfoRequest(mojom::SystemInfoRequest request); @@ -93,9 +90,6 @@ void BindDeviceNotifierRequest(mojom::DeviceNotifierRequest request); void BindLogFactoryManagerRequest(mojom::LogFactoryManagerRequest request); - void MaybeRequestQuitDelayed(); - void MaybeRequestQuit(); - // Initializes a platform-specific device monitor for device-change // notifications. If the client uses the DeviceNotifier interface to get // notifications this function should be called before the DeviceMonitor is @@ -107,10 +101,10 @@ // AudioManager provided by AudioManagerAccessor. THREAD_CHECKER(thread_checker_); - // The members below should outlive |ref_factory_|. + service_manager::ServiceBinding service_binding_; + service_manager::ServiceKeepalive keepalive_; + base::RepeatingClosure quit_closure_; - const base::TimeDelta quit_timeout_; - base::OneShotTimer quit_timer_; std::unique_ptr<AudioManagerAccessor> audio_manager_accessor_; const bool enable_remote_client_support_; @@ -127,8 +121,6 @@ std::unique_ptr<service_manager::BinderRegistry> registry_; - std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; - // TODO(crbug.com/888478): Remove this after diagnosis. volatile uint32_t magic_bytes_;
diff --git a/services/audio/service_factory.cc b/services/audio/service_factory.cc index 09a64d7a..92ea461 100644 --- a/services/audio/service_factory.cc +++ b/services/audio/service_factory.cc
@@ -16,7 +16,6 @@ #include "services/audio/in_process_audio_manager_accessor.h" #include "services/audio/owning_audio_manager_accessor.h" #include "services/audio/service.h" -#include "services/service_manager/public/cpp/service.h" namespace audio { @@ -55,22 +54,24 @@ } // namespace -std::unique_ptr<service_manager::Service> CreateEmbeddedService( - media::AudioManager* audio_manager) { +std::unique_ptr<Service> CreateEmbeddedService( + media::AudioManager* audio_manager, + service_manager::mojom::ServiceRequest request) { return std::make_unique<Service>( std::make_unique<InProcessAudioManagerAccessor>(audio_manager), base::TimeDelta() /* do not quit if all clients disconnected */, false /* enable_device_notifications */, - std::make_unique<service_manager::BinderRegistry>()); + std::make_unique<service_manager::BinderRegistry>(), std::move(request)); } -std::unique_ptr<service_manager::Service> CreateStandaloneService( - std::unique_ptr<service_manager::BinderRegistry> registry) { +std::unique_ptr<Service> CreateStandaloneService( + std::unique_ptr<service_manager::BinderRegistry> registry, + service_manager::mojom::ServiceRequest request) { return std::make_unique<Service>( std::make_unique<audio::OwningAudioManagerAccessor>( base::BindOnce(&media::AudioManager::Create)), GetQuitTimeout(), true /* enable_remote_client_support */, - std::move(registry)); + std::move(registry), std::move(request)); } } // namespace audio
diff --git a/services/audio/service_factory.h b/services/audio/service_factory.h index b294139..7fc85ab 100644 --- a/services/audio/service_factory.h +++ b/services/audio/service_factory.h
@@ -7,11 +7,9 @@ #include <memory> +#include "services/audio/service.h" #include "services/service_manager/public/cpp/binder_registry.h" - -namespace service_manager { -class Service; -} +#include "services/service_manager/public/mojom/service.mojom.h" namespace media { class AudioManager; @@ -22,13 +20,15 @@ // Creates an instance of Audio service which will live in the current process // on top of AudioManager instance belonging to that process. Must be called on // the device thread of AudioManager. -std::unique_ptr<service_manager::Service> CreateEmbeddedService( - media::AudioManager* audio_manager); +std::unique_ptr<Service> CreateEmbeddedService( + media::AudioManager* audio_manager, + service_manager::mojom::ServiceRequest request); // Creates an instance of Audio service which will live in the current process // and will create and own an AudioManager instance. -std::unique_ptr<service_manager::Service> CreateStandaloneService( - std::unique_ptr<service_manager::BinderRegistry> registry); +std::unique_ptr<Service> CreateStandaloneService( + std::unique_ptr<service_manager::BinderRegistry> registry, + service_manager::mojom::ServiceRequest request); } // namespace audio
diff --git a/services/audio/service_main.cc b/services/audio/service_main.cc index 1e983fc..b774903 100644 --- a/services/audio/service_main.cc +++ b/services/audio/service_main.cc
@@ -2,17 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "services/audio/service.h" #include "services/audio/service_factory.h" #include "services/service_manager/public/c/main.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/service_runner.h" - +#include "services/service_manager/public/mojom/service.mojom.h" MojoResult ServiceMain(MojoHandle service_request_handle) { - return service_manager::ServiceRunner( - audio::CreateStandaloneService( - std::make_unique<service_manager::BinderRegistry>()) - .release()) - .Run(service_request_handle); + base::MessageLoop message_loop; + base::RunLoop run_loop; + std::unique_ptr<audio::Service> service = audio::CreateStandaloneService( + std::make_unique<service_manager::BinderRegistry>(), + service_manager::mojom::ServiceRequest(mojo::ScopedMessagePipeHandle( + mojo::MessagePipeHandle(service_request_handle)))); + service->set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/services/audio/test/debug_recording_session_unittest.cc b/services/audio/test/debug_recording_session_unittest.cc index f0fa576..030d7b2 100644 --- a/services/audio/test/debug_recording_session_unittest.cc +++ b/services/audio/test/debug_recording_session_unittest.cc
@@ -17,8 +17,9 @@ #include "media/audio/audio_debug_recording_test.h" #include "media/audio/mock_audio_debug_recording_manager.h" #include "media/audio/mock_audio_manager.h" +#include "services/audio/public/mojom/constants.mojom.h" +#include "services/audio/service.h" #include "services/audio/service_factory.h" -#include "services/service_manager/public/cpp/service_test.h" #include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,10 +90,10 @@ CreateAudioManager(); InitializeAudioDebugRecordingManager(); - connector_factory_ = - service_manager::TestConnectorFactory::CreateForUniqueService( - CreateEmbeddedService( - static_cast<media::AudioManager*>(mock_audio_manager_.get()))); + service_ = CreateEmbeddedService( + static_cast<media::AudioManager*>(mock_audio_manager_.get()), + connector_factory_.RegisterInstance(audio::mojom::kServiceName)); + scoped_task_environment_.RunUntilIdle(); } @@ -103,7 +104,7 @@ std::unique_ptr<DebugRecordingSession> session( std::make_unique<DebugRecordingSession>( base::FilePath(kBaseFileName), - connector_factory_->CreateConnector())); + connector_factory_.CreateConnector())); scoped_task_environment_.RunUntilIdle(); return session; } @@ -115,7 +116,8 @@ } private: - std::unique_ptr<service_manager::TestConnectorFactory> connector_factory_; + service_manager::TestConnectorFactory connector_factory_; + std::unique_ptr<Service> service_; DISALLOW_COPY_AND_ASSIGN(DebugRecordingSessionTest); };
diff --git a/services/audio/test/in_process_service_test.cc b/services/audio/test/in_process_service_test.cc index 2dd2d3c..3fb4779 100644 --- a/services/audio/test/in_process_service_test.cc +++ b/services/audio/test/in_process_service_test.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/scoped_task_environment.h" #include "media/audio/audio_system_test_util.h" #include "media/audio/mock_audio_manager.h" #include "media/audio/test_audio_thread.h" @@ -12,17 +13,20 @@ #include "services/audio/public/mojom/constants.mojom.h" #include "services/audio/service.h" #include "services/audio/test/service_lifetime_test_template.h" +#include "services/audio/tests_catalog_source.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" #include "services/service_manager/public/mojom/service_factory.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" using testing::Exactly; using testing::Invoke; namespace audio { -class ServiceTestClient : public service_manager::test::ServiceTestClient, +class ServiceTestHelper : public service_manager::Service, public service_manager::mojom::ServiceFactory { public: class AudioThreadContext @@ -42,55 +46,57 @@ this, std::move(request))); return; } - DCHECK(!service_context_); - service_context_ = std::make_unique<service_manager::ServiceContext>( - std::make_unique<audio::Service>( - std::make_unique<InProcessAudioManagerAccessor>(audio_manager_), - service_quit_timeout_, false /* device_notifications_enabled */, - std::make_unique<service_manager::BinderRegistry>()), + DCHECK(!service_); + service_ = std::make_unique<audio::Service>( + std::make_unique<InProcessAudioManagerAccessor>(audio_manager_), + service_quit_timeout_, false /* device_notifications_enabled */, + std::make_unique<service_manager::BinderRegistry>(), std::move(request)); - service_context_->SetQuitClosure(base::BindRepeating( + service_->set_termination_closure(base::BindOnce( &AudioThreadContext::QuitOnAudioThread, base::Unretained(this))); } void QuitOnAudioThread() { - if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) { - audio_manager_->GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&AudioThreadContext::QuitOnAudioThread, this)); - return; - } - service_context_.reset(); + DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); + service_.reset(); } private: friend class base::RefCountedThreadSafe<AudioThreadContext>; - virtual ~AudioThreadContext() { - if (service_context_) - service_context_->QuitNow(); - } + virtual ~AudioThreadContext() = default; media::AudioManager* const audio_manager_; const base::TimeDelta service_quit_timeout_; - std::unique_ptr<service_manager::ServiceContext> service_context_; + std::unique_ptr<Service> service_; + + DISALLOW_COPY_AND_ASSIGN(AudioThreadContext); }; - ServiceTestClient(service_manager::test::ServiceTest* test, - media::AudioManager* audio_manager, - base::TimeDelta service_quit_timeout) - : service_manager::test::ServiceTestClient(test), + ServiceTestHelper(media::AudioManager* audio_manager, + base::TimeDelta service_quit_timeout, + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), + audio_manager_(audio_manager), audio_thread_context_( new AudioThreadContext(audio_manager, service_quit_timeout)) { registry_.AddInterface<service_manager::mojom::ServiceFactory>( - base::BindRepeating(&ServiceTestClient::Create, + base::BindRepeating(&ServiceTestHelper::Create, base::Unretained(this))); } - ~ServiceTestClient() override {} + ~ServiceTestHelper() override { + // Ensure that the AudioThreadContext is destroyed on the correct thread by + // passing our only reference into a task posted there. + audio_manager_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AudioThreadContext::QuitOnAudioThread, + std::move(audio_thread_context_))); + } + + service_manager::Connector* connector() { + return service_binding_.GetConnector(); + } protected: - bool OnServiceManagerConnectionLost() override { return true; } - void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override { @@ -111,11 +117,14 @@ } private: + service_manager::ServiceBinding service_binding_; service_manager::BinderRegistry registry_; mojo::BindingSet<service_manager::mojom::ServiceFactory> service_factory_bindings_; + media::AudioManager* const audio_manager_; scoped_refptr<AudioThreadContext> audio_thread_context_; - DISALLOW_COPY_AND_ASSIGN(ServiceTestClient); + + DISALLOW_COPY_AND_ASSIGN(ServiceTestHelper); }; // if |use_audio_thread| is true, AudioManager has a dedicated audio thread and @@ -125,11 +134,18 @@ // thread it lives on (which imitates access to Audio service from UI thread on // Mac). template <bool use_audio_thread> -class InProcessServiceTest : public service_manager::test::ServiceTest { +class InProcessServiceTest : public testing::Test { public: explicit InProcessServiceTest(base::TimeDelta service_quit_timeout) - : ServiceTest("audio_unittests"), - service_quit_timeout_(service_quit_timeout) {} + : test_service_manager_(CreateUnittestCatalog()), + audio_manager_( + std::make_unique<media::TestAudioThread>(use_audio_thread)), + helper_(std::make_unique<ServiceTestHelper>( + &audio_manager_, + service_quit_timeout, + test_service_manager_.RegisterTestInstance("audio_unittests"))), + audio_system_(std::make_unique<AudioSystemToServiceAdapter>( + connector()->Clone())) {} InProcessServiceTest() : InProcessServiceTest(base::TimeDelta() /* not timeout */) {} @@ -137,41 +153,34 @@ ~InProcessServiceTest() override {} protected: - // service_manager::test::ServiceTest: - std::unique_ptr<service_manager::Service> CreateService() override { - return std::make_unique<ServiceTestClient>(this, audio_manager_.get(), - service_quit_timeout_); - } - - void SetUp() override { - audio_manager_ = std::make_unique<media::MockAudioManager>( - std::make_unique<media::TestAudioThread>(use_audio_thread)); - ServiceTest::SetUp(); - audio_system_ = - std::make_unique<AudioSystemToServiceAdapter>(connector()->Clone()); + service_manager::Connector* connector() { + DCHECK(helper_); + return helper_->connector(); } void TearDown() override { audio_system_.reset(); - // Deletes ServiceTestClient, which will result in posting + // Deletes ServiceTestHelper, which will result in posting // AuioThreadContext::QuitOnAudioThread() to AudioManager thread, so that // Service is delete there. - ServiceTest::TearDown(); + helper_.reset(); // Joins AudioManager thread if it is used. - audio_manager_->Shutdown(); + audio_manager_.Shutdown(); } protected: - media::MockAudioManager* audio_manager() { return audio_manager_.get(); } + media::MockAudioManager* audio_manager() { return &audio_manager_; } media::AudioSystem* audio_system() { return audio_system_.get(); } - std::unique_ptr<media::MockAudioManager> audio_manager_; + private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + media::MockAudioManager audio_manager_; + std::unique_ptr<ServiceTestHelper> helper_; std::unique_ptr<media::AudioSystem> audio_system_; - private: - const base::TimeDelta service_quit_timeout_; DISALLOW_COPY_AND_ASSIGN(InProcessServiceTest); };
diff --git a/services/audio/test/service_lifetime_connector_test.cc b/services/audio/test/service_lifetime_connector_test.cc index bdc45ba..5bdc4bb 100644 --- a/services/audio/test/service_lifetime_connector_test.cc +++ b/services/audio/test/service_lifetime_connector_test.cc
@@ -35,16 +35,13 @@ audio_manager_ = std::make_unique<media::MockAudioManager>( std::make_unique<media::TestAudioThread>( false /*not using a separate audio thread*/)); - std::unique_ptr<Service> service_impl = std::make_unique<Service>( + service_ = std::make_unique<Service>( std::make_unique<InProcessAudioManagerAccessor>(audio_manager_.get()), kQuitTimeout, false /* device_notifications_enabled */, - std::make_unique<service_manager::BinderRegistry>()); - service_ = service_impl.get(); - service_->SetQuitClosureForTesting(quit_request_.Get()); - connector_factory_ = - service_manager::TestConnectorFactory::CreateForUniqueService( - std::move(service_impl)); - connector_ = connector_factory_->CreateConnector(); + std::make_unique<service_manager::BinderRegistry>(), + connector_factory_.RegisterInstance(mojom::kServiceName)); + service_->set_termination_closure(quit_request_.Get()); + connector_ = connector_factory_.CreateConnector(); } void TearDown() override { audio_manager_->Shutdown(); } @@ -55,9 +52,9 @@ StrictMock<base::MockCallback<base::RepeatingClosure>> quit_request_; std::unique_ptr<media::MockAudioManager> audio_manager_; - std::unique_ptr<service_manager::TestConnectorFactory> connector_factory_; + service_manager::TestConnectorFactory connector_factory_; + std::unique_ptr<Service> service_; std::unique_ptr<service_manager::Connector> connector_; - Service* service_ = nullptr; private: DISALLOW_COPY_AND_ASSIGN(AudioServiceLifetimeConnectorTest);
diff --git a/services/audio/test/service_lifetime_test_template.h b/services/audio/test/service_lifetime_test_template.h index c02e74e1..b87cabb3 100644 --- a/services/audio/test/service_lifetime_test_template.h +++ b/services/audio/test/service_lifetime_test_template.h
@@ -9,7 +9,6 @@ #include "services/audio/public/mojom/constants.mojom.h" #include "services/audio/public/mojom/system_info.mojom.h" #include "services/audio/test/service_observer_mock.h" -#include "services/service_manager/public/cpp/service_context.h" namespace audio {
diff --git a/services/audio/test/standalone_service_test.cc b/services/audio/test/standalone_service_test.cc index 24712f3..960e3a3 100644 --- a/services/audio/test/standalone_service_test.cc +++ b/services/audio/test/standalone_service_test.cc
@@ -4,35 +4,38 @@ #include "base/command_line.h" #include "base/strings/string_number_conversions.h" +#include "base/test/scoped_task_environment.h" #include "media/base/media_switches.h" #include "services/audio/service.h" #include "services/audio/standalone_unittest_catalog_source.h" #include "services/audio/test/service_lifetime_test_template.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" +#include "testing/gtest/include/gtest/gtest.h" namespace audio { -class StandaloneAudioServiceTest : public service_manager::test::ServiceTest { +class StandaloneAudioServiceTest : public testing::Test { public: - StandaloneAudioServiceTest() : ServiceTest("audio_unittests") {} - - ~StandaloneAudioServiceTest() override {} + StandaloneAudioServiceTest() + : test_service_manager_(CreateStandaloneUnittestCatalog()), + test_service_( + test_service_manager_.RegisterTestInstance("audio_unittests")) {} protected: - // service_manager::test::ServiceTest: - std::unique_ptr<base::Value> CreateCustomTestCatalog() override { - return audio::CreateStandaloneUnittestCatalog(); - } + service_manager::Connector* connector() { return test_service_.connector(); } void SetUp() override { - ServiceTest::SetUp(); base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); cmd_line->AppendSwitchASCII(switches::kAudioServiceQuitTimeoutMs, base::UintToString(10)); } private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + DISALLOW_COPY_AND_ASSIGN(StandaloneAudioServiceTest); };
diff --git a/services/identity/public/cpp/primary_account_mutator.h b/services/identity/public/cpp/primary_account_mutator.h index 77acabb..e2ba816 100644 --- a/services/identity/public/cpp/primary_account_mutator.h +++ b/services/identity/public/cpp/primary_account_mutator.h
@@ -85,7 +85,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - base::RepeatingCallback<void(const std::string&)> callback) = 0; + base::OnceCallback<void(const std::string&)> callback) = 0; // Complete the in-process sign-in (legacy, pre-DICE workflow). virtual void LegacyCompletePendingPrimaryAccountSignin() = 0;
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.cc b/services/identity/public/cpp/primary_account_mutator_impl.cc index 060564b9..e6135213 100644 --- a/services/identity/public/cpp/primary_account_mutator_impl.cc +++ b/services/identity/public/cpp/primary_account_mutator_impl.cc
@@ -72,7 +72,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - base::RepeatingCallback<void(const std::string&)> callback) { + base::OnceCallback<void(const std::string&)> callback) { NOTIMPLEMENTED(); }
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.h b/services/identity/public/cpp/primary_account_mutator_impl.h index 635235ba..45643e4 100644 --- a/services/identity/public/cpp/primary_account_mutator_impl.h +++ b/services/identity/public/cpp/primary_account_mutator_impl.h
@@ -36,7 +36,7 @@ const std::string& gaia_id, const std::string& username, const std::string& password, - base::RepeatingCallback<void(const std::string&)> callback) override; + base::OnceCallback<void(const std::string&)> callback) override; void LegacyCompletePendingPrimaryAccountSignin() override; void LegacyMergeSigninCredentialIntoCookieJar() override; bool LegacyIsPrimaryAccountAuthInProgress() const override;
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index d9a8aaa..01c835bd5 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -502,6 +502,8 @@ base::Optional<std::string> CorsURLLoader::GetHeaderString( const ResourceResponseHead& response, const std::string& header_name) { + if (!response.headers) + return base::nullopt; std::string header_value; if (!response.headers->GetNormalizedHeader(header_name, &header_value)) return base::nullopt;
diff --git a/services/network/public/cpp/net_ipc_param_traits.cc b/services/network/public/cpp/net_ipc_param_traits.cc index 1250cda..03bbf4b 100644 --- a/services/network/public/cpp/net_ipc_param_traits.cc +++ b/services/network/public/cpp/net_ipc_param_traits.cc
@@ -568,11 +568,6 @@ #include "ipc/struct_constructor_macros.h" #include "net_ipc_param_traits.h" -// Generate destructors. -#undef SERVICES_NETWORK_PUBLIC_CPP_NET_IPC_PARAM_TRAITS_H_ -#include "ipc/struct_destructor_macros.h" -#include "net_ipc_param_traits.h" - // Generate param traits write methods. #undef SERVICES_NETWORK_PUBLIC_CPP_NET_IPC_PARAM_TRAITS_H_ #include "ipc/param_traits_write_macros.h"
diff --git a/services/network/public/cpp/network_ipc_param_traits.cc b/services/network/public/cpp/network_ipc_param_traits.cc index fbbdb82..b11b822 100644 --- a/services/network/public/cpp/network_ipc_param_traits.cc +++ b/services/network/public/cpp/network_ipc_param_traits.cc
@@ -265,11 +265,6 @@ #include "ipc/struct_constructor_macros.h" #include "network_ipc_param_traits.h" -// Generate destructors. -#undef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_IPC_PARAM_TRAITS_H_ -#include "ipc/struct_destructor_macros.h" -#include "network_ipc_param_traits.h" - // Generate param traits write methods. #undef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_IPC_PARAM_TRAITS_H_ #include "ipc/param_traits_write_macros.h"
diff --git a/services/network/public/cpp/p2p_param_traits.cc b/services/network/public/cpp/p2p_param_traits.cc index 2028a285..37c6c5c 100644 --- a/services/network/public/cpp/p2p_param_traits.cc +++ b/services/network/public/cpp/p2p_param_traits.cc
@@ -67,11 +67,6 @@ #include "ipc/struct_constructor_macros.h" #include "p2p_param_traits.h" -// Generate destructors. -#undef SERVICES_NETWORK_PUBLIC_CPP_P2P_PARAM_TRAITS_H_ -#include "ipc/struct_destructor_macros.h" -#include "p2p_param_traits.h" - // Generate param traits write methods. #undef SERVICES_NETWORK_PUBLIC_CPP_P2P_PARAM_TRAITS_H_ #include "ipc/param_traits_write_macros.h"
diff --git a/services/service_manager/public/cpp/service.cc b/services/service_manager/public/cpp/service.cc index d1ab5f1..2b49e25 100644 --- a/services/service_manager/public/cpp/service.cc +++ b/services/service_manager/public/cpp/service.cc
@@ -13,6 +13,13 @@ Service::~Service() = default; +// static +void Service::RunUntilTermination(std::unique_ptr<Service> service) { + auto* raw_service = service.get(); + raw_service->set_termination_closure(base::BindOnce( + [](std::unique_ptr<Service> service) {}, std::move(service))); +} + void Service::OnStart() {} void Service::OnBindInterface(const BindSourceInfo& source,
diff --git a/services/service_manager/public/cpp/service.h b/services/service_manager/public/cpp/service.h index b7ad7d4..f316a404 100644 --- a/services/service_manager/public/cpp/service.h +++ b/services/service_manager/public/cpp/service.h
@@ -24,6 +24,16 @@ Service(); virtual ~Service(); + // Transfers ownership of |service| to itself such that self-termination via + // |Terminate()| is also self-deletion. Note that most services implicitly + // call |Terminate()| when disconnected from the Service Manager, via the + // default implementation of |OnDisconnected()|. + // + // This should really only be called on a Service instance that has a bound + // connection to the Service Manager, e.g. a functioning ServiceBinding. If + // the service never calls |Terminate()|, it will effectively leak. + static void RunUntilTermination(std::unique_ptr<Service> service); + // Sets a closure to run when the service wants to self-terminate. This may be // used by whomever created the Service instance in order to clean up // associated resources.
diff --git a/services/service_manager/public/cpp/service_binding.cc b/services/service_manager/public/cpp/service_binding.cc index ed8c57a..745aea53 100644 --- a/services/service_manager/public/cpp/service_binding.cc +++ b/services/service_manager/public/cpp/service_binding.cc
@@ -7,12 +7,68 @@ #include <utility> #include "base/bind.h" +#include "base/no_destructor.h" +#include "base/synchronization/lock.h" #include "services/service_manager/public/cpp/service.h" -#include "base/debug/stack_trace.h" - namespace service_manager { +namespace { + +// Thread-safe mapping of all registered binder overrides in the process. +class BinderOverrides { + public: + BinderOverrides() = default; + ~BinderOverrides() = default; + + void SetOverride(const std::string& service_name, + const std::string& interface_name, + const ServiceBinding::BinderForTesting& binder) { + base::AutoLock lock(lock_); + binders_[service_name][interface_name] = binder; + } + + ServiceBinding::BinderForTesting GetOverride( + const std::string& service_name, + const std::string& interface_name) { + base::AutoLock lock(lock_); + auto service_it = binders_.find(service_name); + if (service_it == binders_.end()) + return ServiceBinding::BinderForTesting(); + auto binder_it = service_it->second.find(interface_name); + if (binder_it == service_it->second.end()) + return ServiceBinding::BinderForTesting(); + return binder_it->second; + } + + void ClearOverride(const std::string& service_name, + const std::string& interface_name) { + base::AutoLock lock(lock_); + auto service_it = binders_.find(service_name); + if (service_it == binders_.end()) + return; + service_it->second.erase(interface_name); + if (service_it->second.empty()) + binders_.erase(service_it); + } + + private: + base::Lock lock_; + + using InterfaceBinderMap = + std::map<std::string, ServiceBinding::BinderForTesting>; + std::map<std::string, InterfaceBinderMap> binders_; + + DISALLOW_COPY_AND_ASSIGN(BinderOverrides); +}; + +BinderOverrides& GetBinderOverrides() { + static base::NoDestructor<BinderOverrides> overrides; + return *overrides; +} + +} // namespace + ServiceBinding::ServiceBinding(service_manager::Service* service) : service_(service), binding_(this) { DCHECK(service_); @@ -60,6 +116,21 @@ connector_.reset(); } +// static +void ServiceBinding::OverrideInterfaceBinderForTesting( + const std::string& service_name, + const std::string& interface_name, + const BinderForTesting& binder) { + GetBinderOverrides().SetOverride(service_name, interface_name, binder); +} + +// static +void ServiceBinding::ClearInterfaceBinderOverrideForTesting( + const std::string& service_name, + const std::string& interface_name) { + GetBinderOverrides().ClearOverride(service_name, interface_name); +} + void ServiceBinding::OnConnectionError() { service_->OnDisconnected(); } @@ -88,6 +159,13 @@ // Acknowledge this request. std::move(callback).Run(); + auto override = + GetBinderOverrides().GetOverride(identity_.name(), interface_name); + if (override) { + override.Run(std::move(interface_pipe)); + return; + } + service_->OnBindInterface(source_info, interface_name, std::move(interface_pipe)); }
diff --git a/services/service_manager/public/cpp/service_binding.h b/services/service_manager/public/cpp/service_binding.h index 668c7e3..dcdfb2d 100644 --- a/services/service_manager/public/cpp/service_binding.h +++ b/services/service_manager/public/cpp/service_binding.h
@@ -97,6 +97,41 @@ // Must only be called on a bound ServiceBinding. void Close(); + // Allows the caller to intercept all requests for a specific interface + // targeting any instance of the service |service_name| running in the calling + // process. Prefer the template helpers for clarity. + using BinderForTesting = + base::RepeatingCallback<void(mojo::ScopedMessagePipeHandle)>; + static void OverrideInterfaceBinderForTesting( + const std::string& service_name, + const std::string& interface_name, + const BinderForTesting& binder); + static void ClearInterfaceBinderOverrideForTesting( + const std::string& service_name, + const std::string& interface_name); + + template <typename Interface> + using TypedBinderForTesting = + base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>)>; + template <typename Interface> + static void OverrideInterfaceBinderForTesting( + const std::string& service_name, + const TypedBinderForTesting<Interface>& binder) { + ServiceBinding::OverrideInterfaceBinderForTesting( + service_name, Interface::Name_, + base::BindRepeating( + [](const TypedBinderForTesting<Interface>& binder, + mojo::ScopedMessagePipeHandle pipe) { + binder.Run(mojo::InterfaceRequest<Interface>(std::move(pipe))); + }, + binder)); + } + template <typename Interface> + static void ClearInterfaceBinderOverrideForTesting( + const std::string& service_name) { + ClearInterfaceBinderOverrideForTesting(service_name, Interface::Name_); + } + private: void OnConnectionError();
diff --git a/services/service_manager/public/cpp/service_keepalive.h b/services/service_manager/public/cpp/service_keepalive.h index ae4b3376..6d93cf7 100644 --- a/services/service_manager/public/cpp/service_keepalive.h +++ b/services/service_manager/public/cpp/service_keepalive.h
@@ -20,6 +20,9 @@ class ServiceBinding; class ServiceContext; +// TODO: Rename ServiceContextRef everywhere. +using ServiceKeepaliveRef = ServiceContextRef; + // Helper class which vends ServiceContextRefs from its own // ServiceContextRefFactory. Whenever the ref count goes to zero, this starts an // idle timer (configured at construction time). If the timer runs out before @@ -64,7 +67,7 @@ base::Optional<base::TimeDelta> idle_timeout); ~ServiceKeepalive(); - std::unique_ptr<ServiceContextRef> CreateRef(); + std::unique_ptr<ServiceKeepaliveRef> CreateRef(); bool HasNoRefs(); void AddObserver(Observer* observer);
diff --git a/services/service_manager/public/cpp/standalone_service/BUILD.gn b/services/service_manager/public/cpp/standalone_service/BUILD.gn index b656a14d8..25ed83d 100644 --- a/services/service_manager/public/cpp/standalone_service/BUILD.gn +++ b/services/service_manager/public/cpp/standalone_service/BUILD.gn
@@ -32,13 +32,6 @@ "//sandbox/linux:seccomp_bpf", ] } - - if (is_mac) { - sources += [ - "mach_broker.cc", - "mach_broker.h", - ] - } } # Service executable targets should link against this to get a boilerplate entry
diff --git a/services/service_manager/public/cpp/standalone_service/mach_broker.cc b/services/service_manager/public/cpp/standalone_service/mach_broker.cc deleted file mode 100644 index a9cc00f..0000000 --- a/services/service_manager/public/cpp/standalone_service/mach_broker.cc +++ /dev/null
@@ -1,43 +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. - -#include "services/service_manager/public/cpp/standalone_service/mach_broker.h" - -#include "base/logging.h" - -namespace service_manager { - -namespace { -const char kBootstrapPortName[] = "mojo_service_manager"; -} - -// static -void MachBroker::SendTaskPortToParent() { - bool result = base::MachPortBroker::ChildSendTaskPortToParent( - kBootstrapPortName); - DCHECK(result); -} - -// static -MachBroker* MachBroker::GetInstance() { - static MachBroker* broker = new MachBroker; - return broker; -} - -MachBroker::MachBroker() : broker_(kBootstrapPortName) { - bool result = broker_.Init(); - DCHECK(result); -} - -MachBroker::~MachBroker() {} - -void MachBroker::ExpectPid(base::ProcessHandle pid) { - broker_.AddPlaceholderForPid(pid); -} - -void MachBroker::RemovePid(base::ProcessHandle pid) { - broker_.InvalidatePid(pid); -} - -} // namespace service_manager
diff --git a/services/service_manager/public/cpp/standalone_service/mach_broker.h b/services/service_manager/public/cpp/standalone_service/mach_broker.h deleted file mode 100644 index a85b0fc..0000000 --- a/services/service_manager/public/cpp/standalone_service/mach_broker.h +++ /dev/null
@@ -1,48 +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. - -#ifndef SERVICES_SERVICE_MANAGER_PUBLIC_CPP_STANDALONE_SERVICE_MACH_BROKER_H_ -#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_STANDALONE_SERVICE_MACH_BROKER_H_ - -#include "base/mac/mach_port_broker.h" - -namespace service_manager { - -// A global singleton |MachBroker| is used by the service manager to provide -// access to -// Mach task ports for service manager out-of-process applications. -class MachBroker { - public: - // Sends the task port of the current process to the parent over Mach IPC. - // For use in child processes. - static void SendTaskPortToParent(); - - // Returns the global |MachBroker|. For use in the service manager. - static MachBroker* GetInstance(); - - // Registers |pid| with a MACH_PORT_NULL task port in the port provider. A - // child's pid must be registered before the broker will accept a task port - // from that child. - // Callers MUST acquire the lock given by GetLock() before calling this method - // (and release the lock afterwards). - void ExpectPid(base::ProcessHandle pid); - - // Removes |pid| from the port provider. - // Callers MUST acquire the lock given by GetLock() before calling this method - // (and release the lock afterwards). - void RemovePid(base::ProcessHandle pid); - - base::Lock& GetLock() { return broker_.GetLock(); } - base::PortProvider* port_provider() { return &broker_; } - - private: - MachBroker(); - ~MachBroker(); - - base::MachPortBroker broker_; -}; - -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_STANDALONE_SERVICE_MACH_BROKER_H_
diff --git a/services/service_manager/public/cpp/standalone_service/standalone_service.cc b/services/service_manager/public/cpp/standalone_service/standalone_service.cc index d904cb8b4..3febd43 100644 --- a/services/service_manager/public/cpp/standalone_service/standalone_service.cc +++ b/services/service_manager/public/cpp/standalone_service/standalone_service.cc
@@ -31,7 +31,7 @@ #endif #if defined(OS_MACOSX) -#include "services/service_manager/public/cpp/standalone_service/mach_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif namespace service_manager { @@ -41,7 +41,7 @@ #if defined(OS_MACOSX) // Send our task port to the parent. - MachBroker::SendTaskPortToParent(); + mojo::core::DefaultMachBroker::SendTaskPortToParent(); #endif const base::CommandLine& command_line =
diff --git a/services/service_manager/public/cpp/test/common_initialization.cc b/services/service_manager/public/cpp/test/common_initialization.cc index 1f5bbd5..4c2b853 100644 --- a/services/service_manager/public/cpp/test/common_initialization.cc +++ b/services/service_manager/public/cpp/test/common_initialization.cc
@@ -18,7 +18,7 @@ #endif #if defined(OS_MACOSX) && !defined(OS_IOS) -#include "services/service_manager/public/cpp/standalone_service/mach_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif namespace service_manager { @@ -33,7 +33,7 @@ #if defined(OS_MACOSX) && !defined(OS_IOS) mojo::core::SetMachPortProvider( - service_manager::MachBroker::GetInstance()->port_provider()); + mojo::core::DefaultMachBroker::Get()->port_provider()); #endif base::Thread ipc_thread("IPC thread");
diff --git a/services/service_manager/runner/host/BUILD.gn b/services/service_manager/runner/host/BUILD.gn index bb8316bd..6ab647f 100644 --- a/services/service_manager/runner/host/BUILD.gn +++ b/services/service_manager/runner/host/BUILD.gn
@@ -42,7 +42,10 @@ "service_process_launcher.h", ] - deps += [ "//services/service_manager/public/cpp/standalone_service" ] + deps += [ + "//mojo/core/embedder", + "//services/service_manager/public/cpp/standalone_service", + ] } }
diff --git a/services/service_manager/runner/host/service_process_launcher.cc b/services/service_manager/runner/host/service_process_launcher.cc index 26f2cb1..92fef03 100644 --- a/services/service_manager/runner/host/service_process_launcher.cc +++ b/services/service_manager/runner/host/service_process_launcher.cc
@@ -40,7 +40,7 @@ #endif #if defined(OS_MACOSX) -#include "services/service_manager/public/cpp/standalone_service/mach_broker.h" +#include "mojo/core/embedder/default_mach_broker.h" #endif namespace service_manager { @@ -198,7 +198,8 @@ #endif { #if defined(OS_MACOSX) - MachBroker* mach_broker = MachBroker::GetInstance(); + mojo::core::DefaultMachBroker* mach_broker = + mojo::core::DefaultMachBroker::Get(); base::AutoLock locker(mach_broker->GetLock()); #endif child_process_ = base::LaunchProcess(*child_command_line, options);
diff --git a/services/service_manager/standalone/context.cc b/services/service_manager/standalone/context.cc index ecfd8572..99d15a48 100644 --- a/services/service_manager/standalone/context.cc +++ b/services/service_manager/standalone/context.cc
@@ -37,10 +37,6 @@ #include "services/service_manager/runner/host/service_process_launcher.h" #endif -#if defined(OS_MACOSX) -#include "services/service_manager/public/cpp/standalone_service/mach_broker.h" -#endif - namespace service_manager { namespace {
diff --git a/services/shape_detection/shape_detection_service.cc b/services/shape_detection/shape_detection_service.cc index 53f5944..60403a4b 100644 --- a/services/shape_detection/shape_detection_service.cc +++ b/services/shape_detection/shape_detection_service.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/macros.h" -#include "services/service_manager/public/cpp/service_context.h" #if defined(OS_WIN) #include "services/shape_detection/barcode_detection_provider_impl.h" #include "services/shape_detection/face_detection_provider_win.h" @@ -30,11 +29,9 @@ namespace shape_detection { -std::unique_ptr<service_manager::Service> ShapeDetectionService::Create() { - return std::make_unique<ShapeDetectionService>(); -} - -ShapeDetectionService::ShapeDetectionService() { +ShapeDetectionService::ShapeDetectionService( + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)) { #if defined(OS_MACOSX) if (__builtin_available(macOS 10.13, *)) { vision_framework_ = @@ -53,9 +50,6 @@ } void ShapeDetectionService::OnStart() { - ref_factory_.reset(new service_manager::ServiceContextRefFactory( - context()->CreateQuitClosure())); - #if defined(OS_ANDROID) registry_.AddInterface( GetJavaInterfaces()
diff --git a/services/shape_detection/shape_detection_service.h b/services/shape_detection/shape_detection_service.h index 893f089..cc09f97 100644 --- a/services/shape_detection/shape_detection_service.h +++ b/services/shape_detection/shape_detection_service.h
@@ -13,16 +13,15 @@ #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context_ref.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace shape_detection { class ShapeDetectionService : public service_manager::Service { public: - // Factory function for use as an embedded service. - static std::unique_ptr<service_manager::Service> Create(); - - ShapeDetectionService(); + explicit ShapeDetectionService( + service_manager::mojom::ServiceRequest request); ~ShapeDetectionService() override; void OnStart() override; @@ -41,7 +40,7 @@ void* vision_framework_; #endif - std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; + service_manager::ServiceBinding service_binding_; service_manager::BinderRegistry registry_; DISALLOW_COPY_AND_ASSIGN(ShapeDetectionService);
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index aa0d049..d36dc71 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -59,6 +59,7 @@ # New failures are appended below by the script. crbug.com/591099 animations/rotate-transform-equivalent.html [ Failure ] +crbug.com/591099 bluetooth/characteristic/notifications/notification-after-disconnection.html [ Pass ] crbug.com/728378 compositing/culling/tile-occlusion-boundaries.html [ Failure ] crbug.com/864398 compositing/iframes/floating-self-painting-frame.html [ Failure ] crbug.com/591099 compositing/overflow/border-radius-above-composited-subframe.html [ Failure ] @@ -70,6 +71,19 @@ crbug.com/591099 css3/selectors3/xml/css3-modsel-38.xml [ Failure ] crbug.com/591099 editing/selection/drag-in-iframe.html [ Failure ] crbug.com/591099 editing/selection/paint-hyphen.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/requestDevice/cross-origin-iframe.sub.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/requestDevice/request-from-iframe.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/requestDevice/request-from-sandboxed-iframe.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/disconnect/detach-gc.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/disconnect/gc-detach.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/getPrimaryService/gen-discovery-complete-no-permission-absent-service.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/getPrimaryService/gen-discovery-complete-service-not-found.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/getPrimaryService/two-iframes-from-same-origin.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/getPrimaryServices/gen-discovery-complete-no-permission-absent-service-with-uuid.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/server/getPrimaryServices/gen-discovery-complete-service-not-found-with-uuid.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/service/getCharacteristic/gen-reconnect-during.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.https.html [ Pass ] +crbug.com/591099 external/wpt/bluetooth/service/getCharacteristics/gen-reconnect-during.https.html [ Pass ] crbug.com/591099 external/wpt/css/CSS2/abspos/abspos-in-block-in-inline-in-relpos-inline.html [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/float-nowrap-3.html [ Pass ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-line-wrap-shifted-001.html [ Pass ] @@ -237,9 +251,9 @@ crbug.com/591099 external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Pass ] crbug.com/591099 external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] crbug.com/591099 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] crbug.com/591099 external/wpt/html/browsers/history/joint-session-history/joint-session-history-remove-iframe.html [ Timeout ] -crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Crash Pass ] +crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Pass ] crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_parent [ Timeout ] crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_self [ Timeout ] crbug.com/591099 external/wpt/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html [ Timeout ] @@ -265,7 +279,6 @@ crbug.com/591099 fast/css-intrinsic-dimensions/height-positioned.html [ Pass ] crbug.com/807708 fast/css-intrinsic-dimensions/width-avoid-floats.html [ Failure ] crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ] -crbug.com/591099 fast/css/acid2.html [ Pass ] crbug.com/591099 fast/css/css-properties-position-relative-as-parent-fixed.html [ Failure ] crbug.com/835484 fast/css/focus-ring-recursive-continuations.html [ Failure ] crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ] @@ -311,7 +324,7 @@ crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ] crbug.com/591099 http/tests/devtools/network/network-datasaver-warning.js [ Failure ] crbug.com/591099 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass ] -crbug.com/591099 http/tests/images/image-decode-in-frame.html [ Crash Pass ] +crbug.com/591099 http/tests/images/image-decode-in-frame.html [ Pass ] crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ] crbug.com/591099 http/tests/intersection-observer/v2/cross-origin-effects.html [ Failure ] crbug.com/591099 http/tests/intersection-observer/v2/cross-origin-occlusion.html [ Failure ] @@ -319,9 +332,9 @@ crbug.com/591099 http/tests/misc/object-embedding-svg-delayed-size-negotiation.xhtml [ Pass ] crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ] -crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash Pass ] +crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Pass ] crbug.com/591099 http/tests/webaudio/autoplay-crossorigin.html [ Timeout ] -crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass Timeout ] +crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ] crbug.com/714962 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.js [ Failure ] crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Failure ] @@ -353,7 +366,7 @@ crbug.com/714962 paint/invalidation/position/relative-positioned-movement-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/position/relayout-fixed-position-after-scale.html [ Failure ] crbug.com/591099 paint/invalidation/scroll/repaint-composited-child-in-scrolled-container.html [ Failure ] -crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-clear.html [ Failure Pass ] +crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-clear.html [ Failure ] crbug.com/591099 paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ] crbug.com/591099 paint/invalidation/svg/text-selection-update.svg [ Failure ] crbug.com/591099 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ] @@ -393,7 +406,7 @@ crbug.com/591099 virtual/feature-policy-vibrate/ [ Skip ] crbug.com/591099 virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-iframe-fixed-position.html [ Failure ] crbug.com/591099 virtual/fractional_scrolling_threaded/fast/scrolling/fractional-scroll-offset-iframe-fixed-position.html [ Failure ] -crbug.com/591099 virtual/fractional_scrolling_threaded/fast/scrolling/overflow-scrollability.html [ Crash Failure Pass ] +crbug.com/591099 virtual/fractional_scrolling_threaded/fast/scrolling/overflow-scrollability.html [ Failure Pass ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-color-over-image.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-gradient-over-pattern.html [ Pass Timeout ] @@ -414,7 +427,7 @@ crbug.com/591099 virtual/outofblink-cors-ns/http/tests/fetch/chromium/release-handle-crash.html [ Pass ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ] -crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash Pass ] +crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Pass ] crbug.com/591099 virtual/outofblink-cors-ns/http/tests/security/video-poster-cross-origin-crash2.html [ Pass ] crbug.com/591099 virtual/outofblink-cors/ [ Skip ] crbug.com/591099 virtual/outofblink-cors/http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] @@ -434,3 +447,5 @@ crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Failure ] crbug.com/591099 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Pass ] +crbug.com/591099 xr/events_session_resetpose.html [ Pass Timeout ] +crbug.com/591099 xr/xrFrameOfReference_stage_updates.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations index 50d5f68..93a5622 100644 --- a/third_party/WebKit/LayoutTests/MSANExpectations +++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -204,3 +204,6 @@ # Disabled by sheriff due to test crash crbug.com/896068 [ Linux ] webaudio/AudioBuffer/huge-buffer.html [ Crash ] crbug.com/896068 [ Linux ] webaudio/dom-exceptions.html [ Pass Crash ] + +# Sheriff 2018-11-22 +crbug.com/856601 [ Linux ] http/tests/devtools/elements/elements-save-to-temp-var.js [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 0d13b9c..15aa90a 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -356,6 +356,8 @@ crbug.com/842995 external/wpt/html/semantics/scripting-1/the-script-element/execution-timing/078.html [ Slow ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/async_007.htm [ Slow ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/async_010.htm [ Slow ] +crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/async_007.htm [ Slow ] +crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/async_010.htm [ Slow ] crbug.com/840792 [ Mac10.12 Mac10.13 ] external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index b9e2b56..53e45eb 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2929,29 +2929,24 @@ crbug.com/893480 external/wpt/infrastructure/testdriver/actions/multiDevice.html [ Failure Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/html/webappapis/user-prompts/newline-normalization-manual.html [ Skip ] +crbug.com/626703 [ Mac10.13 ] external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html [ Crash ] +crbug.com/626703 [ Mac10.13 ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html [ Crash ] +crbug.com/626703 [ Mac10.13 ] external/wpt/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-default-feature-policy.https.sub.html [ Crash ] +crbug.com/626703 [ Retina ] virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Crash ] +crbug.com/626703 [ Mac10.13 ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Crash ] +crbug.com/626703 [ Mac10.13 ] virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-default-feature-policy.https.sub.html [ Crash ] +crbug.com/626703 [ Retina ] virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-default-feature-policy.https.sub.html [ Crash ] +crbug.com/626703 [ Mac10.13 ] external/wpt/media-source/mediasource-detach.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/media-source/mediasource-detach.html [ Crash ] +crbug.com/626703 [ Retina ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html [ Crash ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/pause.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/unsized-media-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/usb-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/payment-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/fullscreen-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/payment-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/microphone-reporting.https.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/camera-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/usb-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/sync-xhr-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/geolocation-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/document-write-reporting.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/midi-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/vr-reporting.https.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/document-write-reporting.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/camera-reporting.https.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/unsized-media-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/fullscreen-reporting.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/midi-reporting.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/vr-reporting.https.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/sync-xhr-reporting.html [ Timeout ] -crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/reporting/geolocation-reporting.https.html [ Timeout ] -crbug.com/626703 external/wpt/feature-policy/reporting/microphone-reporting.https.html [ Timeout ] crbug.com/626703 external/wpt/infrastructure/testdriver/actions/eventOrder.html [ Timeout ] crbug.com/626703 external/wpt/css/css-text/writing-system/writing-system-segment-break-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/writing-system/writing-system-line-break-001.html [ Failure ] @@ -3296,6 +3291,8 @@ crbug.com/626703 external/wpt/websockets/Create-Secure-extensions-empty.any.worker.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-classic.sub.html [ Skip ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-module.sub.html [ Skip ] +crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-classic.sub.html [ Skip ] +crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-module.sub.html [ Skip ] crbug.com/626703 external/wpt/html/browsers/history/joint-session-history/joint-session-history-remove-iframe.html [ Timeout ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-003a.html [ Failure ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-004a.html [ Failure ] @@ -4247,6 +4244,7 @@ # module script lacks XHTML support crbug.com/717643 external/wpt/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml [ Failure ] +crbug.com/717643 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml [ Failure ] # known bug: import() inside set{Timeout,Interval} @@ -4255,6 +4253,10 @@ crbug.com/796034 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html [ Failure ] crbug.com/796034 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html [ Failure ] crbug.com/796034 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html [ Failure ] +crbug.com/796034 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html [ Failure ] +crbug.com/796034 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html [ Failure ] +crbug.com/796034 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html [ Failure ] +crbug.com/796034 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html [ Failure ] # Geolocation tests crbug.com/745079 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] @@ -4708,7 +4710,6 @@ crbug.com/824830 fast/peerconnection/RTCPeerConnection-many.html [ Timeout Crash Failure Pass ] crbug.com/824848 [ Linux Win ] external/wpt/html/semantics/links/following-hyperlinks/activation-behavior.window.html [ Pass Failure ] crbug.com/824904 inspector-protocol/heap-profiler/heap-objects-tracking.js [ Pass Failure ] -crbug.com/824955 external/wpt/css/css-font-loading/idlharness.https.html [ Pass Failure ] # Sheriff 2018-03-23 crbug.com/825262 [ Win Mac Linux ] external/wpt/css/css-transitions/properties-value-001.html [ Pass Failure ] @@ -5380,3 +5381,7 @@ crbug.com/667560 http/tests/devtools/console-cross-origin-iframe-logging.js [ Pass Failure Timeout ] crbug.com/907412 [ Mac10.13 ] external/wpt/domxpath/xml_xpath_runner.html [ Pass Timeout ] crbug.com/907481 [ Win10 ] virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html [ Failure ] + +#Sheriff 2018-11-22 +crbug.com/907736 http/tests/devtools/elements/elements-save-to-temp-var.js [ Timeout Pass ] +crbug.com/907862 [ Mac10.13 ] virtual/user-activation-v2/gamepad/multiple-event-listeners.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 609a2f1..c0659b09 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -1026,5 +1026,15 @@ "prefix": "transferable-streams", "base": "http/tests/streams/transferable", "args": ["--enable-blink-features=TransferableStreams"] + }, + { + "prefix": "streaming-preload", + "base": "http/tests/fetch", + "args": ["--enable-features=ScriptStreamingOnPreload"] + }, + { + "prefix": "streaming-preload", + "base": "external/wpt/html/semantics/scripting-1", + "args": ["--enable-features=ScriptStreamingOnPreload"] } ]
diff --git a/third_party/WebKit/LayoutTests/custom-elements/tentative/form-association.html b/third_party/WebKit/LayoutTests/custom-elements/tentative/form-association.html new file mode 100644 index 0000000..a57a16d --- /dev/null +++ b/third_party/WebKit/LayoutTests/custom-elements/tentative/form-association.html
@@ -0,0 +1,150 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +class PreDefined extends HTMLElement { + static get formAssociated() { return true; } + + constructor() { + super(); + this.internals_ = this.attachInternals(); + } + + get form() { + return this.internals_.form; + } +} +customElements.define('pre-defined', PreDefined); +</script> +<div id="container"> + +<fieldset id="fs1"> +<form id="form1"> +<input> +<pre-defined id="pd1"></pre-defined> +<select></select> +</form> +</fieldset> + +<fieldset id="fs2"> +<pre-defined id="pd2" form="form2"></pre-defined> +<form id="form2"> +<input> +<select></select> +</form> +</fieldset> +<pre-defined id="pd3" form="form2"></pre-defined> + +<table> +<fieldset id="fs3"> +<form id="form3"> +<tr><td><select></select></tr> +<tr><td><pre-defined id="pd4"></pre-defined></tr> +<tr><td><input></tr> +</form> <!-- The end tag is bogus. --> +</fieldset> <!-- The end tag is bogus. --> +<table> + +</div> + +<script> +const $ = document.querySelector.bind(document); + +test(() => { + let controls = $('#form1').elements; + assert_equals(controls.length, 3); + assert_equals(controls[1], $('#pd1'), 'form.elements'); + assert_equals($('#pd1').form, $('#form1')); + assert_equals($('#fs1').elements[1], $('#pd1'), 'fieldset.elements'); + + controls = $('#form2').elements; + assert_equals(controls.length, 4); + assert_equals(controls[0], $('#pd2'), 'form.elements'); + assert_equals(controls[3], $('#pd3')); + assert_equals($('#pd2').form, $('#form2')); + assert_equals($('#pd3').form, $('#form2')); + controls = $('#fs2').elements; + assert_equals(controls.length, 3); + assert_equals(controls[0], $('#pd2'), 'fieldset.elements'); + + controls = $('#form3').elements; + assert_equals(controls.length, 2); + assert_not_equals(controls[1], $('#pd4')); + assert_equals($('#fs3').elements.length, 0); +}, 'Associate by parser, customized at element creation'); + +test(() => { + $('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><will-be-defined id="wbd1">' + + '</will-be-defined><select></select></form></fieldset>' + + '<fieldset id="fs2"><will-be-defined id="wbd2" form="form2"></will-be-defined>' + + '<form id="form2"></form></fieldset><will-be-defined id="wbd3" form="form2"></will-be-defined>'; + let controls = $('#form1').elements; + assert_equals(controls.length, 2); + assert_not_equals(controls[1], $('#wbd1')); + controls = $('#fs1').elements; + assert_equals(controls.length, 2); + assert_not_equals(controls[1], $('#wbd1')); + + assert_equals($('#form2').elements.length, 0); + assert_equals($('#fs2').elements.length, 0); + + class WillBeDefined extends HTMLElement { + static get formAssociated() { return true; } + + constructor() { + super(); + this.internals_ = this.attachInternals(); + } + + get form() { + return this.internals_.form; + } + } + customElements.define('will-be-defined', WillBeDefined); + customElements.upgrade(container); + + controls = $('#form1').elements; + assert_equals(controls.length, 3, 'form.elements.length'); + assert_equals(controls[1], $('#wbd1')); + assert_equals($('#wbd1').form, $('#form1')); + controls = $('#fs1').elements; + assert_equals(controls.length, 3, 'fieldset.elements.length'); + assert_equals(controls[1], $('#wbd1')); + + controls = $('#form2').elements; + assert_equals($('#wbd2').form, $('#form2')); + assert_equals($('#wbd3').form, $('#form2')); + assert_equals(controls.length, 2, 'form.elements.length'); + assert_equals(controls[0], $('#wbd2')); + assert_equals(controls[1], $('#wbd3')); + controls = $('#fs2').elements; + assert_equals(controls.length, 1, 'fieldset.elements.length'); + assert_equals(controls[0], $('#wbd2')); +}, 'Parsed, connected, then upgraded'); + +test(() => { + $('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><pre-defined id="pd1">' + + '</pre-defined><select></select></form></fieldset>' + + '<fieldset id="fs2"><pre-defined id="pd2" form="form2"></pre-defined>' + + '<form id="form2"></form></fieldset><pre-defined id="pd3" form="form2"></pre-defined>'; + + const pd1 = $('#pd1'); + assert_equals($('#form1').elements.length, 3, 'form.elements.length before removal'); + assert_equals($('#fs1').elements.length, 3, 'fildset.elements.length before removal'); + pd1.remove(); + assert_equals(pd1.form, null); + assert_equals($('#form1').elements.length, 2, 'form.elements.length after removal'); + assert_equals($('#fs1').elements.length, 2, 'fildset.elements.length after removal'); + + const pd2 = $('#pd2'); + const pd3 = $('#pd3'); + assert_equals($('#form2').elements.length, 2, 'form.elements.length before removal'); + assert_equals($('#fs2').elements.length, 1, 'fieldset.elements.length before removal'); + pd2.remove(); + pd3.remove(); + assert_equals(pd2.form, null); + assert_equals(pd3.form, null); + assert_equals($('#form2').elements.length, 0, 'form.elements.length after removal'); + assert_equals($('#fs2').elements.length, 0, 'fieldset.elements.length after removal'); +}, 'Disassociation'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json index c3a95a2..5a45f4e 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json
@@ -5095,6 +5095,12 @@ {} ] ], + "html/webappapis/user-prompts/newline-normalization-manual.html": [ + [ + "/html/webappapis/user-prompts/newline-normalization-manual.html", + {} + ] + ], "input-events/input-events-cut-paste-manual.html": [ [ "/input-events/input-events-cut-paste-manual.html", @@ -177821,6 +177827,11 @@ {} ] ], + "service-workers/service-worker/fetch-canvas-tainting-double-write.https-expected.txt": [ + [ + {} + ] + ], "service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https-expected.txt": [ [ {} @@ -178366,6 +178377,11 @@ {} ] ], + "service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js": [ + [ + {} + ] + ], "service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html": [ [ {} @@ -201385,6 +201401,12 @@ {} ] ], + "cookies/path/default.html": [ + [ + "/cookies/path/default.html", + {} + ] + ], "cookies/path/match.html": [ [ "/cookies/path/match.html", @@ -242881,6 +242903,12 @@ {} ] ], + "mediacapture-streams/GUM-non-applicable-constraint.https.html": [ + [ + "/mediacapture-streams/GUM-non-applicable-constraint.https.html", + {} + ] + ], "mediacapture-streams/GUM-optional-constraint.https.html": [ [ "/mediacapture-streams/GUM-optional-constraint.https.html", @@ -268099,6 +268127,12 @@ {} ] ], + "service-workers/service-worker/fetch-canvas-tainting-double-write.https.html": [ + [ + "/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html", + {} + ] + ], "service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html": [ [ "/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html", @@ -302839,7 +302873,7 @@ "support" ], "cookies/http-state/resources/cookie-http-state-template.js": [ - "d737b38c520b83a8f9788b4c625021337fed2f12", + "62459f059fd147779354140d1e830ea52a263abe", "support" ], "cookies/http-state/resources/cookie-setter.py": [ @@ -304638,6 +304672,10 @@ "1b86e65c87c65a78a31e0b8a1d6bfdbe333e08f6", "testharness" ], + "cookies/path/default.html": [ + "3e00bafeee5cf11af1222509b21100124571199a", + "testharness" + ], "cookies/path/match.html": [ "14921d1d62c0d80349cf1149e55e3af0b51f77d5", "testharness" @@ -329383,7 +329421,7 @@ "testharness" ], "css/css-font-loading/idlharness.https-expected.txt": [ - "64d6523baad8d3bf374ef1dda00be9dccc0923c9", + "8422407fe35cc786ded3769d1f003dd9cca23dbd", "support" ], "css/css-font-loading/idlharness.https.html": [ @@ -378539,7 +378577,7 @@ "reftest" ], "custom-elements/CustomElementRegistry-expected.txt": [ - "daa93a401e4bc2ed4480a6b7e70f6ddccbc37bed", + "b5f35e69b0fe871fd50736a43e2245bd87872f4b", "support" ], "custom-elements/CustomElementRegistry.html": [ @@ -406374,6 +406412,10 @@ "31fa4f1264211e050864147db24216465e1ac62f", "testharness" ], + "html/webappapis/user-prompts/newline-normalization-manual.html": [ + "55cb5ce527ea69fa23e6aba675719bb6524d7411", + "manual" + ], "imagebitmap-renderingcontext/META.yml": [ "f6a06f4e7d7625855e271ec5422629ca5e734560", "support" @@ -407283,7 +407325,7 @@ "support" ], "interfaces/fetch.idl": [ - "e86a282534b83a1a78e4911ed15e2e2d0cbe4967", + "5f876e7a4ac439828ac54d11d71554beca40ef6e", "support" ], "interfaces/filter-effects.idl": [ @@ -407499,7 +407541,7 @@ "support" ], "interfaces/scroll-animations.idl": [ - "4e4f962ce4d5db320f68427eca040aae2ff60fcd", + "bb0fde4747dffc37c15a9e1c656114ab3aa67920", "support" ], "interfaces/secure-contexts.idl": [ @@ -408954,6 +408996,10 @@ "d29caeb1345206617aafdb72e7c0e3ad6bb83a29", "testharness" ], + "mediacapture-streams/GUM-non-applicable-constraint.https.html": [ + "8423c56b9a3cba0ae8da03fd8ce770239e0264ac", + "testharness" + ], "mediacapture-streams/GUM-optional-constraint.https.html": [ "becd871ab2a113f62b8a6b0fec61d78337e3f640", "testharness" @@ -430743,7 +430789,7 @@ "support" ], "scroll-animations/META.yml": [ - "0123b6b0e333e7a487a7dfd6fba19e40ee691ca9", + "20f3c7e6c930193207c6cbcd329e36f85a993dc9", "support" ], "scroll-animations/idlharness-expected.txt": [ @@ -432366,6 +432412,14 @@ "9821759bc7b311672a54387edc7d8c26a11d5e54", "testharness" ], + "service-workers/service-worker/fetch-canvas-tainting-double-write.https-expected.txt": [ + "5e4041d0f8d4668fa1516758743a64b4e9cfb666", + "support" + ], + "service-workers/service-worker/fetch-canvas-tainting-double-write.https.html": [ + "4e233053729c42c1f8ac49d9554f3035c8f04728", + "testharness" + ], "service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html": [ "213238112257923657fe84a637ddd45cc0c038c5", "testharness" @@ -433266,6 +433320,10 @@ "61b89cbd95b4b910670e4795cb2518c51abec121", "support" ], + "service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js": [ + "17723dcdda2f2fadb9ab0ab4a00b28c24b815234", + "support" + ], "service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html": [ "a65d2501a8508addf3ec2b6d2daf00b1bdc4af2c", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window-expected.txt index d2026e32..c603f03 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window-expected.txt
@@ -14,5 +14,6 @@ PASS Fetches with mixed content should fail. PASS Matching to a single request should work PASS Matching to a non-existing request should work +PASS Matching multiple times on the same request works as expected. Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window.js index 52d29db5..e256c973 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/fetch.https.window.js
@@ -300,3 +300,27 @@ }, 'Matching to a non-existing request should work'); +backgroundFetchTest(async (test, backgroundFetch) => { + const registrationId = 'matchexistingrequesttwice'; + const registration = + await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt'); + + assert_equals(registration.id, registrationId); + + const {type, eventRegistration, results} = await getMessageFromServiceWorker(); + assert_equals('backgroundfetchsuccess', type); + assert_equals(results.length, 2); + + assert_equals(eventRegistration.id, registration.id); + assert_equals(eventRegistration.result, 'success'); + assert_equals(eventRegistration.failureReason, ''); + + assert_true(results[0].url.includes('resources/feature-name.txt')); + assert_equals(results[0].status, 200); + assert_equals(results[0].text, 'Background Fetch'); + + assert_true(results[1].url.includes('resources/feature-name.txt')); + assert_equals(results[1].status, 200); + assert_equals(results[1].text, 'error'); + +}, 'Matching multiple times on the same request works as expected.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js index 80b4792..d61059d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/service_workers/sw.js
@@ -8,17 +8,25 @@ return { url: response.url, status: response.status, - text: await response.text(), + text: await response.text().catch(() => 'error'), }; } function handleBackgroundFetchEvent(event) { let matchFunction = null; + switch (event.registration.id) { case 'matchexistingrequest': matchFunction = event.registration.match.bind( event.registration, '/background-fetch/resources/feature-name.txt'); break; + case 'matchexistingrequesttwice': + matchFunction = (async () => { + const match1 = await event.registration.match('/background-fetch/resources/feature-name.txt'); + const match2 = await event.registration.match('/background-fetch/resources/feature-name.txt'); + return [match1, match2]; + }).bind(event.registration); + break; case 'matchmissingrequest': matchFunction = event.registration.match.bind( event.registration, '/background-fetch/resources/missing.txt'); @@ -38,7 +46,7 @@ }) // Extract responses. .then(records => - Promise.all(records.map(record => getFetchResult(record)))) + Promise.all(records.map(record => getFetchResult(record)))) // Clone registration and send message. .then(results => { const registrationCopy = cloneRegistration(event.registration);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/http-state/resources/cookie-http-state-template.js b/third_party/WebKit/LayoutTests/external/wpt/cookies/http-state/resources/cookie-http-state-template.js index d737b38..62459f059 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookies/http-state/resources/cookie-http-state-template.js +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/http-state/resources/cookie-http-state-template.js
@@ -86,6 +86,13 @@ expireCookie(cookies_to_delete[i].replace(/=.*$/, ""), /*expiry_date=*/null, /*path=*/'/'); + // Some browsers incorrectly include the final "forward slash" character + // when calculating the default path. The expected behavior for default + // path calculation is verified elsewhere; this utility accommodates the + // non-standard behavior in order to improve the focus of the test suite. + expireCookie(cookies_to_delete[i].replace(/=.*$/, ""), + /*expiry_date=*/null, + /*path=*/getLocalResourcesPath() + "/"); } }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/path/default.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/path/default.html new file mode 100644 index 0000000..3e00baf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/path/default.html
@@ -0,0 +1,64 @@ +<!doctype html> +<html> +<head> + <meta charset=utf-8> + <title>Test for default cookie path</title> + <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4"> + + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> +<div id=log></div> + +<script> +var body = document.getElementsByTagName('body')[0]; +var createIframe = function (src, done) { + var iframe = document.createElement('iframe'); + iframe.src = src; + body.appendChild(iframe); + iframe.onload = function () { + done(iframe); + }; +}; + +async_test(function (t) { + var iframe; + var verify = t.step_func(function () { + assert_true( + !!iframe.contentWindow.isCookieSet('cookies-path-default'), + 'cookie can be retrieved from expected path' + ); + + // The default-path of this cookie must contain, "the characters of the + // uri-path from the first character up to, but not including, the + // right-most %x2F ("/")." + iframe.contentWindow.expireCookie( + 'cookies-path-default', '/cookies/resources' + ); + + // As of 2018-11-21, some UAs were observed to include the right-most %x2F + // character in violation of RFC6265. + t.add_cleanup(function () { + iframe.contentWindow.expireCookie( + 'cookies-path-default', '/cookies/resources/' + ); + }); + + assert_false( + !!iframe.contentWindow.isCookieSet('cookies-path-default'), + 'cookie can be referenced using the expected path' + ); + + t.done(); + }); + + createIframe('/cookies/resources/echo-cookie.html', t.step_func(function (_iframe) { + iframe = _iframe; + + createIframe('/cookies/resources/set.py?cookies-path-default=1', verify); + })); +}); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt index 64d6523b..8422407f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-font-loading/idlharness.https-expected.txt
@@ -1,9 +1,5 @@ This is a testharness.js-based test. -PASS Test IDL implementation of CSS Font Loading -PASS Document interface: attribute fonts -PASS Unscopable handled correctly for fonts property on Document -PASS Document interface: document must inherit property "fonts" with the proper type -PASS WorkerGlobalScope interface: existence and properties of interface object +PASS idl_test setup PASS FontFace interface: existence and properties of interface object PASS FontFace interface object length PASS FontFace interface object name @@ -11,29 +7,31 @@ PASS FontFace interface: existence and properties of interface prototype object's "constructor" property PASS FontFace interface: existence and properties of interface prototype object's @@unscopables property PASS FontFace interface: attribute family -PASS Unscopable handled correctly for family property on FontFace PASS FontFace interface: attribute style -PASS Unscopable handled correctly for style property on FontFace PASS FontFace interface: attribute weight -PASS Unscopable handled correctly for weight property on FontFace PASS FontFace interface: attribute stretch -PASS Unscopable handled correctly for stretch property on FontFace PASS FontFace interface: attribute unicodeRange -PASS Unscopable handled correctly for unicodeRange property on FontFace PASS FontFace interface: attribute variant -PASS Unscopable handled correctly for variant property on FontFace PASS FontFace interface: attribute featureSettings -PASS Unscopable handled correctly for featureSettings property on FontFace FAIL FontFace interface: attribute variationSettings assert_true: The prototype object must have a property "variationSettings" expected true got false -PASS Unscopable handled correctly for variationSettings property on FontFace PASS FontFace interface: attribute display -PASS Unscopable handled correctly for display property on FontFace PASS FontFace interface: attribute status -PASS Unscopable handled correctly for status property on FontFace PASS FontFace interface: operation load() -PASS Unscopable handled correctly for load() on FontFace PASS FontFace interface: attribute loaded -PASS Unscopable handled correctly for loaded property on FontFace +PASS FontFace must be primary interface of new FontFace("family", "src") +PASS Stringification of new FontFace("family", "src") +PASS FontFace interface: new FontFace("family", "src") must inherit property "family" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "style" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "weight" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "stretch" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "unicodeRange" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "variant" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "featureSettings" with the proper type +FAIL FontFace interface: new FontFace("family", "src") must inherit property "variationSettings" with the proper type assert_inherits: property "variationSettings" not found in prototype chain +PASS FontFace interface: new FontFace("family", "src") must inherit property "display" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "status" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "load()" with the proper type +PASS FontFace interface: new FontFace("family", "src") must inherit property "loaded" with the proper type PASS FontFaceSetLoadEvent interface: existence and properties of interface object PASS FontFaceSetLoadEvent interface object length PASS FontFaceSetLoadEvent interface object name @@ -41,7 +39,9 @@ PASS FontFaceSetLoadEvent interface: existence and properties of interface prototype object's "constructor" property PASS FontFaceSetLoadEvent interface: existence and properties of interface prototype object's @@unscopables property PASS FontFaceSetLoadEvent interface: attribute fontfaces -PASS Unscopable handled correctly for fontfaces property on FontFaceSetLoadEvent +PASS FontFaceSetLoadEvent must be primary interface of new FontFaceSetLoadEvent("type") +PASS Stringification of new FontFaceSetLoadEvent("type") +PASS FontFaceSetLoadEvent interface: new FontFaceSetLoadEvent("type") must inherit property "fontfaces" with the proper type FAIL FontFaceSet interface: existence and properties of interface object assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing FAIL FontFaceSet interface object length assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing FAIL FontFaceSet interface object name assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing @@ -49,24 +49,33 @@ FAIL FontFaceSet interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing FAIL FontFaceSet interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing FAIL FontFaceSet interface: operation add(FontFace) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for add(FontFace) on FontFaceSet FAIL FontFaceSet interface: operation delete(FontFace) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for delete(FontFace) on FontFaceSet FAIL FontFaceSet interface: operation clear() assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for clear() on FontFaceSet FAIL FontFaceSet interface: attribute onloading assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for onloading property on FontFaceSet FAIL FontFaceSet interface: attribute onloadingdone assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for onloadingdone property on FontFaceSet FAIL FontFaceSet interface: attribute onloadingerror assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for onloadingerror property on FontFaceSet FAIL FontFaceSet interface: operation load(CSSOMString, CSSOMString) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for load(CSSOMString, CSSOMString) on FontFaceSet FAIL FontFaceSet interface: operation check(CSSOMString, CSSOMString) assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for check(CSSOMString, CSSOMString) on FontFaceSet FAIL FontFaceSet interface: attribute ready assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for ready property on FontFaceSet FAIL FontFaceSet interface: attribute status assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing -PASS Unscopable handled correctly for status property on FontFaceSet +FAIL FontFaceSet must be primary interface of document.fonts assert_own_property: self does not have own property "FontFaceSet" expected property "FontFaceSet" missing +PASS Stringification of document.fonts +PASS FontFaceSet interface: document.fonts must inherit property "add(FontFace)" with the proper type +PASS FontFaceSet interface: calling add(FontFace) on document.fonts with too few arguments must throw TypeError +PASS FontFaceSet interface: document.fonts must inherit property "delete(FontFace)" with the proper type +PASS FontFaceSet interface: calling delete(FontFace) on document.fonts with too few arguments must throw TypeError +PASS FontFaceSet interface: document.fonts must inherit property "clear()" with the proper type +PASS FontFaceSet interface: document.fonts must inherit property "onloading" with the proper type +PASS FontFaceSet interface: document.fonts must inherit property "onloadingdone" with the proper type +PASS FontFaceSet interface: document.fonts must inherit property "onloadingerror" with the proper type +PASS FontFaceSet interface: document.fonts must inherit property "load(CSSOMString, CSSOMString)" with the proper type +PASS FontFaceSet interface: calling load(CSSOMString, CSSOMString) on document.fonts with too few arguments must throw TypeError +PASS FontFaceSet interface: document.fonts must inherit property "check(CSSOMString, CSSOMString)" with the proper type +PASS FontFaceSet interface: calling check(CSSOMString, CSSOMString) on document.fonts with too few arguments must throw TypeError +PASS FontFaceSet interface: document.fonts must inherit property "ready" with the proper type +PASS FontFaceSet interface: document.fonts must inherit property "status" with the proper type +PASS Document interface: attribute fonts +PASS Document interface: document must inherit property "fonts" with the proper type +PASS WorkerGlobalScope interface: existence and properties of interface object Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/interfaces.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/interfaces.any-expected.txt index 5a6ac30cb..4fc02f1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/interfaces.any-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/interfaces.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 458 tests; 426 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 458 tests; 448 PASS, 10 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS SVGFilterElement interface: existence and properties of interface object PASS SVGFilterElement interface object length @@ -31,28 +31,28 @@ PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_DARKEN on interface prototype object PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LIGHTEN on interface object PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LIGHTEN on interface prototype object -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_OVERLAY on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_OVERLAY" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_OVERLAY on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_OVERLAY" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_DODGE on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR_DODGE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_DODGE on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR_DODGE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_BURN on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR_BURN" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_BURN on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR_BURN" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HARD_LIGHT on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_HARD_LIGHT" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HARD_LIGHT on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_HARD_LIGHT" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SOFT_LIGHT on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_SOFT_LIGHT" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SOFT_LIGHT on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_SOFT_LIGHT" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_DIFFERENCE on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_DIFFERENCE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_DIFFERENCE on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_DIFFERENCE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_EXCLUSION on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_EXCLUSION" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_EXCLUSION on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_EXCLUSION" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HUE on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_HUE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HUE on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_HUE" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SATURATION on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_SATURATION" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SATURATION on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_SATURATION" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_COLOR" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LUMINOSITY on interface object assert_own_property: expected property "SVG_FEBLEND_MODE_LUMINOSITY" missing -FAIL SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LUMINOSITY on interface prototype object assert_own_property: expected property "SVG_FEBLEND_MODE_LUMINOSITY" missing +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_OVERLAY on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_OVERLAY on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_DODGE on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_DODGE on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_BURN on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR_BURN on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HARD_LIGHT on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HARD_LIGHT on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SOFT_LIGHT on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SOFT_LIGHT on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_DIFFERENCE on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_DIFFERENCE on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_EXCLUSION on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_EXCLUSION on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HUE on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_HUE on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SATURATION on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_SATURATION on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_COLOR on interface prototype object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LUMINOSITY on interface object +PASS SVGFEBlendElement interface: constant SVG_FEBLEND_MODE_LUMINOSITY on interface prototype object PASS SVGFEBlendElement interface: attribute in1 PASS SVGFEBlendElement interface: attribute in2 PASS SVGFEBlendElement interface: attribute mode
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/svgfeblendelement-mode-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/svgfeblendelement-mode-001.html new file mode 100644 index 0000000..8c9e3ea0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/filter-effects/svgfeblendelement-mode-001.html
@@ -0,0 +1,82 @@ +<!DOCTYPE HTML> +<title>SVGFEBlendElement.prototype.mode</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#InterfaceSVGFEBlendElement"> +<link rel="help" href="https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedEnumeration"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// This test checks the use of SVGAnimatedEnumeration for 'mode' on SVGFEBlendElement. + +const svgNs = "http://www.w3.org/2000/svg"; + +test(function() { + var element = document.createElementNS(svgNs, "feBlend"); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL); + assert_false(element.hasAttribute("mode")); +}, document.title + ", getter, initial value"); + +test(function() { + var element = document.createElementNS(svgNs, "feBlend"); + element.setAttribute("mode", "not-a-valid-value"); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL); + assert_true(element.hasAttribute("mode")); + assert_equals(element.getAttribute("mode"), "not-a-valid-value"); +}, document.title + ", getter, invalid value"); + +const enumerationMap = [ + [ "normal", "NORMAL" ], + [ "multiply", "MULTIPLY" ], + [ "screen", "SCREEN" ], + [ "darken", "DARKEN" ], + [ "lighten", "LIGHTEN" ], + [ "overlay", "OVERLAY" ], + [ "color-dodge", "COLOR_DODGE" ], + [ "color-burn", "COLOR_BURN" ], + [ "hard-light", "HARD_LIGHT" ], + [ "soft-light", "SOFT_LIGHT" ], + [ "difference", "DIFFERENCE" ], + [ "exclusion", "EXCLUSION" ], + [ "hue", "HUE" ], + [ "saturation", "SATURATION" ], + [ "color", "COLOR" ], + [ "luminosity", "LUMINOSITY" ], +]; + +for (let [enumeration, value_suffix] of enumerationMap) { + test(function() { + let value = SVGFEBlendElement["SVG_FEBLEND_MODE_" + value_suffix]; + var element = document.createElementNS(svgNs, "feBlend"); + element.setAttribute("mode", enumeration); + assert_equals(element.mode.baseVal, value); + }, document.title + ", getter, numeric value for \"" + enumeration + "\""); +} + +test(function() { + var element = document.createElementNS(svgNs, "feBlend"); + element.setAttribute("mode", "lighten"); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); + assert_equals(element.getAttribute('mode'), "lighten"); + + assert_throws(new TypeError(), function() { element.mode.baseVal = 17; }); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); + assert_equals(element.getAttribute('mode'), "lighten"); + + assert_throws(new TypeError(), function() { element.mode.baseVal = -1; }); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); + assert_equals(element.getAttribute('mode'), "lighten"); + + assert_throws(new TypeError(), function() { element.mode.baseVal = 0; }); + assert_equals(element.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); + assert_equals(element.getAttribute('mode'), "lighten"); +}, document.title + ", setter, invalid value"); + +for (let [enumeration, value_suffix] of enumerationMap) { + test(function() { + let value = SVGFEBlendElement["SVG_FEBLEND_MODE_" + value_suffix]; + var element = document.createElementNS(svgNs, "feBlend"); + element.mode.baseVal = value; + assert_equals(element.mode.baseVal, value); + assert_equals(element.getAttribute('mode'), enumeration); + }, document.title + ", setter, numeric value for \"" + enumeration + "\""); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/CustomElementRegistry-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/CustomElementRegistry-expected.txt index daa93a4..b5f35e6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/CustomElementRegistry-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/CustomElementRegistry-expected.txt
@@ -11,13 +11,13 @@ PASS customElements.define unset the element definition is running flag before upgrading custom elements FAIL customElements.define must not throw when defining another custom element in a different global object during Get(constructor, "prototype") Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry PASS Custom Elements: CustomElementRegistry interface -FAIL customElements.define must get "prototype" property of the constructor assert_array_equals: lengths differ, expected 1 got 2 +FAIL customElements.define must get "prototype" property of the constructor assert_array_equals: lengths differ, expected 1 got 3 PASS customElements.define must rethrow an exception thrown while getting "prototype" property of the constructor PASS customElements.define must throw when "prototype" property of the constructor is not an object PASS customElements.define must get callbacks of the constructor prototype PASS customElements.define must rethrow an exception thrown while getting callbacks on the constructor prototype PASS customElements.define must rethrow an exception thrown while converting a callback value to Function callback type -FAIL customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present assert_array_equals: lengths differ, expected 4 got 6 +FAIL customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present assert_array_equals: lengths differ, expected 4 got 8 PASS customElements.define must rethrow an exception thrown while getting observedAttributes on the constructor prototype PASS customElements.define must rethrow an exception thrown while converting the value of observedAttributes to sequence<DOMString> PASS customElements.define must rethrow an exception thrown while iterating over observedAttributes to sequence<DOMString>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/experimental-features/resources/common.js b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/experimental-features/resources/common.js index 42790b8a..cbd0518f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/experimental-features/resources/common.js +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/experimental-features/resources/common.js
@@ -70,7 +70,7 @@ if (window.reporting_observer_callback) { reports.forEach(window.reporting_observer_callback); } -}, {types: ["feature-policy"]}); +}, {types: ["feature-policy-violation"]}); window.reporting_observer_instance.observe(); window.reporting_observer_callback = null; @@ -79,7 +79,7 @@ return new Promise( (resolve) => { assert_equals(null, window.reporting_observer_callback); window.reporting_observer_callback = (report) => { - var feature_match = (feature === report.body.feature); + var feature_match = (feature === report.body.featureId); var file_name_match = !file_name || (report.body.sourceFile.indexOf(file_name) !== -1);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-report-only.https.html index 2648868..c22e1a517 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-report-only.https.html
@@ -10,15 +10,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "camera"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "camera"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await test_driver.bless('Activate document for user media'); await navigator.mediaDevices.getUserMedia({video: true});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-reporting.https.html index ced58513..12b48dc 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/camera-reporting.https.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "camera"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-report-only.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-report-only.html index ab0bb827..69ce9f8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-report-only.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-report-only.html
@@ -8,15 +8,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "document-write"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "document-write"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); document.write("This should be written into the document"); check_report_format(await report);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-reporting.html index 93672fa..e67bff07 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/document-write-reporting.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "document-write"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html index 20e44b2f..9ab4b0fe 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-report-only.https.html
@@ -8,15 +8,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "encrypted-media"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "encrypted-media"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await navigator.requestMediaKeySystemAccess("org.w3.clearkey", [{
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html index c3b6393..6575a68 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/encrypted-media-reporting.https.html
@@ -8,12 +8,11 @@ <script> var check_report_format = (reports, observer) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.feature, "encrypted-media"); + assert_equals(report.body.featureId, "encrypted-media"); assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); }; @@ -21,7 +20,7 @@ promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await promise_rejects(t, "SecurityError", navigator.requestMediaKeySystemAccess("org.w3.clearkey",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-report-only.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-report-only.html index a6b3d5ad..48fe9e3a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-report-only.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-report-only.html
@@ -11,15 +11,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "fullscreen"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "fullscreen"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await test_driver.bless('Activate document for fullscreen'); await document.getElementById('fs').requestFullscreen();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-reporting.html index 4190fdd..0153647 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/fullscreen-reporting.html
@@ -12,7 +12,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "fullscreen"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-report-only.https.html index deb6ade..6c8c2ef 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-report-only.https.html
@@ -20,19 +20,18 @@ // Validate that the reported feature is one of the sensor features, and that // we have not seen a report for this feature before. - assert_true(sensor_features_verified.hasOwnProperty(report.body.feature)); - assert_false(sensor_features_verified[report.body.feature]); + assert_true(sensor_features_verified.hasOwnProperty(report.body.featureId)); + assert_false(sensor_features_verified[report.body.featureId]); // Validate the remainder of the report - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.disposition, "report"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); + assert_equals(report.body.disposition, "report"); - sensor_features_verified[report.body.feature] = true; + sensor_features_verified[report.body.featureId] = true; } // Test is only done when reports for all features have been seen @@ -45,7 +44,7 @@ async_test(t => { new ReportingObserver(t.step_func(check_report_format), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); new Accelerometer(); new AmbientLightSensor(); new Gyroscope();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-reporting.https.html index 517c7f6..4ccfcbf0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/generic-sensor-reporting.https.html
@@ -20,19 +20,18 @@ // Validate that the reported feature is one of the sensor features, and that // we have not seen a report for this feature before. - assert_true(sensor_features_verified.hasOwnProperty(report.body.feature)); - assert_false(sensor_features_verified[report.body.feature]); + assert_true(sensor_features_verified.hasOwnProperty(report.body.featureId)); + assert_false(sensor_features_verified[report.body.featureId]); // Validate the remainder of the report - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); + assert_equals(report.body.disposition, "enforce"); - sensor_features_verified[report.body.feature] = true; + sensor_features_verified[report.body.featureId] = true; } // Test is only done when reports for all features have been seen @@ -45,7 +44,7 @@ async_test(t => { new ReportingObserver(t.step_func(check_report_format), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); assert_throws("SecurityError", () => new Accelerometer(), "Constructing sensors should be blocked by policy"); assert_throws("SecurityError", () => new AmbientLightSensor(), "Constructing sensors should be blocked by policy"); assert_throws("SecurityError", () => new Gyroscope(), "Constructing sensors should be blocked by policy");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-report-only.https.html index cf2a75b..6c62b62 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-report-only.https.html
@@ -8,15 +8,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "geolocation"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "geolocation"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); try { await new Promise((resolve, reject) => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-reporting.https.html index 05445fc..fe8761f8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/geolocation-reporting.https.html
@@ -13,9 +13,7 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "geolocation"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); assert_equals(report.body.disposition, "enforce");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-report-only.https.html index 2d7b4d96..539994c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-report-only.https.html
@@ -10,15 +10,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "microphone"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "microphone"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await test_driver.bless('Activate document for user media'); await navigator.mediaDevices.getUserMedia({audio: true});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-reporting.https.html index 246484f..2aeba81 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/microphone-reporting.https.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "microphone"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-report-only.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-report-only.html index e466ce0d..bf0234d3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-report-only.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-report-only.html
@@ -8,15 +8,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "midi"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "midi"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); try { await navigator.requestMIDIAccess();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-reporting.html index c5627e5..94674a3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/midi-reporting.html
@@ -11,7 +11,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "midi"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-report-only.https.html index 6a7678b5..d2b8e5e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-report-only.https.html
@@ -8,15 +8,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "payment"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "payment"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); try { const request = new PaymentRequest(
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-reporting.https.html index 828054a..6655210 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/payment-reporting.https.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "payment"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-report-only.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-report-only.html index 157670f2..9e113a9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-report-only.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-report-only.html
@@ -12,8 +12,8 @@ <script> const check_report_format = ([reports, observer]) => { const report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "picture-in-picture"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "picture-in-picture"); assert_equals(report.body.disposition, "report"); }; @@ -28,7 +28,7 @@ promise_pip_test(async (t) => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); const videoElement = await loadVideo(); await test_driver.bless('picture-in-picture');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-reporting.html index f15f47c..567d68c3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/picture-in-picture-reporting.html
@@ -12,14 +12,13 @@ <script> const check_report_format = (reports, observer) => { const report = reports[0]; - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.feature, "picture-in-picture"); - assert_equals(report.body.disposition, "enforce"); + assert_equals(report.body.featureId, "picture-in-picture"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); + assert_equals(report.body.disposition, "enforce"); }; const loadVideo = () => new Promise(resolve => { @@ -33,7 +32,7 @@ promise_pip_test(async (t) => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); const videoElement = await loadVideo(); await test_driver.bless('picture-in-picture');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-report-only.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-report-only.html index f841f63..76d26ed 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-report-only.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-report-only.html
@@ -8,15 +8,15 @@ <script> const check_report_format = ([reports, observer]) => { const report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "sync-xhr"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "sync-xhr"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); const xhr = new XMLHttpRequest(); xhr.open("GET", document.location.href, false);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-reporting.html index 82200cdfb..d92a685 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/sync-xhr-reporting.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "sync-xhr"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/unsized-media-reporting.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/unsized-media-reporting.html index 00a1558..bb81a49 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/unsized-media-reporting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/unsized-media-reporting.html
@@ -12,7 +12,7 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "unsized-media"); - assert_equals(typeof report.body.message, "string"); + assert_equals(report.body.disposition, "enforce"); }; async_test(t => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-report-only.https.html index e44c6c5..7933e9eb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-report-only.https.html
@@ -11,15 +11,15 @@ <script> var check_report_format = ([reports, observer]) => { let report = reports[0]; - assert_equals(report.type, "feature-policy"); - assert_equals(report.body.feature, "usb"); + assert_equals(report.type, "feature-policy-violation"); + assert_equals(report.body.featureId, "usb"); assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await test_driver.bless('Activate document for USB'); await navigator.usb.getDevices();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-reporting.https.html index 0ddff45..a63f301 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/usb-reporting.https.html
@@ -13,7 +13,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "usb"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-report-only.https.html index 91016d3..b64a201 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-report-only.https.html
@@ -8,20 +8,19 @@ <script> const check_report_format = ([reports, observer]) => { const report = reports[0]; - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.feature, "vr"); - assert_equals(report.body.disposition, "report"); + assert_equals(report.body.featureId, "vr"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); + assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); await navigator.getVRDisplays(); check_report_format(await report);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-reporting.https.html index e0bb635..42a2e73 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/vr-reporting.https.html
@@ -11,7 +11,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "vr"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-report-only.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-report-only.https.html index 5d4fb06..b52bdbfa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-report-only.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-report-only.https.html
@@ -8,20 +8,19 @@ <script> const check_report_format = ([reports, observer]) => { const report = reports[0]; - assert_equals(report.type, "feature-policy"); + assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); - assert_equals(report.body.feature, "vr"); - assert_equals(report.body.disposition, "report"); + assert_equals(report.body.featureId, "vr"); assert_equals(report.body.sourceFile, document.location.href); - assert_equals(typeof report.body.message, "string"); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number"); + assert_equals(report.body.disposition, "report"); }; promise_test(async t => { const report = new Promise(resolve => { new ReportingObserver((reports, observer) => resolve([reports, observer]), - {types: ['feature-policy']}).observe(); + {types: ['feature-policy-violation']}).observe(); }); try { await navigator.xr.requestDevice();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-reporting.https.html index 0844860..b737bb9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/reporting/xr-reporting.https.html
@@ -11,7 +11,6 @@ assert_equals(report.type, "feature-policy-violation"); assert_equals(report.url, document.location.href); assert_equals(report.body.featureId, "vr"); - assert_equals(report.body.disposition, "enforce"); assert_equals(report.body.sourceFile, document.location.href); assert_equals(typeof report.body.lineNumber, "number"); assert_equals(typeof report.body.columnNumber, "number");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/user-prompts/newline-normalization-manual.html b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/user-prompts/newline-normalization-manual.html new file mode 100644 index 0000000..55cb5ce --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/user-prompts/newline-normalization-manual.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Newline normalization in simple dialogs</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#simple-dialogs"> + +<p>The dialogs should all contain text looking like:</p> + +<pre>Line 1.1 +Line 1.2 +Line 1.3 +Line 1.4 + +Line 2.1</pre> + +<script> +"use strict"; + +for (const func of [alert, confirm, prompt]) { + func('Line 1.1\nLine 1.2\rLine 1.3\r\nLine 1.4\n\rLine 2.1'); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/fetch.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/fetch.idl index e86a282..5f876e7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/fetch.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/fetch.idl
@@ -93,7 +93,7 @@ dictionary ResponseInit { unsigned short status = 200; - ByteString statusText = "OK"; + ByteString statusText = ""; HeadersInit headers; };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl index 4e4f962..bb0fde4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl
@@ -4,7 +4,6 @@ // Source: Scroll-linked Animations (https://wicg.github.io/scroll-animations/) enum ScrollDirection { - "auto", "block", "inline", "horizontal", @@ -15,7 +14,7 @@ dictionary ScrollTimelineOptions { Element scrollSource; - ScrollDirection orientation = "auto"; + ScrollDirection orientation = "block"; DOMString startScrollOffset = "auto"; DOMString endScrollOffset = "auto"; (double or ScrollTimelineAutoKeyword) timeRange = "auto";
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/GUM-non-applicable-constraint.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/GUM-non-applicable-constraint.https.html new file mode 100644 index 0000000..8423c56b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/GUM-non-applicable-constraint.https.html
@@ -0,0 +1,72 @@ +<!doctype html> +<title>non-applicable constraint in getUserMedia</title> +<link rel="author" title="Intel" href="http://www.intel.com"/> +<link rel="help" href="https://w3c.github.io/mediacapture-main/#methods-5"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<p class="instructions">When prompted, accept to share your audio and video stream.</p> + +<script> + +let video_only_valid_constraints = { + width: {min: 0}, + height: {min: 0}, + frameRate: {min: 0}, + aspectRatio: {min: 0}, + facingMode: {ideal: 'environment'}, + resizeMode: {ideal: 'none'} +} + +let video_only_invalid_constraints = { + width: {min: 100000000}, + height: {min: 100000000}, + frameRate: {min: 100000000}, + aspectRatio: {min: 100000000}, + facingMode: {exact: 'invalid'}, + resizeMode: {exact: 'invalid'} +} + +let audio_only_valid_constraints = { + volume: {min: 0}, + sampleRate: {min: 0}, + sampleSize: {min: 0}, + echoCancellation: {ideal: true}, + autoGainControl: {ideal: true}, + noiseSuppression: {ideal: true}, + latency: {min: 0}, + channelCount: {min: 0} +} + +let audio_only_invalid_constraints = { + volume: {min: 2}, + sampleRate: {min: 100000000}, + sampleSize: {min: 100000000}, + echoCancellation: {exact: true}, + autoGainControl: {exact: true}, + noiseSuppression: {exact: true}, + latency: {max: 0}, + channelCount: {max: 0} +} + +promise_test(async () => { + let stream = await navigator.mediaDevices.getUserMedia({audio: video_only_valid_constraints}) + assert_equals(stream.getAudioTracks().length, 1, "the media stream has exactly one audio track"); +}, 'Test that setting video-only valid constraints inside of "audio" is simply ignored'); + +promise_test(async () => { + let stream = await navigator.mediaDevices.getUserMedia({audio: video_only_invalid_constraints}) + assert_equals(stream.getAudioTracks().length, 1, "the media stream has exactly one audio track"); +}, 'Test that setting video-only invalid constraints inside of "audio" is simply ignored'); + +promise_test(async () => { + let stream = await navigator.mediaDevices.getUserMedia({video: audio_only_valid_constraints}) + assert_equals(stream.getVideoTracks().length, 1, "the media stream has exactly one video track"); +}, 'Test that setting audio-only valid constraints inside of "video" is simply ignored'); + +promise_test(async () => { + let stream = await navigator.mediaDevices.getUserMedia({video: audio_only_invalid_constraints}) + assert_equals(stream.getVideoTracks().length, 1, "the media stream has exactly one video track"); +}, 'Test that setting audio-only invalid constraints inside of "video" is simply ignored'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml index 0123b6b..20f3c7e6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml +++ b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml
@@ -2,3 +2,5 @@ suggested_reviewers: - birtles - theres-waldo + - graouts + - stephenmcgruer
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https-expected.txt new file mode 100644 index 0000000..5e4041d0f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL canvas is tainted after writing both a non-opaque image and an opaque image from the same URL assert_throws: function "() => { canvas.toDataURL(); }" did not throw +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html new file mode 100644 index 0000000..4e23305 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<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> +<meta charset="utf-8"> +<title>canvas tainting when written twice</title> +<script> +function loadImage(doc, url) { + return new Promise((resolve, reject) => { + const image = doc.createElement('img'); + image.onload = () => { resolve(image); } + image.onerror = () => { reject('failed to load: ' + url); }; + image.src = url; + }); +} + +// Tests that a canvas is tainted after it's written to with both a clear image +// and opaque image from the same URL. A bad implementation might cache the +// info of the clear image and assume the opaque image is also clear because +// it's from the same URL. See https://crbug.com/907047 for details. +promise_test(async (t) => { + // Set up a service worker and a controlled iframe. + const script = 'resources/fetch-canvas-tainting-double-write-worker.js'; + const scope = 'resources/fetch-canvas-tainting-double-write-iframe.html'; + const registration = await service_worker_unregister_and_register( + t, script, scope); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + const iframe = await with_iframe(scope); + t.add_cleanup(() => iframe.remove()); + + // Load the same cross-origin image URL through the controlled iframe and + // this uncontrolled frame. The service worker responds with a same-origin + // image for the controlled iframe, so it is cleartext. + const imagePath = base_path() + 'resources/fetch-access-control.py?PNGIMAGE'; + const imageUrl = get_host_info()['HTTPS_REMOTE_ORIGIN'] + imagePath; + const clearImage = await loadImage(iframe.contentDocument, imageUrl); + const opaqueImage = await loadImage(document, imageUrl); + + // Set up a canvas for testing tainting. + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + canvas.width = clearImage.width; + canvas.height = clearImage.height; + + // The clear image and the opaque image have the same src URL. But... + + // ... the clear image doesn't taint the canvas. + context.drawImage(clearImage, 0, 0); + assert_true(canvas.toDataURL().length > 0); + + // ... the opaque image taints the canvas. + context.drawImage(opaqueImage, 0, 0); + assert_throws('SecurityError', () => { canvas.toDataURL(); }); +}, 'canvas is tainted after writing both a non-opaque image and an opaque image from the same URL'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js new file mode 100644 index 0000000..17723dcd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js
@@ -0,0 +1,7 @@ +self.addEventListener('fetch', (event) => { + url = new URL(event.request.url); + if (url.search == '?PNGIMAGE') { + localUrl = new URL(url.pathname + url.search, self.location); + event.respondWith(fetch(localUrl)); + } +});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt index 8b0fd5b0..4b5d005c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt
@@ -32,6 +32,7 @@ PASS ReadableStream: should call underlying source methods as methods PASS ReadableStream: desiredSize when closed PASS ReadableStream: desiredSize when errored +PASS ReadableStream: ReadableStream is extendable PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately PASS ReadableStream integration test: adapting a random push source
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt index 8b0fd5b0..4b5d005c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt
@@ -32,6 +32,7 @@ PASS ReadableStream: should call underlying source methods as methods PASS ReadableStream: desiredSize when closed PASS ReadableStream: desiredSize when errored +PASS ReadableStream: ReadableStream is extendable PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately PASS ReadableStream integration test: adapting a random push source
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.js b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.js index 05382d4..c3cb0a9f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.js +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.js
@@ -775,6 +775,13 @@ }, 'ReadableStream: desiredSize when errored'); test(() => { + class Extended extends ReadableStream { + newMethod() { return 'foo' }; + }; + assert_equals((new Extended()).newMethod(), 'foo'); +}, 'ReadableStream: ReadableStream is extendable'); + +test(() => { let startCalled = false; new ReadableStream({
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt index d2229bb..084a1be 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt
@@ -33,6 +33,7 @@ PASS ReadableStream: should call underlying source methods as methods PASS ReadableStream: desiredSize when closed PASS ReadableStream: desiredSize when errored +PASS ReadableStream: ReadableStream is extendable PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately PASS ReadableStream integration test: adapting a random push source
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt index 8b0fd5b0..4b5d005c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt
@@ -32,6 +32,7 @@ PASS ReadableStream: should call underlying source methods as methods PASS ReadableStream: desiredSize when closed PASS ReadableStream: desiredSize when errored +PASS ReadableStream: ReadableStream is extendable PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately PASS ReadableStream integration test: adapting a random push source
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedEnumeration-SVGFEBlendElement.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedEnumeration-SVGFEBlendElement.html deleted file mode 100644 index b399264..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedEnumeration-SVGFEBlendElement.html +++ /dev/null
@@ -1,61 +0,0 @@ -<!DOCTYPE HTML> -<title>Use of SVGAnimatedEnumeration within SVGFEBlendElement</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -test(function() { - // This test checks the use of SVGAnimatedEnumeration within SVGFEBlendElement. - - var feBlendElement = document.createElementNS("http://www.w3.org/2000/svg", "feBlend"); - feBlendElement.setAttribute("mode", "normal"); - - // Check initial 'mode' value. - assert_true(feBlendElement.mode instanceof SVGAnimatedEnumeration); - assert_equals(typeof(feBlendElement.mode.baseVal), "number"); - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL); - - // Switch to 'multiply'. - feBlendElement.mode.baseVal = SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY; - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_MULTIPLY); - assert_equals(feBlendElement.getAttribute('mode'), "multiply"); - - // Switch to 'screen'. - feBlendElement.mode.baseVal = SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN; - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_SCREEN); - assert_equals(feBlendElement.getAttribute('mode'), "screen"); - - // Switch to 'darken'; - feBlendElement.mode.baseVal = SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN; - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_DARKEN); - assert_equals(feBlendElement.getAttribute('mode'), "darken"); - - // Switch to 'lighten' - feBlendElement.mode.baseVal = SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN; - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); - assert_equals(feBlendElement.getAttribute('mode'), "lighten"); - - // Try setting invalid values. - assert_throws(new TypeError(), function() { feBlendElement.mode.baseVal = 6; }); - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); - assert_equals(feBlendElement.getAttribute('mode'), "lighten"); - - assert_throws(new TypeError(), function() { feBlendElement.mode.baseVal = -1; }); - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); - assert_equals(feBlendElement.getAttribute('mode'), "lighten"); - - assert_throws(new TypeError(), function() { feBlendElement.mode.baseVal = 0; }); - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_LIGHTEN); - assert_equals(feBlendElement.getAttribute('mode'), "lighten"); - - // Switch to 'normal'. - feBlendElement.mode.baseVal = SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL; - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_NORMAL); - assert_equals(feBlendElement.getAttribute('mode'), "normal"); - - // baseVal access when mode is set to a value not in SVGFEBlendElement.SVG_FEBLEND_MODE_*. . - feBlendElement.setAttribute("mode", "color-dodge"); - assert_equals(feBlendElement.mode.baseVal, SVGFEBlendElement.SVG_FEBLEND_MODE_UNKNOWN); - assert_throws(new TypeError(), function() { feBlendElement.mode.baseVal = 13; }); - assert_equals(feBlendElement.getAttribute('mode'), "color-dodge"); -}); -</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html index 39cdf7b6..a3511263 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html
@@ -14,7 +14,7 @@ async_test(function() { var w1 = new SharedWorker('#1', 'x'); w1.port.addEventListener('message', this.step_func(function(e) { - assert_equals(e.data, 'x'); + assert_equals(e.data, 1); this.done(); }), false); w1.port.start();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/name-property-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/workers/name-property-expected.txt index 0c142db..30d73f9b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/name-property-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/name-property-expected.txt
@@ -3,7 +3,7 @@ PASS name property is replaceable for DedicatedWorkerGlobalScope PASS Declaring name as an accidental global must not cause a harness error for DedicatedWorkerGlobalScope FAIL name property value for SharedWorkerGlobalScope assert_equals: expected "my name" but got "[object Object]" -FAIL name property is replaceable for SharedWorkerGlobalScope Cannot assign to read only property 'name' of object '#<SharedWorkerGlobalScope>' -FAIL name-as-accidental-global Uncaught TypeError: Cannot assign to read only property 'name' of object '#<SharedWorkerGlobalScope>' +PASS name property is replaceable for SharedWorkerGlobalScope +PASS Declaring name as an accidental global must not cause a harness error for SharedWorkerGlobalScope Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/support/name.js b/third_party/WebKit/LayoutTests/external/wpt/workers/support/name.js index 7c42c78..970578e4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/support/name.js +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/support/name.js
@@ -2,8 +2,8 @@ importScripts("/resources/testharness.js"); test(() => { - assert_true(self.hasOwnProperty("name"), "property exists on the global") - assert_equals(self.name, "my name") + assert_true(self.hasOwnProperty("name"), "property exists on the global"); + assert_equals(self.name, "my name"); }, `name property value for ${self.constructor.name}`); test(() => {
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocking-timers6.html b/third_party/WebKit/LayoutTests/fast/events/popup-blocking-timers6.html index a39ce77..06034d6d 100644 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocking-timers6.html +++ b/third_party/WebKit/LayoutTests/fast/events/popup-blocking-timers6.html
@@ -12,12 +12,6 @@ } function clickHandler() { - if (internals.runtimeFlags.userActivationV2Enabled) { - if (window.testRunner) - testRunner.notifyDone(); - return; - } - setTimeout(function() { newWindow = window.open("about:blank"); self.focus();
diff --git a/third_party/WebKit/LayoutTests/fast/events/resources/open-window-from-another-frame-otherFrame.html b/third_party/WebKit/LayoutTests/fast/events/resources/open-window-from-another-frame-otherFrame.html index 26bc5bd..17f2172 100644 --- a/third_party/WebKit/LayoutTests/fast/events/resources/open-window-from-another-frame-otherFrame.html +++ b/third_party/WebKit/LayoutTests/fast/events/resources/open-window-from-another-frame-otherFrame.html
@@ -21,9 +21,11 @@ closeWin(newWin); } } else { - parent.log("Window was not opened! Test succeeded!"); - if (window.testRunner) - testRunner.notifyDone(); + if (!newWin) { + parent.log("Window was not opened! Test succeeded!"); + if (window.testRunner) + testRunner.notifyDone(); + } } event.preventDefault();
diff --git a/third_party/WebKit/LayoutTests/svg/filters/feBlend-invalid-mode-expected.txt b/third_party/WebKit/LayoutTests/svg/filters/feBlend-invalid-mode-expected.txt index 9f1771a..fb5aad461 100644 --- a/third_party/WebKit/LayoutTests/svg/filters/feBlend-invalid-mode-expected.txt +++ b/third_party/WebKit/LayoutTests/svg/filters/feBlend-invalid-mode-expected.txt
@@ -1,2 +1,2 @@ -CONSOLE ERROR: line 14: Uncaught TypeError: Failed to set the 'baseVal' property on 'SVGAnimatedEnumeration': The enumeration value provided (65535) is larger than the largest allowed value (5). +CONSOLE ERROR: line 14: Uncaught TypeError: Failed to set the 'baseVal' property on 'SVGAnimatedEnumeration': The enumeration value provided (65535) is larger than the largest allowed value (16). PASS: Invalid blend modes do not trigger a crash.
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt index 408499a4..3592be2 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -1445,11 +1445,22 @@ property systemLanguage property transform svg element feBlend + property SVG_FEBLEND_MODE_COLOR + property SVG_FEBLEND_MODE_COLOR_BURN + property SVG_FEBLEND_MODE_COLOR_DODGE property SVG_FEBLEND_MODE_DARKEN + property SVG_FEBLEND_MODE_DIFFERENCE + property SVG_FEBLEND_MODE_EXCLUSION + property SVG_FEBLEND_MODE_HARD_LIGHT + property SVG_FEBLEND_MODE_HUE property SVG_FEBLEND_MODE_LIGHTEN + property SVG_FEBLEND_MODE_LUMINOSITY property SVG_FEBLEND_MODE_MULTIPLY property SVG_FEBLEND_MODE_NORMAL + property SVG_FEBLEND_MODE_OVERLAY + property SVG_FEBLEND_MODE_SATURATION property SVG_FEBLEND_MODE_SCREEN + property SVG_FEBLEND_MODE_SOFT_LIGHT property SVG_FEBLEND_MODE_UNKNOWN property height property in1
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index 6cdbeeff..2585c8d6 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -5403,11 +5403,22 @@ method constructor interface SVGFEBlendElement : SVGElement attribute @@toStringTag + attribute SVG_FEBLEND_MODE_COLOR + attribute SVG_FEBLEND_MODE_COLOR_BURN + attribute SVG_FEBLEND_MODE_COLOR_DODGE attribute SVG_FEBLEND_MODE_DARKEN + attribute SVG_FEBLEND_MODE_DIFFERENCE + attribute SVG_FEBLEND_MODE_EXCLUSION + attribute SVG_FEBLEND_MODE_HARD_LIGHT + attribute SVG_FEBLEND_MODE_HUE attribute SVG_FEBLEND_MODE_LIGHTEN + attribute SVG_FEBLEND_MODE_LUMINOSITY attribute SVG_FEBLEND_MODE_MULTIPLY attribute SVG_FEBLEND_MODE_NORMAL + attribute SVG_FEBLEND_MODE_OVERLAY + attribute SVG_FEBLEND_MODE_SATURATION attribute SVG_FEBLEND_MODE_SCREEN + attribute SVG_FEBLEND_MODE_SOFT_LIGHT attribute SVG_FEBLEND_MODE_UNKNOWN getter height getter in1
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 88a6e93..3a6ba4f 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -2491,6 +2491,7 @@ [Worker] method webkitRequestFileSystemSync [Worker] method webkitResolveLocalFileSystemSyncURL [Worker] method webkitResolveLocalFileSystemURL +[Worker] setter name [Worker] setter onconnect PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/virtual/streaming-preload/external/wpt/html/semantics/scripting-1/README.txt b/third_party/WebKit/LayoutTests/virtual/streaming-preload/external/wpt/html/semantics/scripting-1/README.txt new file mode 100644 index 0000000..38c97164 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/streaming-preload/external/wpt/html/semantics/scripting-1/README.txt
@@ -0,0 +1,2 @@ +# This suite runs the tests in external/wpt/html/semantics/scripting-1 with the +# flag --enable-feature=ScriptStreamingOnPreload \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/virtual/streaming-preload/http/tests/fetch/README.txt b/third_party/WebKit/LayoutTests/virtual/streaming-preload/http/tests/fetch/README.txt new file mode 100644 index 0000000..45ff0e3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/streaming-preload/http/tests/fetch/README.txt
@@ -0,0 +1,2 @@ +# This suite runs the tests in http/tests/fetch with the flag +# --enable-feature=ScriptStreamingOnPreload \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fast/events/popup-blocking-timers6-expected.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fast/events/popup-blocking-timers6-expected.txt deleted file mode 100644 index 875cc83..0000000 --- a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fast/events/popup-blocking-timers6-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Click Here -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt index 3db6052b..a5c5b57a 100644 --- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -1565,11 +1565,22 @@ property systemLanguage property transform svg element feBlend + property SVG_FEBLEND_MODE_COLOR + property SVG_FEBLEND_MODE_COLOR_BURN + property SVG_FEBLEND_MODE_COLOR_DODGE property SVG_FEBLEND_MODE_DARKEN + property SVG_FEBLEND_MODE_DIFFERENCE + property SVG_FEBLEND_MODE_EXCLUSION + property SVG_FEBLEND_MODE_HARD_LIGHT + property SVG_FEBLEND_MODE_HUE property SVG_FEBLEND_MODE_LIGHTEN + property SVG_FEBLEND_MODE_LUMINOSITY property SVG_FEBLEND_MODE_MULTIPLY property SVG_FEBLEND_MODE_NORMAL + property SVG_FEBLEND_MODE_OVERLAY + property SVG_FEBLEND_MODE_SATURATION property SVG_FEBLEND_MODE_SCREEN + property SVG_FEBLEND_MODE_SOFT_LIGHT property SVG_FEBLEND_MODE_UNKNOWN property height property in1
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 3edaacc..ec0b35e 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -2047,6 +2047,7 @@ setter slot interface ElementInternals attribute @@toStringTag + getter form method constructor interface EnterPictureInPictureEvent : Event attribute @@toStringTag @@ -6168,11 +6169,22 @@ method constructor interface SVGFEBlendElement : SVGElement attribute @@toStringTag + attribute SVG_FEBLEND_MODE_COLOR + attribute SVG_FEBLEND_MODE_COLOR_BURN + attribute SVG_FEBLEND_MODE_COLOR_DODGE attribute SVG_FEBLEND_MODE_DARKEN + attribute SVG_FEBLEND_MODE_DIFFERENCE + attribute SVG_FEBLEND_MODE_EXCLUSION + attribute SVG_FEBLEND_MODE_HARD_LIGHT + attribute SVG_FEBLEND_MODE_HUE attribute SVG_FEBLEND_MODE_LIGHTEN + attribute SVG_FEBLEND_MODE_LUMINOSITY attribute SVG_FEBLEND_MODE_MULTIPLY attribute SVG_FEBLEND_MODE_NORMAL + attribute SVG_FEBLEND_MODE_OVERLAY + attribute SVG_FEBLEND_MODE_SATURATION attribute SVG_FEBLEND_MODE_SCREEN + attribute SVG_FEBLEND_MODE_SOFT_LIGHT attribute SVG_FEBLEND_MODE_UNKNOWN getter height getter in1
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 15cfa1c..19d2829d 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -3461,6 +3461,7 @@ [Worker] method webkitRequestFileSystemSync [Worker] method webkitResolveLocalFileSystemSyncURL [Worker] method webkitResolveLocalFileSystemURL +[Worker] setter name [Worker] setter onconnect PASS successfullyParsed is true
diff --git a/third_party/blink/public/platform/reporting.mojom b/third_party/blink/public/platform/reporting.mojom index f1da9a34..34cd006e 100644 --- a/third_party/blink/public/platform/reporting.mojom +++ b/third_party/blink/public/platform/reporting.mojom
@@ -50,9 +50,9 @@ // // (See //third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h.) QueueFeaturePolicyViolationReport(url.mojom.Url url, - string policy, + string policy_id, string disposition, - string message, + string? message, string? source_file, int32 line_number, int32 column_number);
diff --git a/third_party/blink/public/platform/web_database_observer.h b/third_party/blink/public/platform/web_database_observer.h index abe32e96..7bd01496 100644 --- a/third_party/blink/public/platform/web_database_observer.h +++ b/third_party/blink/public/platform/web_database_observer.h
@@ -48,35 +48,9 @@ const WebString& database_name) = 0; virtual void DatabaseClosed(const WebSecurityOrigin&, const WebString& database_name) = 0; - virtual void ReportOpenDatabaseResult(const WebSecurityOrigin&, - const WebString& database_name, - int error_site, - int web_sql_error_code, - int sqlite_error_code, - base::TimeDelta call_time) {} - virtual void ReportChangeVersionResult(const WebSecurityOrigin&, - const WebString& database_name, - int error_site, - int web_sql_error_code, - int sqlite_error_code) {} - virtual void ReportStartTransactionResult(const WebSecurityOrigin&, - const WebString& database_name, - int error_site, - int web_sql_error_code, - int sqlite_error_code) {} - virtual void ReportCommitTransactionResult(const WebSecurityOrigin&, - const WebString& database_name, - int error_site, - int web_sql_error_code, - int sqlite_error_code) {} - virtual void ReportExecuteStatementResult(const WebSecurityOrigin&, - const WebString& database_name, - int error_site, - int web_sql_error_code, - int sqlite_error_code) {} - virtual void ReportVacuumDatabaseResult(const WebSecurityOrigin&, - const WebString& database_name, - int sqlite_error_code) {} + virtual void ReportSqliteError(const blink::WebSecurityOrigin& origin, + const blink::WebString& database_name, + int error) = 0; protected: ~WebDatabaseObserver() = default;
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 7cbf7a8..656b938 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -206,6 +206,7 @@ BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool); BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool); BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool); + BLINK_PLATFORM_EXPORT static void EnableScriptStreamingOnPreload(bool); BLINK_PLATFORM_EXPORT static void EnableExperimentalProductivityFeatures( bool); BLINK_PLATFORM_EXPORT static void EnableAutoplayIgnoresWebAudio(bool);
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni index 60df557b..3e9cd6a 100644 --- a/third_party/blink/renderer/bindings/bindings.gni +++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -21,6 +21,7 @@ "core/v8/custom/v8_message_event_custom.cc", "core/v8/custom/v8_pop_state_event_custom.cc", "core/v8/custom/v8_promise_rejection_event_custom.cc", + "core/v8/custom/v8_readable_stream_custom.cc", "core/v8/custom/v8_shadow_root_custom.cc", "core/v8/custom/v8_window_custom.cc", "core/v8/custom/v8_xml_http_request_custom.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/third_party/blink/renderer/bindings/core/v8/BUILD.gn index 79b8bfa5..b37b8ca1 100644 --- a/third_party/blink/renderer/bindings/core/v8/BUILD.gn +++ b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -144,6 +144,10 @@ "$bindings_core_v8_output_dir/v8_custom_element_attribute_changed_callback.h", "$bindings_core_v8_output_dir/v8_custom_element_constructor.cc", "$bindings_core_v8_output_dir/v8_custom_element_constructor.h", + "$bindings_core_v8_output_dir/v8_custom_element_disabled_state_changed_callback.cc", + "$bindings_core_v8_output_dir/v8_custom_element_disabled_state_changed_callback.h", + "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.cc", + "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.h", "$bindings_core_v8_output_dir/v8_display_lock_callback.cc", "$bindings_core_v8_output_dir/v8_display_lock_callback.h", "$bindings_core_v8_output_dir/v8_event_handler_non_null.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc new file mode 100644 index 0000000..26e55d3 --- /dev/null +++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/v8_binding.h" +#include "v8/include/v8.h" + +namespace blink { + +void V8ReadableStream::constructorCustom( + const v8::FunctionCallbackInfo<v8::Value>& info) { + RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT( + info.GetIsolate(), "Blink_ReadableStream_ConstructorCallback"); + + ExceptionState exception_state(info.GetIsolate(), + ExceptionState::kConstructionContext, + "ReadableStream"); + ScriptState* script_state = + ScriptState::From(info.NewTarget().As<v8::Object>()->CreationContext()); + + ScriptValue underlying_source = + ScriptValue(ScriptState::Current(info.GetIsolate()), + v8::Undefined(info.GetIsolate())); + ScriptValue strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), + v8::Undefined(info.GetIsolate())); + int num_args = info.Length(); + auto* impl = MakeGarbageCollected<ReadableStream>(); + v8::Local<v8::Object> wrapper = info.Holder(); + wrapper = impl->AssociateWithWrapper( + info.GetIsolate(), &V8ReadableStream::wrapperTypeInfo, wrapper); + + if (num_args >= 1) { + underlying_source = + ScriptValue(ScriptState::Current(info.GetIsolate()), info[0]); + } + if (num_args >= 2) + strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), info[1]); + + impl->Init(script_state, underlying_source, strategy, exception_state); + if (exception_state.HadException()) { + return; + } + V8SetReturnValue(info, wrapper); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc index e58e4603..07cfd3f 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -93,8 +93,8 @@ const ScriptFetchOptions& fetch_options) { TRACE_EVENT1( "devtools.timeline", "EvaluateScript", "data", - InspectorEvaluateScriptEvent::Data(GetFrame(), source.Url().GetString(), - source.StartPosition())); + inspector_evaluate_script_event::Data( + GetFrame(), source.Url().GetString(), source.StartPosition())); v8::Local<v8::Value> result; { V8CacheOptions v8_cache_options = kV8CacheOptionsDefault;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc index 1c3625d..db2db818 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
@@ -8,6 +8,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_adopted_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_attribute_changed_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_constructor.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_disabled_state_changed_callback.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_form_associated_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element.h" #include "third_party/blink/renderer/bindings/core/v8/v8_function.h" @@ -81,13 +83,19 @@ V8VoidFunction* disconnected_callback, V8CustomElementAdoptedCallback* adopted_callback, V8CustomElementAttributeChangedCallback* attribute_changed_callback, + V8CustomElementFormAssociatedCallback* form_associated_callback, + V8CustomElementDisabledStateChangedCallback* + disabled_state_changed_callback, HashSet<AtomicString>&& observed_attributes, - const Vector<String>& disabled_features) { + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag) { ScriptCustomElementDefinition* definition = MakeGarbageCollected<ScriptCustomElementDefinition>( script_state, descriptor, constructor, connected_callback, disconnected_callback, adopted_callback, attribute_changed_callback, - std::move(observed_attributes), disabled_features); + form_associated_callback, disabled_state_changed_callback, + std::move(observed_attributes), disabled_features, + form_association_flag); // Tag the JavaScript constructor object with its ID. v8::Local<v8::Value> id_value = @@ -109,17 +117,24 @@ V8VoidFunction* disconnected_callback, V8CustomElementAdoptedCallback* adopted_callback, V8CustomElementAttributeChangedCallback* attribute_changed_callback, + V8CustomElementFormAssociatedCallback* form_associated_callback, + V8CustomElementDisabledStateChangedCallback* + disabled_state_changed_callback, HashSet<AtomicString>&& observed_attributes, - const Vector<String>& disabled_features) + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag) : CustomElementDefinition(descriptor, std::move(observed_attributes), - disabled_features), + disabled_features, + form_association_flag), script_state_(script_state), constructor_(constructor), connected_callback_(connected_callback), disconnected_callback_(disconnected_callback), adopted_callback_(adopted_callback), - attribute_changed_callback_(attribute_changed_callback) {} + attribute_changed_callback_(attribute_changed_callback), + form_associated_callback_(form_associated_callback), + disabled_state_changed_callback_(disabled_state_changed_callback) {} void ScriptCustomElementDefinition::Trace(Visitor* visitor) { visitor->Trace(script_state_); @@ -128,6 +143,8 @@ visitor->Trace(disconnected_callback_); visitor->Trace(adopted_callback_); visitor->Trace(attribute_changed_callback_); + visitor->Trace(form_associated_callback_); + visitor->Trace(disabled_state_changed_callback_); CustomElementDefinition::Trace(visitor); } @@ -268,6 +285,14 @@ return adopted_callback_; } +bool ScriptCustomElementDefinition::HasFormAssociatedCallback() const { + return form_associated_callback_; +} + +bool ScriptCustomElementDefinition::HasDisabledStateChangedCallback() const { + return disabled_state_changed_callback_; +} + void ScriptCustomElementDefinition::RunConnectedCallback(Element* element) { if (!connected_callback_) return; @@ -303,4 +328,21 @@ element, name.LocalName(), old_value, new_value, name.NamespaceURI()); } +void ScriptCustomElementDefinition::RunFormAssociatedCallback( + Element* element, + HTMLFormElement* nullable_form) { + if (!form_associated_callback_) + return; + form_associated_callback_->InvokeAndReportException(element, nullable_form); +} + +void ScriptCustomElementDefinition::RunDisabledStateChangedCallback( + Element* element, + bool is_disabled) { + if (!disabled_state_changed_callback_) + return; + disabled_state_changed_callback_->InvokeAndReportException(element, + is_disabled); +} + } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h index 336b627d..4a1eb049 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h +++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
@@ -20,6 +20,8 @@ class V8CustomElementAdoptedCallback; class V8CustomElementAttributeChangedCallback; class V8CustomElementConstructor; +class V8CustomElementDisabledStateChangedCallback; +class V8CustomElementFormAssociatedCallback; class V8VoidFunction; class CORE_EXPORT ScriptCustomElementDefinition final @@ -42,8 +44,12 @@ V8VoidFunction* disconnected_callback, V8CustomElementAdoptedCallback* adopted_callback, V8CustomElementAttributeChangedCallback* attribute_changed_callback, + V8CustomElementFormAssociatedCallback* form_associated_callback, + V8CustomElementDisabledStateChangedCallback* + disabled_state_changed_callback, HashSet<AtomicString>&& observed_attributes, - const Vector<String>& disabled_features); + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag); ScriptCustomElementDefinition( ScriptState*, @@ -53,8 +59,12 @@ V8VoidFunction* disconnected_callback, V8CustomElementAdoptedCallback* adopted_callback, V8CustomElementAttributeChangedCallback* attribute_changed_callback, + V8CustomElementFormAssociatedCallback* form_associated_callback, + V8CustomElementDisabledStateChangedCallback* + disabled_state_changed_callback, HashSet<AtomicString>&& observed_attributes, - const Vector<String>& disabled_features); + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag); ~ScriptCustomElementDefinition() override = default; void Trace(Visitor*) override; @@ -67,6 +77,8 @@ bool HasConnectedCallback() const override; bool HasDisconnectedCallback() const override; bool HasAdoptedCallback() const override; + bool HasFormAssociatedCallback() const override; + bool HasDisabledStateChangedCallback() const override; void RunConnectedCallback(Element*) override; void RunDisconnectedCallback(Element*) override; @@ -77,6 +89,10 @@ const QualifiedName&, const AtomicString& old_value, const AtomicString& new_value) override; + void RunFormAssociatedCallback(Element* element, + HTMLFormElement* nullable_form) override; + void RunDisabledStateChangedCallback(Element* element, + bool is_disabled) override; private: // Implementations of |CustomElementDefinition| @@ -98,6 +114,10 @@ TraceWrapperMember<V8CustomElementAdoptedCallback> adopted_callback_; TraceWrapperMember<V8CustomElementAttributeChangedCallback> attribute_changed_callback_; + TraceWrapperMember<V8CustomElementFormAssociatedCallback> + form_associated_callback_; + TraceWrapperMember<V8CustomElementDisabledStateChangedCallback> + disabled_state_changed_callback_; }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc index 1f52e9f..79f2c83 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc
@@ -12,6 +12,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_adopted_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_attribute_changed_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_constructor.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_disabled_state_changed_callback.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_form_associated_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h" #include "third_party/blink/renderer/platform/bindings/callback_method_retriever.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" @@ -147,6 +149,47 @@ } } + if (RuntimeEnabledFeatures::FormAssociatedCustomElementsEnabled()) { + auto* isolate = script_state_->GetIsolate(); + v8::Local<v8::Context> current_context = isolate->GetCurrentContext(); + v8::TryCatch try_catch(isolate); + v8::Local<v8::Value> v8_form_associated; + + if (!constructor_->CallbackObject() + ->Get(current_context, V8AtomicString(isolate, "formAssociated")) + .ToLocal(&v8_form_associated)) { + exception_state_.RethrowV8Exception(try_catch.Exception()); + return false; + } + + if (!v8_form_associated->IsUndefined()) { + is_form_associated_ = NativeValueTraits<IDLBoolean>::NativeValue( + isolate, v8_form_associated, exception_state_); + if (exception_state_.HadException()) + return false; + } + } + if (is_form_associated_) { + v8_form_associated_callback_ = retriever.GetMethodOrUndefined( + "formAssociatedCallback", exception_state_); + if (exception_state_.HadException()) + return false; + if (v8_form_associated_callback_->IsFunction()) { + form_associated_callback_ = V8CustomElementFormAssociatedCallback::Create( + v8_form_associated_callback_.As<v8::Function>()); + } + + v8_disabled_state_changed_callback_ = retriever.GetMethodOrUndefined( + "disabledStateChangedCallback", exception_state_); + if (exception_state_.HadException()) + return false; + if (v8_disabled_state_changed_callback_->IsFunction()) { + disabled_state_changed_callback_ = + V8CustomElementDisabledStateChangedCallback::Create( + v8_disabled_state_changed_callback_.As<v8::Function>()); + } + } + return true; } @@ -156,8 +199,11 @@ return ScriptCustomElementDefinition::Create( script_state_, registry_, descriptor, id, constructor_, connected_callback_, disconnected_callback_, adopted_callback_, - attribute_changed_callback_, std::move(observed_attributes_), - disabled_features_); + attribute_changed_callback_, form_associated_callback_, + disabled_state_changed_callback_, std::move(observed_attributes_), + disabled_features_, + is_form_associated_ ? FormAssociationFlag::kYes + : FormAssociationFlag::kNo); } } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h index e7ade99d..c343194 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h +++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h
@@ -25,6 +25,8 @@ class V8CustomElementAdoptedCallback; class V8CustomElementAttributeChangedCallback; class V8CustomElementConstructor; +class V8CustomElementDisabledStateChangedCallback; +class V8CustomElementFormAssociatedCallback; class V8VoidFunction; class CORE_EXPORT ScriptCustomElementDefinitionBuilder @@ -57,12 +59,18 @@ v8::Local<v8::Value> v8_disconnected_callback_; v8::Local<v8::Value> v8_adopted_callback_; v8::Local<v8::Value> v8_attribute_changed_callback_; + v8::Local<v8::Value> v8_form_associated_callback_; + v8::Local<v8::Value> v8_disabled_state_changed_callback_; Member<V8VoidFunction> connected_callback_; Member<V8VoidFunction> disconnected_callback_; Member<V8CustomElementAdoptedCallback> adopted_callback_; Member<V8CustomElementAttributeChangedCallback> attribute_changed_callback_; + Member<V8CustomElementFormAssociatedCallback> form_associated_callback_; + Member<V8CustomElementDisabledStateChangedCallback> + disabled_state_changed_callback_; HashSet<AtomicString> observed_attributes_; Vector<String> disabled_features_; + bool is_form_associated_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index 40a98c8..c254dfa 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -313,8 +313,8 @@ ScriptStreamer* streamer) { TRACE_EVENT1( "v8,devtools.timeline", "v8.parseOnBackground", "data", - InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(), - streamer->ScriptURLString())); + inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(), + streamer->ScriptURLString())); // Running the task can and will block: SourceStream::GetSomeData will get // called and it will block and wait for data from the network. task->Run();
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc index 4bd5bf7..3433c20 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
@@ -69,8 +69,8 @@ DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); TRACE_EVENT1( "v8,devtools.timeline", "v8.parseOnBackground", "data", - InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(), - streamer->ScriptURLString())); + inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(), + streamer->ScriptURLString())); // Running the task can and will block: SourceStream::GetSomeData will get // called and it will block and wait for data from the network. task->Run();
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc index 7898b09..9faae3c 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
@@ -223,12 +223,12 @@ TRACE_EVENT_END1( kTraceEventCategoryGroup, "v8.compile", "data", - InspectorCompileScriptEvent::Data( + inspector_compile_script_event::Data( source.Url().GetString(), source.StartPosition(), - InspectorCompileScriptEvent::V8CacheResult( - InspectorCompileScriptEvent::V8CacheResult::ProduceResult( + inspector_compile_script_event::V8CacheResult( + inspector_compile_script_event::V8CacheResult::ProduceResult( compile_options, cached_data ? cached_data->length : 0), - base::Optional<InspectorCompileScriptEvent::V8CacheResult:: + base::Optional<inspector_compile_script_event::V8CacheResult:: ConsumeResult>()), source.Streamer(), source.NotStreamingReason())); break; @@ -311,14 +311,14 @@ TRACE_EVENT_END1( kTraceEventCategoryGroup, "v8.compile", "data", - InspectorCompileScriptEvent::Data( + inspector_compile_script_event::Data( file_name, TextPosition(), - InspectorCompileScriptEvent::V8CacheResult( - InspectorCompileScriptEvent::V8CacheResult::ProduceResult( + inspector_compile_script_event::V8CacheResult( + inspector_compile_script_event::V8CacheResult::ProduceResult( v8::ScriptCompiler::kEagerCompile, cached_data ? cached_data->length : 0), - base::Optional< - InspectorCompileScriptEvent::V8CacheResult::ConsumeResult>()), + base::Optional<inspector_compile_script_event::V8CacheResult:: + ConsumeResult>()), false, ScriptStreamer::kHasCodeCache)); return cached_metadata;
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc index e3c681d..753e61b 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -322,7 +322,7 @@ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorUpdateCountersEvent::Data()); + inspector_update_counters_event::Data()); } void V8GCController::CollectAllGarbageForTesting(
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index e60e055..af58d8a 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -98,7 +98,7 @@ v8::ScriptOrigin origin, v8::ScriptCompiler::CompileOptions compile_options, v8::ScriptCompiler::NoCacheReason no_cache_reason, - InspectorCompileScriptEvent::V8CacheResult* cache_result) { + inspector_compile_script_event::V8CacheResult* cache_result) { v8::Local<v8::String> code = V8String(isolate, source_code.Source()); if (ScriptStreamer* streamer = source_code.Streamer()) { @@ -147,7 +147,7 @@ } if (cache_result) { cache_result->consume_result = base::make_optional( - InspectorCompileScriptEvent::V8CacheResult::ConsumeResult( + inspector_compile_script_event::V8CacheResult::ConsumeResult( v8::ScriptCompiler::kConsumeCodeCache, cached_data->length, cached_data->rejected)); } @@ -212,12 +212,12 @@ compile_options, no_cache_reason, nullptr); } - InspectorCompileScriptEvent::V8CacheResult cache_result; + inspector_compile_script_event::V8CacheResult cache_result; v8::MaybeLocal<v8::Script> script = CompileScriptInternal(isolate, execution_context, source, origin, compile_options, no_cache_reason, &cache_result); TRACE_EVENT_END1(kTraceEventCategoryGroup, "v8.compile", "data", - InspectorCompileScriptEvent::Data( + inspector_compile_script_event::Data( file_name, script_start_position, cache_result, source.Streamer(), source.NotStreamingReason())); return script;
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc index 9b8c92b..0511190 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
@@ -115,103 +115,6 @@ const Member<ScriptState> script_state_; }; -// TODO(ahaas): Remove |FetchDataLoaderAsWasmModule| once the -// |SetWasmCompileStreamingCallback| API is successfully replaced by the -// |SetWasmStreamingCallback| API. -class FetchDataLoaderAsWasmModule final : public FetchDataLoader, - public BytesConsumer::Client { - USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsWasmModule); - - public: - explicit FetchDataLoaderAsWasmModule(ScriptState* script_state) - : builder_(script_state->GetIsolate()), script_state_(script_state) {} - - void Start(BytesConsumer* consumer, - FetchDataLoader::Client* client) override { - DCHECK(!consumer_); - DCHECK(!client_); - client_ = client; - consumer_ = consumer; - consumer_->SetClient(this); - OnStateChange(); - } - - v8::Local<v8::Promise> GetPromise() { return builder_.GetPromise(); } - - void OnStateChange() override { - while (true) { - // |buffer| is owned by |consumer_|. - const char* buffer = nullptr; - size_t available = 0; - BytesConsumer::Result result = consumer_->BeginRead(&buffer, &available); - - if (result == BytesConsumer::Result::kShouldWait) - return; - if (result == BytesConsumer::Result::kOk) { - if (available > 0) { - DCHECK_NE(buffer, nullptr); - builder_.OnBytesReceived(reinterpret_cast<const uint8_t*>(buffer), - available); - } - result = consumer_->EndRead(available); - } - switch (result) { - case BytesConsumer::Result::kShouldWait: - NOTREACHED(); - return; - case BytesConsumer::Result::kOk: { - break; - } - case BytesConsumer::Result::kDone: { - ScriptState::Scope scope(script_state_); - builder_.Finish(); - client_->DidFetchDataLoadedCustomFormat(); - return; - } - case BytesConsumer::Result::kError: { - return AbortCompilation(); - } - } - } - } - - String DebugName() const override { return "FetchDataLoaderAsWasmModule"; } - - void Cancel() override { - consumer_->Cancel(); - return AbortCompilation(); - } - - void Trace(blink::Visitor* visitor) override { - visitor->Trace(consumer_); - visitor->Trace(client_); - visitor->Trace(script_state_); - FetchDataLoader::Trace(visitor); - BytesConsumer::Client::Trace(visitor); - } - - private: - // TODO(mtrofin): replace with spec-ed error types, once spec clarifies - // what they are. - void AbortCompilation() { - if (script_state_->ContextIsValid()) { - ScriptState::Scope scope(script_state_); - builder_.Abort(V8ThrowException::CreateTypeError( - script_state_->GetIsolate(), "Could not download wasm module")); - } else { - // We are not allowed to execute a script, which indicates that we should - // not reject the promise of the streaming compilation. By passing no - // abort reason, we indicate the V8 side that the promise should not get - // rejected. - builder_.Abort(v8::Local<v8::Value>()); - } - } - TraceWrapperMember<BytesConsumer> consumer_; - Member<FetchDataLoader::Client> client_; - v8::WasmModuleObjectBuilderStreaming builder_; - const Member<ScriptState> script_state_; -}; - // TODO(mtrofin): WasmDataLoaderClient is necessary so we may provide an // argument to BodyStreamBuffer::startLoading, however, it fulfills // a very small role. Consider refactoring to avoid it. @@ -324,109 +227,9 @@ exception_state); } -// This callback may be entered as a promise is resolved, or directly -// from the overload callback. -// See -// https://github.com/WebAssembly/design/blob/master/Web.md#webassemblycompile -void CompileFromResponseCallback( - const v8::FunctionCallbackInfo<v8::Value>& args) { - ExceptionState exception_state(args.GetIsolate(), - ExceptionState::kExecutionContext, - "WebAssembly", "compile"); - ExceptionToRejectPromiseScope reject_promise_scope(args, exception_state); - - ScriptState* script_state = ScriptState::ForCurrentRealm(args); - if (!script_state->ContextIsValid()) { - V8SetReturnValue(args, ScriptPromise().V8Value()); - return; - } - - Response* response = - V8Response::ToImplWithTypeCheck(args.GetIsolate(), args[0]); - if (!response) { - exception_state.ThrowTypeError( - "An argument must be provided, which must be a " - "Response or Promise<Response> object"); - return; - } - - if (!response->ok()) { - exception_state.ThrowTypeError("HTTP status code is not ok"); - return; - } - - if (response->MimeType() != "application/wasm") { - exception_state.ThrowTypeError( - "Incorrect response MIME type. Expected 'application/wasm'."); - return; - } - - Body::BodyLocked body_locked = response->IsBodyLocked(exception_state); - if (body_locked == Body::BodyLocked::kBroken) - return; - - if (body_locked == Body::BodyLocked::kLocked || - response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { - DCHECK(!exception_state.HadException()); - exception_state.ThrowTypeError( - "Cannot compile WebAssembly.Module from an already read Response"); - return; - } - - if (exception_state.HadException()) - return; - - if (!response->BodyBuffer()) { - exception_state.ThrowTypeError("Response object has a null body."); - return; - } - - FetchDataLoaderAsWasmModule* loader = - new FetchDataLoaderAsWasmModule(script_state); - v8::Local<v8::Value> promise = loader->GetPromise(); - response->BodyBuffer()->StartLoading(loader, new WasmDataLoaderClient(), - exception_state); - if (exception_state.HadException()) - return; - - V8SetReturnValue(args, promise); -} - -// See https://crbug.com/708238 for tracking avoiding the hand-generated code. -void WasmCompileStreamingImpl(const v8::FunctionCallbackInfo<v8::Value>& args) { - ScriptState* script_state = ScriptState::ForCurrentRealm(args); - V8PerIsolateData* per_isolate_data = - V8PerIsolateData::From(script_state->GetIsolate()); - - // An unique key of the v8::FunctionTemplate cache in V8PerIsolateData. - // Everyone uses address of something as a key, so the address of |unique_key| - // is guaranteed to be unique for the function template cache. - static const int unique_key = 0; - v8::Local<v8::FunctionTemplate> function_template = - per_isolate_data->FindOrCreateOperationTemplate( - script_state->World(), &unique_key, CompileFromResponseCallback, - v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 1); - v8::Local<v8::Function> compile_callback; - if (!function_template->GetFunction(script_state->GetContext()) - .ToLocal(&compile_callback)) { - return; // Throw an exception. - } - - // treat either case of parameter as - // Promise.resolve(parameter) - // as per https://www.w3.org/2001/tag/doc/promises-guide#resolve-arguments - - // Ending with: - // return Promise.resolve(parameter).then(compileCallback); - V8SetReturnValue(args, ScriptPromise::Cast(script_state, args[0]) - .Then(compile_callback) - .V8Value()); -} - } // namespace void WasmResponseExtensions::Initialize(v8::Isolate* isolate) { - isolate->SetWasmCompileStreamingCallback(WasmCompileStreamingImpl); isolate->SetWasmStreamingCallback(StreamFromResponseCallback); }
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc index 8ede0bd4..d165e15 100644 --- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -258,8 +258,8 @@ DCHECK(IsContextInitialized()); TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", - InspectorEvaluateScriptEvent::Data(nullptr, source_code.Url(), - source_code.StartPosition())); + inspector_evaluate_script_event::Data( + nullptr, source_code.Url(), source_code.StartPosition())); ScriptState::Scope scope(script_state_);
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index 52ffa85..bab13ca 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -1142,19 +1142,21 @@ if (old_play_state != new_play_state) { bool was_active = old_play_state == kPending || old_play_state == kRunning; bool is_active = new_play_state == kPending || new_play_state == kRunning; - if (!was_active && is_active) + if (!was_active && is_active) { TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( "blink.animations,devtools.timeline,benchmark,rail", "Animation", - animation_, "data", InspectorAnimationEvent::Data(*animation_)); - else if (was_active && !is_active) + animation_, "data", inspector_animation_event::Data(*animation_)); + } else if (was_active && !is_active) { TRACE_EVENT_NESTABLE_ASYNC_END1( "blink.animations,devtools.timeline,benchmark,rail", "Animation", animation_, "endData", - InspectorAnimationStateEvent::Data(*animation_)); - else + inspector_animation_state_event::Data(*animation_)); + } else { TRACE_EVENT_NESTABLE_ASYNC_INSTANT1( "blink.animations,devtools.timeline,benchmark,rail", "Animation", - animation_, "data", InspectorAnimationStateEvent::Data(*animation_)); + animation_, "data", + inspector_animation_state_event::Data(*animation_)); + } } // Ordering is important, the ready promise should resolve/reject before
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index cf65b07..a8bdb4b5 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -528,7 +528,7 @@ for (const auto& entry : pending_update_.NewAnimations()) { const InertEffect* inert_animation = entry.effect.Get(); AnimationEventDelegate* event_delegate = - new AnimationEventDelegate(element, entry.name); + MakeGarbageCollected<AnimationEventDelegate>(element, entry.name); KeyframeEffect* effect = KeyframeEffect::Create( element, inert_animation->Model(), inert_animation->SpecifiedTiming(), KeyframeEffect::kDefaultPriority, event_delegate); @@ -538,7 +538,8 @@ animation->pause(); animation->Update(kTimingUpdateOnDemand); - running_animations_.push_back(new RunningAnimation(animation, entry)); + running_animations_.push_back( + MakeGarbageCollected<RunningAnimation>(animation, entry)); } // Transitions that are run on the compositor only update main-thread state @@ -592,7 +593,7 @@ const PropertyHandle& property = new_transition.property; const InertEffect* inert_animation = new_transition.effect.Get(); TransitionEventDelegate* event_delegate = - new TransitionEventDelegate(element, property); + MakeGarbageCollected<TransitionEventDelegate>(element, property); KeyframeEffectModelBase* model = inert_animation->Model();
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index 133c44a..0bdef44 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -540,7 +540,7 @@ "frame/navigator_user_activation.idl", "frame/window_base64.idl", "frame/window_event_handlers.idl", - "frame/window_timers.idl", + "frame/window_or_worker_global_scope.idl", "fullscreen/document_fullscreen.idl", "fullscreen/element_fullscreen.idl", "html/html_hyperlink_element_utils.idl",
diff --git a/third_party/blink/renderer/core/css/css_calculation_value.cc b/third_party/blink/renderer/core/css/css_calculation_value.cc index 6145bbf3..cac6c210 100644 --- a/third_party/blink/renderer/core/css/css_calculation_value.cc +++ b/third_party/blink/renderer/core/css/css_calculation_value.cc
@@ -165,7 +165,7 @@ public: static CSSCalcPrimitiveValue* Create(CSSPrimitiveValue* value, bool is_integer) { - return new CSSCalcPrimitiveValue(value, is_integer); + return MakeGarbageCollected<CSSCalcPrimitiveValue>(value, is_integer); } static CSSCalcPrimitiveValue* Create(double value, @@ -173,10 +173,15 @@ bool is_integer) { if (std::isnan(value) || std::isinf(value)) return nullptr; - return new CSSCalcPrimitiveValue(CSSPrimitiveValue::Create(value, type), - is_integer); + return MakeGarbageCollected<CSSCalcPrimitiveValue>( + CSSPrimitiveValue::Create(value, type), is_integer); } + CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool is_integer) + : CSSCalcExpressionNode(UnitCategory(value->TypeWithCalcResolved()), + is_integer), + value_(value) {} + bool IsZero() const override { return !value_->GetDoubleValue(); } String CustomCSSText() const override { return value_->CssText(); } @@ -278,11 +283,6 @@ } private: - CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool is_integer) - : CSSCalcExpressionNode(UnitCategory(value->TypeWithCalcResolved()), - is_integer), - value_(value) {} - Member<CSSPrimitiveValue> value_; }; @@ -375,7 +375,8 @@ if (new_category == kCalcOther) return nullptr; - return new CSSCalcBinaryOperation(left_side, right_side, op, new_category); + return MakeGarbageCollected<CSSCalcBinaryOperation>(left_side, right_side, + op, new_category); } static CSSCalcExpressionNode* CreateSimplified( @@ -462,6 +463,16 @@ return Create(left_side, right_side, op); } + CSSCalcBinaryOperation(CSSCalcExpressionNode* left_side, + CSSCalcExpressionNode* right_side, + CalcOperator op, + CalculationCategory category) + : CSSCalcExpressionNode(category, + IsIntegerResult(left_side, right_side, op)), + left_side_(left_side), + right_side_(right_side), + operator_(op) {} + bool IsZero() const override { return !DoubleValue(); } void AccumulatePixelsAndPercent( @@ -627,16 +638,6 @@ } private: - CSSCalcBinaryOperation(CSSCalcExpressionNode* left_side, - CSSCalcExpressionNode* right_side, - CalcOperator op, - CalculationCategory category) - : CSSCalcExpressionNode(category, - IsIntegerResult(left_side, right_side, op)), - left_side_(left_side), - right_side_(right_side), - operator_(op) {} - static CSSCalcExpressionNode* GetNumberSide( CSSCalcExpressionNode* left_side, CSSCalcExpressionNode* right_side) { @@ -852,12 +853,13 @@ CSSCalcExpressionNodeParser parser; CSSCalcExpressionNode* expression = parser.ParseCalc(tokens); - return expression ? new CSSCalcValue(expression, range) : nullptr; + return expression ? MakeGarbageCollected<CSSCalcValue>(expression, range) + : nullptr; } CSSCalcValue* CSSCalcValue::Create(CSSCalcExpressionNode* expression, ValueRange range) { - return new CSSCalcValue(expression, range); + return MakeGarbageCollected<CSSCalcValue>(expression, range); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_calculation_value.h b/third_party/blink/renderer/core/css/css_calculation_value.h index da67fb8b..609924e 100644 --- a/third_party/blink/renderer/core/css/css_calculation_value.h +++ b/third_party/blink/renderer/core/css/css_calculation_value.h
@@ -120,6 +120,10 @@ static CSSCalcExpressionNode* CreateExpressionNode(double pixels, double percent); + CSSCalcValue(CSSCalcExpressionNode* expression, ValueRange range) + : expression_(expression), + non_negative_(range == kValueRangeNonNegative) {} + scoped_refptr<CalculationValue> ToCalcValue( const CSSToLengthConversionData& conversion_data) const { PixelsAndPercent value(0, 0); @@ -147,10 +151,6 @@ void Trace(blink::Visitor* visitor) { visitor->Trace(expression_); } private: - CSSCalcValue(CSSCalcExpressionNode* expression, ValueRange range) - : expression_(expression), - non_negative_(range == kValueRangeNonNegative) {} - double ClampToPermittedRange(double) const; const Member<CSSCalcExpressionNode> expression_;
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.h b/third_party/blink/renderer/core/css/css_computed_style_declaration.h index 9e9a46a9..bc7cfa4 100644 --- a/third_party/blink/renderer/core/css/css_computed_style_declaration.h +++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.h
@@ -46,11 +46,13 @@ Node* node, bool allow_visited_style = false, const String& pseudo_element_name = String()) { - return new CSSComputedStyleDeclaration(node, allow_visited_style, - pseudo_element_name); + return MakeGarbageCollected<CSSComputedStyleDeclaration>( + node, allow_visited_style, pseudo_element_name); } static const Vector<const CSSProperty*>& ComputableProperties(); + + CSSComputedStyleDeclaration(Node*, bool allow_visited_style, const String&); ~CSSComputedStyleDeclaration() override; String GetPropertyValue(CSSPropertyID) const; @@ -75,8 +77,6 @@ void Trace(blink::Visitor*) override; private: - CSSComputedStyleDeclaration(Node*, bool allow_visited_style, const String&); - // The styled node is either the node passed into getComputedStyle, or the // PseudoElement for :before and :after if they exist. // FIXME: This should be styledElement since in JS getComputedStyle only works
diff --git a/third_party/blink/renderer/core/css/css_custom_ident_value.h b/third_party/blink/renderer/core/css/css_custom_ident_value.h index 86aa17f..12800f70 100644 --- a/third_party/blink/renderer/core/css/css_custom_ident_value.h +++ b/third_party/blink/renderer/core/css/css_custom_ident_value.h
@@ -14,15 +14,18 @@ class CORE_EXPORT CSSCustomIdentValue : public CSSValue { public: static CSSCustomIdentValue* Create(const AtomicString& str) { - return new CSSCustomIdentValue(str); + return MakeGarbageCollected<CSSCustomIdentValue>(str); } // TODO(sashab, timloh): Remove this and lazily parse the CSSPropertyID in // isKnownPropertyID(). static CSSCustomIdentValue* Create(CSSPropertyID id) { - return new CSSCustomIdentValue(id); + return MakeGarbageCollected<CSSCustomIdentValue>(id); } + explicit CSSCustomIdentValue(const AtomicString&); + explicit CSSCustomIdentValue(CSSPropertyID); + AtomicString Value() const { DCHECK(!IsKnownPropertyID()); return string_; @@ -43,9 +46,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - explicit CSSCustomIdentValue(const AtomicString&); - explicit CSSCustomIdentValue(CSSPropertyID); - AtomicString string_; CSSPropertyID property_id_; };
diff --git a/third_party/blink/renderer/core/css/css_custom_property_declaration.h b/third_party/blink/renderer/core/css/css_custom_property_declaration.h index 32d5722c..c81b2d1d 100644 --- a/third_party/blink/renderer/core/css/css_custom_property_declaration.h +++ b/third_party/blink/renderer/core/css/css_custom_property_declaration.h
@@ -17,14 +17,31 @@ static CSSCustomPropertyDeclaration* Create( const AtomicString& name, scoped_refptr<CSSVariableData> value) { - return new CSSCustomPropertyDeclaration(name, std::move(value)); + return MakeGarbageCollected<CSSCustomPropertyDeclaration>(name, + std::move(value)); } static CSSCustomPropertyDeclaration* Create(const AtomicString& name, CSSValueID id) { - return new CSSCustomPropertyDeclaration(name, id); + return MakeGarbageCollected<CSSCustomPropertyDeclaration>(name, id); } + CSSCustomPropertyDeclaration(const AtomicString& name, CSSValueID id) + : CSSValue(kCustomPropertyDeclarationClass), + name_(name), + value_(nullptr), + value_id_(id) { + DCHECK(id == CSSValueInherit || id == CSSValueInitial || + id == CSSValueUnset); + } + + CSSCustomPropertyDeclaration(const AtomicString& name, + scoped_refptr<CSSVariableData> value) + : CSSValue(kCustomPropertyDeclarationClass), + name_(name), + value_(std::move(value)), + value_id_(CSSValueInvalid) {} + const AtomicString& GetName() const { return name_; } CSSVariableData* Value() const { return value_.get(); } @@ -46,22 +63,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSCustomPropertyDeclaration(const AtomicString& name, CSSValueID id) - : CSSValue(kCustomPropertyDeclarationClass), - name_(name), - value_(nullptr), - value_id_(id) { - DCHECK(id == CSSValueInherit || id == CSSValueInitial || - id == CSSValueUnset); - } - - CSSCustomPropertyDeclaration(const AtomicString& name, - scoped_refptr<CSSVariableData> value) - : CSSValue(kCustomPropertyDeclarationClass), - name_(name), - value_(std::move(value)), - value_id_(CSSValueInvalid) {} - const AtomicString name_; scoped_refptr<CSSVariableData> value_; CSSValueID value_id_;
diff --git a/third_party/blink/renderer/core/css/css_font_face_rule.h b/third_party/blink/renderer/core/css/css_font_face_rule.h index 3e37da4..f7412603 100644 --- a/third_party/blink/renderer/core/css/css_font_face_rule.h +++ b/third_party/blink/renderer/core/css/css_font_face_rule.h
@@ -37,9 +37,10 @@ public: static CSSFontFaceRule* Create(StyleRuleFontFace* rule, CSSStyleSheet* sheet) { - return new CSSFontFaceRule(rule, sheet); + return MakeGarbageCollected<CSSFontFaceRule>(rule, sheet); } + CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent); ~CSSFontFaceRule() override; String cssText() const override; @@ -52,8 +53,6 @@ void Trace(blink::Visitor*) override; private: - CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent); - CSSRule::Type type() const override { return kFontFaceRule; } Member<StyleRuleFontFace> font_face_rule_;
diff --git a/third_party/blink/renderer/core/css/css_font_face_src_value.h b/third_party/blink/renderer/core/css/css_font_face_src_value.h index 6b36900..e850ea3 100644 --- a/third_party/blink/renderer/core/css/css_font_face_src_value.h +++ b/third_party/blink/renderer/core/css/css_font_face_src_value.h
@@ -43,18 +43,32 @@ const String& absolute_resource, const Referrer& referrer, ContentSecurityPolicyDisposition should_check_content_security_policy) { - return new CSSFontFaceSrcValue(specified_resource, absolute_resource, - referrer, false, - should_check_content_security_policy); + return MakeGarbageCollected<CSSFontFaceSrcValue>( + specified_resource, absolute_resource, referrer, false, + should_check_content_security_policy); } static CSSFontFaceSrcValue* CreateLocal( const String& absolute_resource, ContentSecurityPolicyDisposition should_check_content_security_policy) { - return new CSSFontFaceSrcValue(g_empty_string, absolute_resource, - Referrer(), true, - should_check_content_security_policy); + return MakeGarbageCollected<CSSFontFaceSrcValue>( + g_empty_string, absolute_resource, Referrer(), true, + should_check_content_security_policy); } + CSSFontFaceSrcValue( + const String& specified_resource, + const String& absolute_resource, + const Referrer& referrer, + bool local, + ContentSecurityPolicyDisposition should_check_content_security_policy) + : CSSValue(kFontFaceSrcClass), + absolute_resource_(absolute_resource), + specified_resource_(specified_resource), + referrer_(referrer), + is_local_(local), + should_check_content_security_policy_( + should_check_content_security_policy) {} + const String& GetResource() const { return absolute_resource_; } const String& Format() const { return format_; } bool IsLocal() const { return is_local_; } @@ -77,20 +91,6 @@ } private: - CSSFontFaceSrcValue( - const String& specified_resource, - const String& absolute_resource, - const Referrer& referrer, - bool local, - ContentSecurityPolicyDisposition should_check_content_security_policy) - : CSSValue(kFontFaceSrcClass), - absolute_resource_(absolute_resource), - specified_resource_(specified_resource), - referrer_(referrer), - is_local_(local), - should_check_content_security_policy_( - should_check_content_security_policy) {} - void RestoreCachedResourceIfNeeded(ExecutionContext*) const; String absolute_resource_; @@ -109,7 +109,12 @@ static FontResourceHelper* Create( FontResource* resource, base::SingleThreadTaskRunner* task_runner) { - return new FontResourceHelper(resource, task_runner); + return MakeGarbageCollected<FontResourceHelper>(resource, task_runner); + } + + FontResourceHelper(FontResource* resource, + base::SingleThreadTaskRunner* task_runner) { + SetResource(resource, task_runner); } void Trace(blink::Visitor* visitor) override { @@ -117,11 +122,6 @@ } private: - FontResourceHelper(FontResource* resource, - base::SingleThreadTaskRunner* task_runner) { - SetResource(resource, task_runner); - } - String DebugName() const override { return "CSSFontFaceSrcValue::FontResourceHelper"; }
diff --git a/third_party/blink/renderer/core/css/css_font_family_value.cc b/third_party/blink/renderer/core/css/css_font_family_value.cc index 9420fbe6..99e4f96 100644 --- a/third_party/blink/renderer/core/css/css_font_family_value.cc +++ b/third_party/blink/renderer/core/css/css_font_family_value.cc
@@ -12,11 +12,13 @@ CSSFontFamilyValue* CSSFontFamilyValue::Create(const String& family_name) { if (family_name.IsNull()) - return new CSSFontFamilyValue(family_name); + return MakeGarbageCollected<CSSFontFamilyValue>(family_name); CSSValuePool::FontFamilyValueCache::AddResult entry = CssValuePool().GetFontFamilyCacheEntry(family_name); - if (!entry.stored_value->value) - entry.stored_value->value = new CSSFontFamilyValue(family_name); + if (!entry.stored_value->value) { + entry.stored_value->value = + MakeGarbageCollected<CSSFontFamilyValue>(family_name); + } return entry.stored_value->value; }
diff --git a/third_party/blink/renderer/core/css/css_font_family_value.h b/third_party/blink/renderer/core/css/css_font_family_value.h index ffe15d4..4ed587d 100644 --- a/third_party/blink/renderer/core/css/css_font_family_value.h +++ b/third_party/blink/renderer/core/css/css_font_family_value.h
@@ -14,6 +14,8 @@ public: static CSSFontFamilyValue* Create(const String& family_name); + CSSFontFamilyValue(const String&); + String Value() const { return string_; } String CustomCSSText() const; @@ -27,8 +29,6 @@ private: friend class CSSValuePool; - CSSFontFamilyValue(const String&); - // TODO(sashab): Change this to an AtomicString. String string_; };
diff --git a/third_party/blink/renderer/core/css/css_font_selector.h b/third_party/blink/renderer/core/css/css_font_selector.h index e15f782a..b39f138 100644 --- a/third_party/blink/renderer/core/css/css_font_selector.h +++ b/third_party/blink/renderer/core/css/css_font_selector.h
@@ -43,8 +43,10 @@ class CORE_EXPORT CSSFontSelector : public FontSelector { public: static CSSFontSelector* Create(Document* document) { - return new CSSFontSelector(document); + return MakeGarbageCollected<CSSFontSelector>(document); } + + explicit CSSFontSelector(Document*); ~CSSFontSelector() override; unsigned Version() const override { return font_face_cache_.Version(); } @@ -81,8 +83,6 @@ void Trace(blink::Visitor*) override; protected: - explicit CSSFontSelector(Document*); - void DispatchInvalidationCallbacks(); private:
diff --git a/third_party/blink/renderer/core/css/css_function_value.h b/third_party/blink/renderer/core/css/css_function_value.h index 14fde898..ffc0cbb 100644 --- a/third_party/blink/renderer/core/css/css_function_value.h +++ b/third_party/blink/renderer/core/css/css_function_value.h
@@ -13,9 +13,12 @@ class CSSFunctionValue : public CSSValueList { public: static CSSFunctionValue* Create(CSSValueID id) { - return new CSSFunctionValue(id); + return MakeGarbageCollected<CSSFunctionValue>(id); } + CSSFunctionValue(CSSValueID id) + : CSSValueList(kFunctionClass, kCommaSeparator), value_id_(id) {} + String CustomCSSText() const; bool Equals(const CSSFunctionValue& other) const { @@ -28,9 +31,6 @@ } private: - CSSFunctionValue(CSSValueID id) - : CSSValueList(kFunctionClass, kCommaSeparator), value_id_(id) {} - const CSSValueID value_id_; };
diff --git a/third_party/blink/renderer/core/css/css_global_rule_set.h b/third_party/blink/renderer/core/css/css_global_rule_set.h index d0f2e16..61d5dc8 100644 --- a/third_party/blink/renderer/core/css/css_global_rule_set.h +++ b/third_party/blink/renderer/core/css/css_global_rule_set.h
@@ -24,7 +24,11 @@ class CSSGlobalRuleSet : public GarbageCollectedFinalized<CSSGlobalRuleSet> { public: - static CSSGlobalRuleSet* Create() { return new CSSGlobalRuleSet(); } + static CSSGlobalRuleSet* Create() { + return MakeGarbageCollected<CSSGlobalRuleSet>(); + } + + CSSGlobalRuleSet() = default; void Dispose(); void InitWatchedSelectorsRuleSet(Document&); @@ -44,7 +48,6 @@ void Trace(blink::Visitor*); private: - CSSGlobalRuleSet() = default; // Constructed from rules in all TreeScopes including UA style and style // injected from extensions. RuleFeatureSet features_;
diff --git a/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h b/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h index ba728b9..bfb629b 100644 --- a/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h +++ b/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h
@@ -26,7 +26,13 @@ class CSSGridAutoRepeatValue : public CSSValueList { public: static CSSGridAutoRepeatValue* Create(CSSValueID id) { - return new CSSGridAutoRepeatValue(id); + return MakeGarbageCollected<CSSGridAutoRepeatValue>(id); + } + + CSSGridAutoRepeatValue(CSSValueID id) + : CSSValueList(kGridAutoRepeatClass, kSpaceSeparator), + auto_repeat_id_(id) { + DCHECK(id == CSSValueAutoFill || id == CSSValueAutoFit); } String CustomCSSText() const; @@ -37,12 +43,6 @@ } private: - CSSGridAutoRepeatValue(CSSValueID id) - : CSSValueList(kGridAutoRepeatClass, kSpaceSeparator), - auto_repeat_id_(id) { - DCHECK(id == CSSValueAutoFill || id == CSSValueAutoFit); - } - const CSSValueID auto_repeat_id_; };
diff --git a/third_party/blink/renderer/core/css/css_grid_line_names_value.h b/third_party/blink/renderer/core/css/css_grid_line_names_value.h index 18cb9c8..dec5c98 100644 --- a/third_party/blink/renderer/core/css/css_grid_line_names_value.h +++ b/third_party/blink/renderer/core/css/css_grid_line_names_value.h
@@ -37,16 +37,17 @@ class CSSGridLineNamesValue : public CSSValueList { public: - static CSSGridLineNamesValue* Create() { return new CSSGridLineNamesValue(); } + static CSSGridLineNamesValue* Create() { + return MakeGarbageCollected<CSSGridLineNamesValue>(); + } + + CSSGridLineNamesValue(); String CustomCSSText() const; void TraceAfterDispatch(blink::Visitor* visitor) { CSSValueList::TraceAfterDispatch(visitor); } - - private: - CSSGridLineNamesValue(); }; DEFINE_CSS_VALUE_TYPE_CASTS(CSSGridLineNamesValue, IsGridLineNamesValue());
diff --git a/third_party/blink/renderer/core/css/css_grid_template_areas_value.h b/third_party/blink/renderer/core/css/css_grid_template_areas_value.h index 027dde5..c2cba1c 100644 --- a/third_party/blink/renderer/core/css/css_grid_template_areas_value.h +++ b/third_party/blink/renderer/core/css/css_grid_template_areas_value.h
@@ -43,9 +43,13 @@ const NamedGridAreaMap& grid_area_map, size_t row_count, size_t column_count) { - return new CSSGridTemplateAreasValue(grid_area_map, row_count, - column_count); + return MakeGarbageCollected<CSSGridTemplateAreasValue>( + grid_area_map, row_count, column_count); } + + CSSGridTemplateAreasValue(const NamedGridAreaMap&, + size_t row_count, + size_t column_count); ~CSSGridTemplateAreasValue() = default; String CustomCSSText() const; @@ -61,10 +65,6 @@ } private: - CSSGridTemplateAreasValue(const NamedGridAreaMap&, - size_t row_count, - size_t column_count); - NamedGridAreaMap grid_area_map_; size_t row_count_; size_t column_count_;
diff --git a/third_party/blink/renderer/core/css/css_identifier_value.cc b/third_party/blink/renderer/core/css/css_identifier_value.cc index aa4a8e8..63f0c70 100644 --- a/third_party/blink/renderer/core/css/css_identifier_value.cc +++ b/third_party/blink/renderer/core/css/css_identifier_value.cc
@@ -16,7 +16,7 @@ CSSIdentifierValue* css_value = CssValuePool().IdentifierCacheValue(value_id); if (!css_value) { css_value = CssValuePool().SetIdentifierCacheValue( - value_id, new CSSIdentifierValue(value_id)); + value_id, MakeGarbageCollected<CSSIdentifierValue>(value_id)); } return css_value; }
diff --git a/third_party/blink/renderer/core/css/css_identifier_value.h b/third_party/blink/renderer/core/css/css_identifier_value.h index 8829909..3ca9441b 100644 --- a/third_party/blink/renderer/core/css/css_identifier_value.h +++ b/third_party/blink/renderer/core/css/css_identifier_value.h
@@ -26,13 +26,24 @@ static_assert(!std::is_same<T, CSSValueID>::value, "Do not call create() with a CSSValueID; call " "createIdentifier() instead"); - return new CSSIdentifierValue(value); + return MakeGarbageCollected<CSSIdentifierValue>(value); } static CSSIdentifierValue* Create(const Length& value) { - return new CSSIdentifierValue(value); + return MakeGarbageCollected<CSSIdentifierValue>(value); } + explicit CSSIdentifierValue(CSSValueID); + + // TODO(sashab): Remove this function, and update mapping methods to + // specialize the create() method instead. + template <typename T> + CSSIdentifierValue( + T t) // Overriden for special cases in CSSPrimitiveValueMappings.h + : CSSValue(kIdentifierClass), value_id_(PlatformEnumToCSSValueID(t)) {} + + CSSIdentifierValue(const Length&); + CSSValueID GetValueID() const { return value_id_; } String CustomCSSText() const; @@ -50,17 +61,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - explicit CSSIdentifierValue(CSSValueID); - - // TODO(sashab): Remove this function, and update mapping methods to - // specialize the create() method instead. - template <typename T> - CSSIdentifierValue( - T t) // Overriden for special cases in CSSPrimitiveValueMappings.h - : CSSValue(kIdentifierClass), value_id_(PlatformEnumToCSSValueID(t)) {} - - CSSIdentifierValue(const Length&); - CSSValueID value_id_; };
diff --git a/third_party/blink/renderer/core/css/css_image_set_value.h b/third_party/blink/renderer/core/css/css_image_set_value.h index 2841c73..43b9db23 100644 --- a/third_party/blink/renderer/core/css/css_image_set_value.h +++ b/third_party/blink/renderer/core/css/css_image_set_value.h
@@ -41,8 +41,10 @@ class CSSImageSetValue : public CSSValueList { public: static CSSImageSetValue* Create(CSSParserMode parser_mode) { - return new CSSImageSetValue(parser_mode); + return MakeGarbageCollected<CSSImageSetValue>(parser_mode); } + + explicit CSSImageSetValue(CSSParserMode); ~CSSImageSetValue(); bool IsCachePending(float device_scale_factor) const; @@ -72,8 +74,6 @@ ImageWithScale BestImageForScaleFactor(float scale_factor); private: - explicit CSSImageSetValue(CSSParserMode); - void FillImageSet(); static inline bool CompareByScaleFactor(ImageWithScale first, ImageWithScale second) {
diff --git a/third_party/blink/renderer/core/css/css_image_value.h b/third_party/blink/renderer/core/css/css_image_value.h index 6124f79..ec7e0cfe 100644 --- a/third_party/blink/renderer/core/css/css_image_value.h +++ b/third_party/blink/renderer/core/css/css_image_value.h
@@ -55,11 +55,17 @@ const KURL& url, const Referrer& referrer, StyleImage* image = nullptr) { - return new CSSImageValue(raw_value, url, referrer, image); + return MakeGarbageCollected<CSSImageValue>(raw_value, url, referrer, image); } static CSSImageValue* Create(const AtomicString& absolute_url) { - return new CSSImageValue(absolute_url); + return MakeGarbageCollected<CSSImageValue>(absolute_url); } + + CSSImageValue(const AtomicString& raw_value, + const KURL&, + const Referrer&, + StyleImage*); + CSSImageValue(const AtomicString& absolute_url); ~CSSImageValue(); bool IsCachePending() const { return !cached_image_; } @@ -101,12 +107,6 @@ void RestoreCachedResourceIfNeeded(const Document&) const; private: - CSSImageValue(const AtomicString& raw_value, - const KURL&, - const Referrer&, - StyleImage*); - CSSImageValue(const AtomicString& absolute_url); - AtomicString relative_url_; Referrer referrer_; AtomicString initiator_name_;
diff --git a/third_party/blink/renderer/core/css/css_import_rule.h b/third_party/blink/renderer/core/css/css_import_rule.h index 546eb5d..d9be4fdc 100644 --- a/third_party/blink/renderer/core/css/css_import_rule.h +++ b/third_party/blink/renderer/core/css/css_import_rule.h
@@ -35,9 +35,10 @@ public: static CSSImportRule* Create(StyleRuleImport* rule, CSSStyleSheet* sheet) { - return new CSSImportRule(rule, sheet); + return MakeGarbageCollected<CSSImportRule>(rule, sheet); } + CSSImportRule(StyleRuleImport*, CSSStyleSheet*); ~CSSImportRule() override; String cssText() const override; @@ -50,8 +51,6 @@ void Trace(blink::Visitor*) override; private: - CSSImportRule(StyleRuleImport*, CSSStyleSheet*); - CSSRule::Type type() const override { return kImportRule; } Member<StyleRuleImport> import_rule_;
diff --git a/third_party/blink/renderer/core/css/css_initial_value.h b/third_party/blink/renderer/core/css/css_initial_value.h index 77a65cb..7cbecaf 100644 --- a/third_party/blink/renderer/core/css/css_initial_value.h +++ b/third_party/blink/renderer/core/css/css_initial_value.h
@@ -31,6 +31,8 @@ public: static CSSInitialValue* Create(); + CSSInitialValue() : CSSValue(kInitialClass) {} + String CustomCSSText() const; bool Equals(const CSSInitialValue&) const { return true; } @@ -41,8 +43,6 @@ private: friend class CSSValuePool; - - CSSInitialValue() : CSSValue(kInitialClass) {} }; DEFINE_CSS_VALUE_TYPE_CASTS(CSSInitialValue, IsInitialValue());
diff --git a/third_party/blink/renderer/core/css/css_keyframe_rule.h b/third_party/blink/renderer/core/css/css_keyframe_rule.h index e4172f5..df8f03f 100644 --- a/third_party/blink/renderer/core/css/css_keyframe_rule.h +++ b/third_party/blink/renderer/core/css/css_keyframe_rule.h
@@ -40,6 +40,7 @@ DEFINE_WRAPPERTYPEINFO(); public: + CSSKeyframeRule(StyleRuleKeyframe*, CSSKeyframesRule* parent); ~CSSKeyframeRule() override; String cssText() const override { return keyframe_->CssText(); } @@ -53,8 +54,6 @@ void Trace(blink::Visitor*) override; private: - CSSKeyframeRule(StyleRuleKeyframe*, CSSKeyframesRule* parent); - CSSRule::Type type() const override { return kKeyframeRule; } Member<StyleRuleKeyframe> keyframe_;
diff --git a/third_party/blink/renderer/core/css/css_keyframes_rule.cc b/third_party/blink/renderer/core/css/css_keyframes_rule.cc index 4a7b8e2e..93650f7 100644 --- a/third_party/blink/renderer/core/css/css_keyframes_rule.cc +++ b/third_party/blink/renderer/core/css/css_keyframes_rule.cc
@@ -162,9 +162,11 @@ DCHECK_EQ(child_rule_cssom_wrappers_.size(), keyframes_rule_->Keyframes().size()); Member<CSSKeyframeRule>& rule = child_rule_cssom_wrappers_[index]; - if (!rule) - rule = new CSSKeyframeRule(keyframes_rule_->Keyframes()[index].Get(), - const_cast<CSSKeyframesRule*>(this)); + if (!rule) { + rule = MakeGarbageCollected<CSSKeyframeRule>( + keyframes_rule_->Keyframes()[index].Get(), + const_cast<CSSKeyframesRule*>(this)); + } return rule.Get(); }
diff --git a/third_party/blink/renderer/core/css/css_keyframes_rule.h b/third_party/blink/renderer/core/css/css_keyframes_rule.h index 032d1ce..e9db417 100644 --- a/third_party/blink/renderer/core/css/css_keyframes_rule.h +++ b/third_party/blink/renderer/core/css/css_keyframes_rule.h
@@ -39,8 +39,12 @@ class StyleRuleKeyframes final : public StyleRuleBase { public: - static StyleRuleKeyframes* Create() { return new StyleRuleKeyframes(); } + static StyleRuleKeyframes* Create() { + return MakeGarbageCollected<StyleRuleKeyframes>(); + } + StyleRuleKeyframes(); + explicit StyleRuleKeyframes(const StyleRuleKeyframes&); ~StyleRuleKeyframes(); const HeapVector<Member<StyleRuleKeyframe>>& Keyframes() const { @@ -59,7 +63,9 @@ int FindKeyframeIndex(const String& key) const; - StyleRuleKeyframes* Copy() const { return new StyleRuleKeyframes(*this); } + StyleRuleKeyframes* Copy() const { + return MakeGarbageCollected<StyleRuleKeyframes>(*this); + } void TraceAfterDispatch(blink::Visitor*); @@ -67,9 +73,6 @@ unsigned Version() const { return version_; } private: - StyleRuleKeyframes(); - explicit StyleRuleKeyframes(const StyleRuleKeyframes&); - HeapVector<Member<StyleRuleKeyframe>> keyframes_; AtomicString name_; unsigned version_ : 31; @@ -84,9 +87,10 @@ public: static CSSKeyframesRule* Create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet) { - return new CSSKeyframesRule(rule, sheet); + return MakeGarbageCollected<CSSKeyframesRule>(rule, sheet); } + CSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent); ~CSSKeyframesRule() override; StyleRuleKeyframes* Keyframes() { return keyframes_rule_.Get(); } @@ -116,8 +120,6 @@ void Trace(blink::Visitor*) override; private: - CSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent); - CSSRule::Type type() const override { return kKeyframesRule; } Member<StyleRuleKeyframes> keyframes_rule_;
diff --git a/third_party/blink/renderer/core/css/css_media_rule.h b/third_party/blink/renderer/core/css/css_media_rule.h index fb6b752..1991686 100644 --- a/third_party/blink/renderer/core/css/css_media_rule.h +++ b/third_party/blink/renderer/core/css/css_media_rule.h
@@ -35,9 +35,10 @@ public: static CSSMediaRule* Create(StyleRuleMedia* rule, CSSStyleSheet* sheet) { - return new CSSMediaRule(rule, sheet); + return MakeGarbageCollected<CSSMediaRule>(rule, sheet); } + CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*); ~CSSMediaRule() override; void Reattach(StyleRuleBase*) override; @@ -49,8 +50,6 @@ void Trace(blink::Visitor*) override; private: - CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*); - CSSRule::Type type() const override { return kMediaRule; } scoped_refptr<MediaQuerySet> MediaQueries() const;
diff --git a/third_party/blink/renderer/core/css/css_namespace_rule.h b/third_party/blink/renderer/core/css/css_namespace_rule.h index ad2f2f2..448891b 100644 --- a/third_party/blink/renderer/core/css/css_namespace_rule.h +++ b/third_party/blink/renderer/core/css/css_namespace_rule.h
@@ -17,9 +17,10 @@ public: static CSSNamespaceRule* Create(StyleRuleNamespace* rule, CSSStyleSheet* sheet) { - return new CSSNamespaceRule(rule, sheet); + return MakeGarbageCollected<CSSNamespaceRule>(rule, sheet); } + CSSNamespaceRule(StyleRuleNamespace*, CSSStyleSheet*); ~CSSNamespaceRule() override; String cssText() const override; @@ -31,8 +32,6 @@ void Trace(blink::Visitor*) override; private: - CSSNamespaceRule(StyleRuleNamespace*, CSSStyleSheet*); - CSSRule::Type type() const override { return kNamespaceRule; } Member<StyleRuleNamespace> namespace_rule_;
diff --git a/third_party/blink/renderer/core/css/css_page_rule.h b/third_party/blink/renderer/core/css/css_page_rule.h index 9e839663..c5f756c 100644 --- a/third_party/blink/renderer/core/css/css_page_rule.h +++ b/third_party/blink/renderer/core/css/css_page_rule.h
@@ -38,9 +38,10 @@ public: static CSSPageRule* Create(StyleRulePage* rule, CSSStyleSheet* sheet) { - return new CSSPageRule(rule, sheet); + return MakeGarbageCollected<CSSPageRule>(rule, sheet); } + CSSPageRule(StyleRulePage*, CSSStyleSheet*); ~CSSPageRule() override; String cssText() const override; @@ -54,8 +55,6 @@ void Trace(blink::Visitor*) override; private: - CSSPageRule(StyleRulePage*, CSSStyleSheet*); - CSSRule::Type type() const override { return kPageRule; } Member<StyleRulePage> page_rule_;
diff --git a/third_party/blink/renderer/core/css/css_paint_value.cc b/third_party/blink/renderer/core/css/css_paint_value.cc index 57f3a3d..0069f562 100644 --- a/third_party/blink/renderer/core/css/css_paint_value.cc +++ b/third_party/blink/renderer/core/css/css_paint_value.cc
@@ -16,7 +16,7 @@ CSSPaintValue::CSSPaintValue(CSSCustomIdentValue* name) : CSSImageGeneratorValue(kPaintClass), name_(name), - paint_image_generator_observer_(new Observer(this)) {} + paint_image_generator_observer_(MakeGarbageCollected<Observer>(this)) {} CSSPaintValue::CSSPaintValue( CSSCustomIdentValue* name,
diff --git a/third_party/blink/renderer/core/css/css_paint_value.h b/third_party/blink/renderer/core/css/css_paint_value.h index fc879596..32953d1 100644 --- a/third_party/blink/renderer/core/css/css_paint_value.h +++ b/third_party/blink/renderer/core/css/css_paint_value.h
@@ -18,15 +18,18 @@ class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue { public: static CSSPaintValue* Create(CSSCustomIdentValue* name) { - return new CSSPaintValue(name); + return MakeGarbageCollected<CSSPaintValue>(name); } static CSSPaintValue* Create( CSSCustomIdentValue* name, Vector<scoped_refptr<CSSVariableData>>& variable_data) { - return new CSSPaintValue(name, variable_data); + return MakeGarbageCollected<CSSPaintValue>(name, variable_data); } + explicit CSSPaintValue(CSSCustomIdentValue* name); + CSSPaintValue(CSSCustomIdentValue* name, + Vector<scoped_refptr<CSSVariableData>>&); ~CSSPaintValue(); String CustomCSSText() const; @@ -59,11 +62,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - explicit CSSPaintValue(CSSCustomIdentValue* name); - - CSSPaintValue(CSSCustomIdentValue* name, - Vector<scoped_refptr<CSSVariableData>>&); - class Observer final : public CSSPaintImageGenerator::Observer { public: explicit Observer(CSSPaintValue* owner_value) : owner_value_(owner_value) {}
diff --git a/third_party/blink/renderer/core/css/css_pending_substitution_value.h b/third_party/blink/renderer/core/css/css_pending_substitution_value.h index 4c847157..c26dcb6 100644 --- a/third_party/blink/renderer/core/css/css_pending_substitution_value.h +++ b/third_party/blink/renderer/core/css/css_pending_substitution_value.h
@@ -16,10 +16,16 @@ static CSSPendingSubstitutionValue* Create( CSSPropertyID shorthand_property_id, CSSVariableReferenceValue* shorthand_value) { - return new CSSPendingSubstitutionValue(shorthand_property_id, - shorthand_value); + return MakeGarbageCollected<CSSPendingSubstitutionValue>( + shorthand_property_id, shorthand_value); } + CSSPendingSubstitutionValue(CSSPropertyID shorthand_property_id, + CSSVariableReferenceValue* shorthand_value) + : CSSValue(kPendingSubstitutionValueClass), + shorthand_property_id_(shorthand_property_id), + shorthand_value_(shorthand_value) {} + CSSVariableReferenceValue* ShorthandValue() const { return shorthand_value_.Get(); } @@ -34,12 +40,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSPendingSubstitutionValue(CSSPropertyID shorthand_property_id, - CSSVariableReferenceValue* shorthand_value) - : CSSValue(kPendingSubstitutionValueClass), - shorthand_property_id_(shorthand_property_id), - shorthand_value_(shorthand_value) {} - CSSPropertyID shorthand_property_id_; Member<CSSVariableReferenceValue> shorthand_value_; };
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.cc b/third_party/blink/renderer/core/css/css_primitive_value.cc index 3b39794..11e9d16 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.cc +++ b/third_party/blink/renderer/core/css/css_primitive_value.cc
@@ -95,37 +95,39 @@ value = 0; if (value < 0 || value > CSSValuePool::kMaximumCacheableIntegerValue) - return new CSSPrimitiveValue(value, type); + return MakeGarbageCollected<CSSPrimitiveValue>(value, type); int int_value = clampTo<int>(value); if (value != int_value) - return new CSSPrimitiveValue(value, type); + return MakeGarbageCollected<CSSPrimitiveValue>(value, type); CSSValuePool& pool = CssValuePool(); CSSPrimitiveValue* result = nullptr; switch (type) { case CSSPrimitiveValue::UnitType::kPixels: result = pool.PixelCacheValue(int_value); - if (!result) - result = pool.SetPixelCacheValue(int_value, - new CSSPrimitiveValue(value, type)); + if (!result) { + result = pool.SetPixelCacheValue( + int_value, MakeGarbageCollected<CSSPrimitiveValue>(value, type)); + } return result; case CSSPrimitiveValue::UnitType::kPercentage: result = pool.PercentCacheValue(int_value); - if (!result) - result = pool.SetPercentCacheValue(int_value, - new CSSPrimitiveValue(value, type)); + if (!result) { + result = pool.SetPercentCacheValue( + int_value, MakeGarbageCollected<CSSPrimitiveValue>(value, type)); + } return result; case CSSPrimitiveValue::UnitType::kNumber: case CSSPrimitiveValue::UnitType::kInteger: result = pool.NumberCacheValue(int_value); if (!result) result = pool.SetNumberCacheValue( - int_value, new CSSPrimitiveValue( + int_value, MakeGarbageCollected<CSSPrimitiveValue>( value, CSSPrimitiveValue::UnitType::kInteger)); return result; default: - return new CSSPrimitiveValue(value, type); + return MakeGarbageCollected<CSSPrimitiveValue>(value, type); } }
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.h b/third_party/blink/renderer/core/css/css_primitive_value.h index 0b60e4c..467bbb18 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.h +++ b/third_party/blink/renderer/core/css/css_primitive_value.h
@@ -220,15 +220,23 @@ static CSSPrimitiveValue* Create(double value, UnitType); static CSSPrimitiveValue* Create(const Length& value, float zoom) { - return new CSSPrimitiveValue(value, zoom); + return MakeGarbageCollected<CSSPrimitiveValue>(value, zoom); } // TODO(sashab): Remove this. template <typename T> static CSSPrimitiveValue* Create(T value) { - return new CSSPrimitiveValue(value); + return MakeGarbageCollected<CSSPrimitiveValue>(value); } + CSSPrimitiveValue(const Length&, float zoom); + CSSPrimitiveValue(double, UnitType); + template <typename T> + CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h + template <typename T> + CSSPrimitiveValue(T* val) : CSSValue(kPrimitiveClass) { + Init(val); + } ~CSSPrimitiveValue(); UnitType TypeWithCalcResolved() const; @@ -282,17 +290,6 @@ static UnitType LengthUnitTypeToUnitType(LengthUnitType); private: - CSSPrimitiveValue(const Length&, float zoom); - CSSPrimitiveValue(double, UnitType); - - template <typename T> - CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h - - template <typename T> - CSSPrimitiveValue(T* val) : CSSValue(kPrimitiveClass) { - Init(val); - } - static void Create(int); // compile-time guard static void Create(unsigned); // compile-time guard template <typename T>
diff --git a/third_party/blink/renderer/core/css/css_quad_value.h b/third_party/blink/renderer/core/css/css_quad_value.h index dffd941..dc6718c 100644 --- a/third_party/blink/renderer/core/css/css_quad_value.h +++ b/third_party/blink/renderer/core/css/css_quad_value.h
@@ -36,9 +36,22 @@ CSSValue* bottom, CSSValue* left, TypeForSerialization serialization_type) { - return new CSSQuadValue(top, right, bottom, left, serialization_type); + return MakeGarbageCollected<CSSQuadValue>(top, right, bottom, left, + serialization_type); } + CSSQuadValue(CSSValue* top, + CSSValue* right, + CSSValue* bottom, + CSSValue* left, + TypeForSerialization serialization_type) + : CSSValue(kQuadClass), + serialization_type_(serialization_type), + top_(top), + right_(right), + bottom_(bottom), + left_(left) {} + CSSValue* Top() const { return top_.Get(); } CSSValue* Right() const { return right_.Get(); } CSSValue* Bottom() const { return bottom_.Get(); } @@ -57,19 +70,6 @@ void TraceAfterDispatch(blink::Visitor*); - protected: - CSSQuadValue(CSSValue* top, - CSSValue* right, - CSSValue* bottom, - CSSValue* left, - TypeForSerialization serialization_type) - : CSSValue(kQuadClass), - serialization_type_(serialization_type), - top_(top), - right_(right), - bottom_(bottom), - left_(left) {} - private: TypeForSerialization serialization_type_; Member<CSSValue> top_;
diff --git a/third_party/blink/renderer/core/css/css_segmented_font_face.h b/third_party/blink/renderer/core/css/css_segmented_font_face.h index f521100..ff69a70 100644 --- a/third_party/blink/renderer/core/css/css_segmented_font_face.h +++ b/third_party/blink/renderer/core/css/css_segmented_font_face.h
@@ -47,8 +47,11 @@ public: static CSSSegmentedFontFace* Create( FontSelectionCapabilities font_selection_capabilities) { - return new CSSSegmentedFontFace(font_selection_capabilities); + return MakeGarbageCollected<CSSSegmentedFontFace>( + font_selection_capabilities); } + + CSSSegmentedFontFace(FontSelectionCapabilities); ~CSSSegmentedFontFace(); FontSelectionCapabilities GetFontSelectionCapabilities() const { @@ -76,8 +79,6 @@ void Trace(blink::Visitor*); private: - CSSSegmentedFontFace(FontSelectionCapabilities); - void PruneTable(); bool IsValid() const;
diff --git a/third_party/blink/renderer/core/css/css_selector_watch.cc b/third_party/blink/renderer/core/css/css_selector_watch.cc index cb416216e..0c6ad72 100644 --- a/third_party/blink/renderer/core/css/css_selector_watch.cc +++ b/third_party/blink/renderer/core/css/css_selector_watch.cc
@@ -55,7 +55,7 @@ CSSSelectorWatch& CSSSelectorWatch::From(Document& document) { CSSSelectorWatch* watch = FromIfExists(document); if (!watch) { - watch = new CSSSelectorWatch(document); + watch = MakeGarbageCollected<CSSSelectorWatch>(document); ProvideTo(document, watch); } return *watch;
diff --git a/third_party/blink/renderer/core/css/css_selector_watch.h b/third_party/blink/renderer/core/css/css_selector_watch.h index fcc7e95..1f8f1677 100644 --- a/third_party/blink/renderer/core/css/css_selector_watch.h +++ b/third_party/blink/renderer/core/css/css_selector_watch.h
@@ -50,6 +50,7 @@ public: static const char kSupplementName[]; + explicit CSSSelectorWatch(Document&); virtual ~CSSSelectorWatch() = default; static CSSSelectorWatch& From(Document&); @@ -66,7 +67,6 @@ void Trace(blink::Visitor*) override; private: - explicit CSSSelectorWatch(Document&); void CallbackSelectorChangeTimerFired(TimerBase*); HeapVector<Member<StyleRule>> watched_callback_selectors_;
diff --git a/third_party/blink/renderer/core/css/css_shadow_value.h b/third_party/blink/renderer/core/css/css_shadow_value.h index d42c673..0783d72 100644 --- a/third_party/blink/renderer/core/css/css_shadow_value.h +++ b/third_party/blink/renderer/core/css/css_shadow_value.h
@@ -39,9 +39,17 @@ CSSPrimitiveValue* spread, CSSIdentifierValue* style, CSSValue* color) { - return new CSSShadowValue(x, y, blur, spread, style, color); + return MakeGarbageCollected<CSSShadowValue>(x, y, blur, spread, style, + color); } + CSSShadowValue(CSSPrimitiveValue* x, + CSSPrimitiveValue* y, + CSSPrimitiveValue* blur, + CSSPrimitiveValue* spread, + CSSIdentifierValue* style, + CSSValue* color); + String CustomCSSText() const; bool Equals(const CSSShadowValue&) const; @@ -54,14 +62,6 @@ Member<CSSValue> color; void TraceAfterDispatch(blink::Visitor*); - - private: - CSSShadowValue(CSSPrimitiveValue* x, - CSSPrimitiveValue* y, - CSSPrimitiveValue* blur, - CSSPrimitiveValue* spread, - CSSIdentifierValue* style, - CSSValue* color); }; DEFINE_CSS_VALUE_TYPE_CASTS(CSSShadowValue, IsShadowValue());
diff --git a/third_party/blink/renderer/core/css/css_string_value.h b/third_party/blink/renderer/core/css/css_string_value.h index c5ef637..6c0ed697 100644 --- a/third_party/blink/renderer/core/css/css_string_value.h +++ b/third_party/blink/renderer/core/css/css_string_value.h
@@ -13,9 +13,11 @@ class CSSStringValue : public CSSValue { public: static CSSStringValue* Create(const String& str) { - return new CSSStringValue(str); + return MakeGarbageCollected<CSSStringValue>(str); } + CSSStringValue(const String&); + String Value() const { return string_; } String CustomCSSText() const; @@ -27,8 +29,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSStringValue(const String&); - String string_; };
diff --git a/third_party/blink/renderer/core/css/css_style_rule.h b/third_party/blink/renderer/core/css/css_style_rule.h index c8e8a3e..bde00b9 100644 --- a/third_party/blink/renderer/core/css/css_style_rule.h +++ b/third_party/blink/renderer/core/css/css_style_rule.h
@@ -38,9 +38,10 @@ public: static CSSStyleRule* Create(StyleRule* rule, CSSStyleSheet* sheet) { - return new CSSStyleRule(rule, sheet); + return MakeGarbageCollected<CSSStyleRule>(rule, sheet); } + CSSStyleRule(StyleRule*, CSSStyleSheet*); ~CSSStyleRule() override; String cssText() const override; @@ -59,8 +60,6 @@ void Trace(blink::Visitor*) override; private: - CSSStyleRule(StyleRule*, CSSStyleSheet*); - CSSRule::Type type() const override { return kStyleRule; } Member<StyleRule> style_rule_;
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc index 507d9ebf..eba4085 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet.cc +++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -52,17 +52,17 @@ class StyleSheetCSSRuleList final : public CSSRuleList { public: static StyleSheetCSSRuleList* Create(CSSStyleSheet* sheet) { - return new StyleSheetCSSRuleList(sheet); + return MakeGarbageCollected<StyleSheetCSSRuleList>(sheet); } + StyleSheetCSSRuleList(CSSStyleSheet* sheet) : style_sheet_(sheet) {} + void Trace(blink::Visitor* visitor) override { visitor->Trace(style_sheet_); CSSRuleList::Trace(visitor); } private: - StyleSheetCSSRuleList(CSSStyleSheet* sheet) : style_sheet_(sheet) {} - unsigned length() const override { return style_sheet_->length(); } CSSRule* item(unsigned index) const override { return style_sheet_->item(index); @@ -103,7 +103,7 @@ // https://wicg.github.io/construct-stylesheets/#dom-cssstylesheet-cssstylesheet CSSParserContext* parser_context = CSSParserContext::Create(document); StyleSheetContents* contents = StyleSheetContents::Create(parser_context); - CSSStyleSheet* sheet = new CSSStyleSheet(contents, nullptr); + CSSStyleSheet* sheet = MakeGarbageCollected<CSSStyleSheet>(contents, nullptr); sheet->SetTitle(options->title()); sheet->ClearOwnerNode(); sheet->ClearOwnerRule(); @@ -124,20 +124,21 @@ CSSStyleSheet* CSSStyleSheet::Create(StyleSheetContents* sheet, CSSImportRule* owner_rule) { - return new CSSStyleSheet(sheet, owner_rule); + return MakeGarbageCollected<CSSStyleSheet>(sheet, owner_rule); } CSSStyleSheet* CSSStyleSheet::Create(StyleSheetContents* sheet, Node& owner_node) { - return new CSSStyleSheet(sheet, owner_node, false, - TextPosition::MinimumPosition()); + return MakeGarbageCollected<CSSStyleSheet>(sheet, owner_node, false, + TextPosition::MinimumPosition()); } CSSStyleSheet* CSSStyleSheet::CreateInline(StyleSheetContents* sheet, Node& owner_node, const TextPosition& start_position) { DCHECK(sheet); - return new CSSStyleSheet(sheet, owner_node, true, start_position); + return MakeGarbageCollected<CSSStyleSheet>(sheet, owner_node, true, + start_position); } CSSStyleSheet* CSSStyleSheet::CreateInline(Node& owner_node, @@ -150,7 +151,8 @@ owner_node.GetDocument().GetReferrerPolicy(), encoding); StyleSheetContents* sheet = StyleSheetContents::Create(base_url.GetString(), parser_context); - return new CSSStyleSheet(sheet, owner_node, true, start_position); + return MakeGarbageCollected<CSSStyleSheet>(sheet, owner_node, true, + start_position); } CSSStyleSheet::CSSStyleSheet(StyleSheetContents* contents,
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.h b/third_party/blink/renderer/core/css/css_style_sheet.h index 2e733e0..51d77f9 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet.h +++ b/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -70,6 +70,11 @@ Node& owner_node, const TextPosition& start_position = TextPosition::MinimumPosition()); + CSSStyleSheet(StyleSheetContents*, CSSImportRule* owner_rule); + CSSStyleSheet(StyleSheetContents*, + Node& owner_node, + bool is_inline_stylesheet, + const TextPosition& start_position); ~CSSStyleSheet() override; CSSStyleSheet* parentStyleSheet() const override; @@ -193,12 +198,6 @@ void Trace(blink::Visitor*) override; private: - CSSStyleSheet(StyleSheetContents*, CSSImportRule* owner_rule); - CSSStyleSheet(StyleSheetContents*, - Node& owner_node, - bool is_inline_stylesheet, - const TextPosition& start_position); - bool IsCSSStyleSheet() const override { return true; } String type() const override { return "text/css"; }
diff --git a/third_party/blink/renderer/core/css/css_style_sheet_test.cc b/third_party/blink/renderer/core/css/css_style_sheet_test.cc index 7acc898..3cdf716 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet_test.cc +++ b/third_party/blink/renderer/core/css/css_style_sheet_test.cc
@@ -28,14 +28,15 @@ public: static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, ScriptValue* output) { - FunctionForTest* self = new FunctionForTest(script_state, output); + FunctionForTest* self = + MakeGarbageCollected<FunctionForTest>(script_state, output); return self->BindToV8Function(); } - private: FunctionForTest(ScriptState* script_state, ScriptValue* output) : ScriptFunction(script_state), output_(output) {} + private: ScriptValue Call(ScriptValue value) override { DCHECK(!value.IsEmpty()); *output_ = value;
diff --git a/third_party/blink/renderer/core/css/css_supports_rule.h b/third_party/blink/renderer/core/css/css_supports_rule.h index 75088cf..2ff67c34 100644 --- a/third_party/blink/renderer/core/css/css_supports_rule.h +++ b/third_party/blink/renderer/core/css/css_supports_rule.h
@@ -41,16 +41,15 @@ public: static CSSSupportsRule* Create(StyleRuleSupports* rule, CSSStyleSheet* sheet) { - return new CSSSupportsRule(rule, sheet); + return MakeGarbageCollected<CSSSupportsRule>(rule, sheet); } + CSSSupportsRule(StyleRuleSupports*, CSSStyleSheet*); ~CSSSupportsRule() override = default; String cssText() const override; private: - CSSSupportsRule(StyleRuleSupports*, CSSStyleSheet*); - CSSRule::Type type() const override { return kSupportsRule; } };
diff --git a/third_party/blink/renderer/core/css/css_unicode_range_value.h b/third_party/blink/renderer/core/css/css_unicode_range_value.h index 7562110..7057845 100644 --- a/third_party/blink/renderer/core/css/css_unicode_range_value.h +++ b/third_party/blink/renderer/core/css/css_unicode_range_value.h
@@ -34,9 +34,12 @@ class CSSUnicodeRangeValue : public CSSValue { public: static CSSUnicodeRangeValue* Create(UChar32 from, UChar32 to) { - return new CSSUnicodeRangeValue(from, to); + return MakeGarbageCollected<CSSUnicodeRangeValue>(from, to); } + CSSUnicodeRangeValue(UChar32 from, UChar32 to) + : CSSValue(kUnicodeRangeClass), from_(from), to_(to) {} + UChar32 From() const { return from_; } UChar32 To() const { return to_; } @@ -49,9 +52,6 @@ } private: - CSSUnicodeRangeValue(UChar32 from, UChar32 to) - : CSSValue(kUnicodeRangeClass), from_(from), to_(to) {} - UChar32 from_; UChar32 to_; };
diff --git a/third_party/blink/renderer/core/css/css_uri_value.h b/third_party/blink/renderer/core/css/css_uri_value.h index 57b4519..2f0ea52 100644 --- a/third_party/blink/renderer/core/css/css_uri_value.h +++ b/third_party/blink/renderer/core/css/css_uri_value.h
@@ -17,11 +17,15 @@ class CSSURIValue : public CSSValue { public: static CSSURIValue* Create(const String& relative_url, const KURL& url) { - return new CSSURIValue(AtomicString(relative_url), url); + return MakeGarbageCollected<CSSURIValue>(AtomicString(relative_url), url); } static CSSURIValue* Create(const AtomicString& absolute_url) { - return new CSSURIValue(absolute_url, absolute_url); + return MakeGarbageCollected<CSSURIValue>(absolute_url, absolute_url); } + + CSSURIValue(const AtomicString&, const KURL&); + CSSURIValue(const AtomicString& relative_url, + const AtomicString& absolute_url); ~CSSURIValue(); SVGResource* EnsureResourceReference() const; @@ -41,10 +45,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSURIValue(const AtomicString&, const KURL&); - CSSURIValue(const AtomicString& relative_url, - const AtomicString& absolute_url); - KURL AbsoluteUrl() const; AtomicString relative_url_;
diff --git a/third_party/blink/renderer/core/css/css_value_list.h b/third_party/blink/renderer/core/css/css_value_list.h index 085c2021..090786ff 100644 --- a/third_party/blink/renderer/core/css/css_value_list.h +++ b/third_party/blink/renderer/core/css/css_value_list.h
@@ -36,19 +36,22 @@ using const_iterator = HeapVector<Member<const CSSValue>, 4>::const_iterator; static CSSValueList* CreateCommaSeparated() { - return new CSSValueList(kCommaSeparator); + return MakeGarbageCollected<CSSValueList>(kCommaSeparator); } static CSSValueList* CreateSpaceSeparated() { - return new CSSValueList(kSpaceSeparator); + return MakeGarbageCollected<CSSValueList>(kSpaceSeparator); } static CSSValueList* CreateSlashSeparated() { - return new CSSValueList(kSlashSeparator); + return MakeGarbageCollected<CSSValueList>(kSlashSeparator); } static CSSValueList* CreateWithSeparatorFrom(const CSSValueList& list) { - return new CSSValueList( + return MakeGarbageCollected<CSSValueList>( static_cast<ValueListSeparator>(list.value_list_separator_)); } + CSSValueList(ClassType, ValueListSeparator); + explicit CSSValueList(ValueListSeparator); + iterator begin() { return values_.begin(); } iterator end() { return values_.end(); } const_iterator begin() const { return values_.begin(); } @@ -72,12 +75,7 @@ void TraceAfterDispatch(blink::Visitor*); - protected: - CSSValueList(ClassType, ValueListSeparator); - private: - explicit CSSValueList(ValueListSeparator); - HeapVector<Member<const CSSValue>, 4> values_; DISALLOW_COPY_AND_ASSIGN(CSSValueList); };
diff --git a/third_party/blink/renderer/core/css/css_value_pair.h b/third_party/blink/renderer/core/css/css_value_pair.h index 211ec99..92312f7 100644 --- a/third_party/blink/renderer/core/css/css_value_pair.h +++ b/third_party/blink/renderer/core/css/css_value_pair.h
@@ -34,7 +34,19 @@ static CSSValuePair* Create(const CSSValue* first, const CSSValue* second, IdenticalValuesPolicy identical_values_policy) { - return new CSSValuePair(first, second, identical_values_policy); + return MakeGarbageCollected<CSSValuePair>(first, second, + identical_values_policy); + } + + CSSValuePair(const CSSValue* first, + const CSSValue* second, + IdenticalValuesPolicy identical_values_policy) + : CSSValue(kValuePairClass), + first_(first), + second_(second), + identical_values_policy_(identical_values_policy) { + DCHECK(first_); + DCHECK(second_); } const CSSValue& First() const { return *first_; } @@ -61,17 +73,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSValuePair(const CSSValue* first, - const CSSValue* second, - IdenticalValuesPolicy identical_values_policy) - : CSSValue(kValuePairClass), - first_(first), - second_(second), - identical_values_policy_(identical_values_policy) { - DCHECK(first_); - DCHECK(second_); - } - Member<const CSSValue> first_; Member<const CSSValue> second_; IdenticalValuesPolicy identical_values_policy_;
diff --git a/third_party/blink/renderer/core/css/css_value_pool.cc b/third_party/blink/renderer/core/css/css_value_pool.cc index d9fec1f..7cb3062 100644 --- a/third_party/blink/renderer/core/css/css_value_pool.cc +++ b/third_party/blink/renderer/core/css/css_value_pool.cc
@@ -37,7 +37,7 @@ thread_specific_pool, ()); Persistent<CSSValuePool>& pool_handle = *thread_specific_pool; if (!pool_handle) { - pool_handle = new CSSValuePool; + pool_handle = MakeGarbageCollected<CSSValuePool>(); pool_handle.RegisterAsStaticReference(); } return *pool_handle; @@ -45,7 +45,7 @@ CSSValuePool::CSSValuePool() : inherited_value_(new CSSInheritedValue), - initial_value_(new CSSInitialValue()), + initial_value_(MakeGarbageCollected<CSSInitialValue>()), unset_value_(new CSSUnsetValue), invalid_variable_value_(new CSSInvalidVariableValue), color_transparent_(new CSSColorValue(Color::kTransparent)),
diff --git a/third_party/blink/renderer/core/css/css_value_pool.h b/third_party/blink/renderer/core/css/css_value_pool.h index 40b6bfc9..b0ad715a 100644 --- a/third_party/blink/renderer/core/css/css_value_pool.h +++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -61,6 +61,8 @@ static const unsigned kMaximumFontFaceCacheSize = 128; using FontFamilyValueCache = HeapHashMap<String, Member<CSSFontFamilyValue>>; + CSSValuePool(); + // Cached individual values. CSSColorValue* TransparentColor() { return color_transparent_; } CSSColorValue* WhiteColor() { return color_white_; } @@ -124,8 +126,6 @@ void Trace(blink::Visitor*); private: - CSSValuePool(); - // Cached individual values. Member<CSSInheritedValue> inherited_value_; Member<CSSInitialValue> initial_value_;
diff --git a/third_party/blink/renderer/core/css/css_variable_reference_value.h b/third_party/blink/renderer/core/css/css_variable_reference_value.h index b79c7e4e..278f07d 100644 --- a/third_party/blink/renderer/core/css/css_variable_reference_value.h +++ b/third_party/blink/renderer/core/css/css_variable_reference_value.h
@@ -16,13 +16,25 @@ public: static CSSVariableReferenceValue* Create( scoped_refptr<CSSVariableData> data) { - return new CSSVariableReferenceValue(std::move(data)); + return MakeGarbageCollected<CSSVariableReferenceValue>(std::move(data)); } static CSSVariableReferenceValue* Create(scoped_refptr<CSSVariableData> data, const CSSParserContext& context) { - return new CSSVariableReferenceValue(std::move(data), context); + return MakeGarbageCollected<CSSVariableReferenceValue>(std::move(data), + context); } + CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data) + : CSSValue(kVariableReferenceClass), + data_(std::move(data)), + parser_context_(nullptr) {} + + CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data, + const CSSParserContext& context) + : CSSValue(kVariableReferenceClass), + data_(std::move(data)), + parser_context_(context) {} + CSSVariableData* VariableDataValue() const { return data_.get(); } const CSSParserContext* ParserContext() const { DCHECK(parser_context_); @@ -37,18 +49,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data) - : CSSValue(kVariableReferenceClass), - data_(std::move(data)), - parser_context_(nullptr) {} - - CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data, - const CSSParserContext& context) - : CSSValue(kVariableReferenceClass), - data_(std::move(data)), - parser_context_(context) { - } - scoped_refptr<CSSVariableData> data_; Member<const CSSParserContext> parser_context_; };
diff --git a/third_party/blink/renderer/core/css/css_viewport_rule.h b/third_party/blink/renderer/core/css/css_viewport_rule.h index ec49f61f..4ed4ce8 100644 --- a/third_party/blink/renderer/core/css/css_viewport_rule.h +++ b/third_party/blink/renderer/core/css/css_viewport_rule.h
@@ -46,8 +46,10 @@ public: static CSSViewportRule* Create(StyleRuleViewport* viewport_rule, CSSStyleSheet* sheet) { - return new CSSViewportRule(viewport_rule, sheet); + return MakeGarbageCollected<CSSViewportRule>(viewport_rule, sheet); } + + CSSViewportRule(StyleRuleViewport*, CSSStyleSheet*); ~CSSViewportRule() override; String cssText() const override; @@ -58,8 +60,6 @@ void Trace(blink::Visitor*) override; private: - CSSViewportRule(StyleRuleViewport*, CSSStyleSheet*); - CSSRule::Type type() const override { return kViewportRule; } Member<StyleRuleViewport> viewport_rule_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc b/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc index b23b9d6e..a1de447 100644 --- a/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc
@@ -22,18 +22,18 @@ "CSSKeywordValue does not support empty strings"); return nullptr; } - return new CSSKeywordValue(keyword); + return MakeGarbageCollected<CSSKeywordValue>(keyword); } CSSKeywordValue* CSSKeywordValue::FromCSSValue(const CSSValue& value) { if (value.IsInheritedValue()) - return new CSSKeywordValue(getValueName(CSSValueInherit)); + return MakeGarbageCollected<CSSKeywordValue>(getValueName(CSSValueInherit)); if (value.IsInitialValue()) - return new CSSKeywordValue(getValueName(CSSValueInitial)); + return MakeGarbageCollected<CSSKeywordValue>(getValueName(CSSValueInitial)); if (value.IsUnsetValue()) - return new CSSKeywordValue(getValueName(CSSValueUnset)); + return MakeGarbageCollected<CSSKeywordValue>(getValueName(CSSValueUnset)); if (value.IsIdentifierValue()) { - return new CSSKeywordValue( + return MakeGarbageCollected<CSSKeywordValue>( getValueName(ToCSSIdentifierValue(value).GetValueID())); } if (value.IsCustomIdentValue()) { @@ -43,7 +43,7 @@ // CSSKeywordValue represents a RHS. return nullptr; } - return new CSSKeywordValue(ident_value.Value()); + return MakeGarbageCollected<CSSKeywordValue>(ident_value.Value()); } NOTREACHED(); return nullptr; @@ -51,7 +51,7 @@ CSSKeywordValue* CSSKeywordValue::Create(const String& keyword) { DCHECK(!keyword.IsEmpty()); - return new CSSKeywordValue(keyword); + return MakeGarbageCollected<CSSKeywordValue>(keyword); } const String& CSSKeywordValue::value() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_keyword_value.h b/third_party/blink/renderer/core/css/cssom/css_keyword_value.h index 8ecb982..77acd90 100644 --- a/third_party/blink/renderer/core/css/cssom/css_keyword_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_keyword_value.h
@@ -22,6 +22,8 @@ static CSSKeywordValue* Create(const String& keyword, ExceptionState&); static CSSKeywordValue* FromCSSValue(const CSSValue&); + explicit CSSKeywordValue(const String& keyword) : keyword_value_(keyword) {} + StyleValueType GetType() const override { return kKeywordType; } const String& value() const; @@ -31,8 +33,6 @@ const CSSValue* ToCSSValue() const override; private: - explicit CSSKeywordValue(const String& keyword) : keyword_value_(keyword) {} - String keyword_value_; DISALLOW_COPY_AND_ASSIGN(CSSKeywordValue); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_invert.h b/third_party/blink/renderer/core/css/cssom/css_math_invert.h index 2d164c6..134df10 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_invert.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_invert.h
@@ -22,10 +22,13 @@ } // Blink-internal constructor static CSSMathInvert* Create(CSSNumericValue* value) { - return new CSSMathInvert( + return MakeGarbageCollected<CSSMathInvert>( value, CSSNumericValueType::NegateExponents(value->Type())); } + CSSMathInvert(CSSNumericValue* value, const CSSNumericValueType& type) + : CSSMathValue(type), value_(value) {} + String getOperator() const final { return "invert"; } void value(CSSNumberish& value) { value.SetCSSNumericValue(value_); } @@ -56,9 +59,6 @@ } private: - CSSMathInvert(CSSNumericValue* value, const CSSNumericValueType& type) - : CSSMathValue(type), value_(value) {} - // From CSSNumericValue CSSNumericValue* Invert() final { return value_.Get(); } base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_max.cc b/third_party/blink/renderer/core/css/cssom/css_math_max.cc index afad801..07986816 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_max.cc +++ b/third_party/blink/renderer/core/css/cssom/css_math_max.cc
@@ -31,8 +31,8 @@ CSSNumericValueType final_type = CSSMathVariadic::TypeCheck(values, CSSNumericValueType::Add, error); return error ? nullptr - : new CSSMathMax(CSSNumericArray::Create(std::move(values)), - final_type); + : MakeGarbageCollected<CSSMathMax>( + CSSNumericArray::Create(std::move(values)), final_type); } base::Optional<CSSNumericSumValue> CSSMathMax::SumValue() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_max.h b/third_party/blink/renderer/core/css/cssom/css_math_max.h index 76433594..c307520d 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_max.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_max.h
@@ -22,6 +22,9 @@ // Blink-internal constructor. static CSSMathMax* Create(CSSNumericValueVector); + CSSMathMax(CSSNumericArray* values, const CSSNumericValueType& type) + : CSSMathVariadic(values, type) {} + String getOperator() const final { return "max"; } // From CSSStyleValue. @@ -33,9 +36,6 @@ } private: - CSSMathMax(CSSNumericArray* values, const CSSNumericValueType& type) - : CSSMathVariadic(values, type) {} - void BuildCSSText(Nested, ParenLess, StringBuilder&) const final; base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_min.cc b/third_party/blink/renderer/core/css/cssom/css_math_min.cc index 49afba4..93cf2c9 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_min.cc +++ b/third_party/blink/renderer/core/css/cssom/css_math_min.cc
@@ -31,8 +31,8 @@ CSSNumericValueType final_type = CSSMathVariadic::TypeCheck(values, CSSNumericValueType::Add, error); return error ? nullptr - : new CSSMathMin(CSSNumericArray::Create(std::move(values)), - final_type); + : MakeGarbageCollected<CSSMathMin>( + CSSNumericArray::Create(std::move(values)), final_type); } base::Optional<CSSNumericSumValue> CSSMathMin::SumValue() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_min.h b/third_party/blink/renderer/core/css/cssom/css_math_min.h index 7edde5b0f..6f7dbdb 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_min.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_min.h
@@ -24,6 +24,9 @@ // Blink-internal constructor. static CSSMathMin* Create(CSSNumericValueVector); + CSSMathMin(CSSNumericArray* values, const CSSNumericValueType& type) + : CSSMathVariadic(values, type) {} + String getOperator() const final { return "min"; } // From CSSStyleValue. @@ -35,9 +38,6 @@ } private: - CSSMathMin(CSSNumericArray* values, const CSSNumericValueType& type) - : CSSMathVariadic(values, type) {} - void BuildCSSText(Nested, ParenLess, StringBuilder&) const final; base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_negate.h b/third_party/blink/renderer/core/css/cssom/css_math_negate.h index 56201d2..b800222 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_negate.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_negate.h
@@ -22,9 +22,12 @@ } // Blink-internal constructor static CSSMathNegate* Create(CSSNumericValue* value) { - return new CSSMathNegate(value, value->Type()); + return MakeGarbageCollected<CSSMathNegate>(value, value->Type()); } + CSSMathNegate(CSSNumericValue* value, const CSSNumericValueType& type) + : CSSMathValue(type), value_(value) {} + String getOperator() const final { return "negate"; } void value(CSSNumberish& value) { value.SetCSSNumericValue(value_); } @@ -55,9 +58,6 @@ } private: - CSSMathNegate(CSSNumericValue* value, const CSSNumericValueType& type) - : CSSMathValue(type), value_(value) {} - // From CSSNumericValue CSSNumericValue* Negate() final { return value_.Get(); } base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_product.cc b/third_party/blink/renderer/core/css/cssom/css_math_product.cc index 88a6435c..f38e313 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_product.cc +++ b/third_party/blink/renderer/core/css/cssom/css_math_product.cc
@@ -53,8 +53,8 @@ CSSNumericValueType final_type = CSSMathVariadic::TypeCheck(values, CSSNumericValueType::Multiply, error); return error ? nullptr - : new CSSMathProduct(CSSNumericArray::Create(std::move(values)), - final_type); + : MakeGarbageCollected<CSSMathProduct>( + CSSNumericArray::Create(std::move(values)), final_type); } base::Optional<CSSNumericSumValue> CSSMathProduct::SumValue() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_product.h b/third_party/blink/renderer/core/css/cssom/css_math_product.h index 3fa5ced1..f0b3210 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_product.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_product.h
@@ -22,6 +22,9 @@ // Blink internal-constructor. static CSSMathProduct* Create(CSSNumericValueVector); + CSSMathProduct(CSSNumericArray* values, const CSSNumericValueType& type) + : CSSMathVariadic(values, type) {} + String getOperator() const final { return "product"; } // From CSSStyleValue. @@ -30,9 +33,6 @@ CSSCalcExpressionNode* ToCalcExpressionNode() const final; private: - CSSMathProduct(CSSNumericArray* values, const CSSNumericValueType& type) - : CSSMathVariadic(values, type) {} - void BuildCSSText(Nested, ParenLess, StringBuilder&) const final; base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_sum.cc b/third_party/blink/renderer/core/css/cssom/css_math_sum.cc index b468e1d7..a69b090 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_sum.cc +++ b/third_party/blink/renderer/core/css/cssom/css_math_sum.cc
@@ -71,8 +71,8 @@ CSSNumericValueType final_type = CSSMathVariadic::TypeCheck(values, CSSNumericValueType::Add, error); return error ? nullptr - : new CSSMathSum(CSSNumericArray::Create(std::move(values)), - final_type); + : MakeGarbageCollected<CSSMathSum>( + CSSNumericArray::Create(std::move(values)), final_type); } base::Optional<CSSNumericSumValue> CSSMathSum::SumValue() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_sum.h b/third_party/blink/renderer/core/css/cssom/css_math_sum.h index 69398350..0ff1d04 100644 --- a/third_party/blink/renderer/core/css/cssom/css_math_sum.h +++ b/third_party/blink/renderer/core/css/cssom/css_math_sum.h
@@ -22,6 +22,9 @@ // Blink-internal constructor. static CSSMathSum* Create(CSSNumericValueVector); + CSSMathSum(CSSNumericArray* values, const CSSNumericValueType& type) + : CSSMathVariadic(values, type) {} + String getOperator() const final { return "sum"; } // From CSSStyleValue. @@ -30,9 +33,6 @@ CSSCalcExpressionNode* ToCalcExpressionNode() const final; private: - CSSMathSum(CSSNumericArray* values, const CSSNumericValueType& type) - : CSSMathVariadic(values, type) {} - void BuildCSSText(Nested, ParenLess, StringBuilder&) const final; base::Optional<CSSNumericSumValue> SumValue() const final;
diff --git a/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc b/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc index fdbf4dc2..568cfb7 100644 --- a/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc +++ b/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc
@@ -29,7 +29,7 @@ CSSMatrixComponent* CSSMatrixComponent::Create( DOMMatrixReadOnly* matrix, const CSSMatrixComponentOptions* options) { - return new CSSMatrixComponent( + return MakeGarbageCollected<CSSMatrixComponent>( matrix, options->hasIs2D() ? options->is2D() : matrix->is2D()); }
diff --git a/third_party/blink/renderer/core/css/cssom/css_matrix_component.h b/third_party/blink/renderer/core/css/cssom/css_matrix_component.h index c989c72..e60ebef 100644 --- a/third_party/blink/renderer/core/css/cssom/css_matrix_component.h +++ b/third_party/blink/renderer/core/css/cssom/css_matrix_component.h
@@ -28,6 +28,9 @@ // Blink-internal ways of creating CSSMatrixComponents. static CSSMatrixComponent* FromCSSValue(const CSSFunctionValue&); + CSSMatrixComponent(DOMMatrixReadOnly* matrix, bool is2D) + : CSSTransformComponent(is2D), matrix_(DOMMatrix::Create(matrix)) {} + // Getters and setters for attributes defined in the IDL. DOMMatrix* matrix() { return matrix_.Get(); } void setMatrix(DOMMatrix* matrix) { matrix_ = matrix; } @@ -44,9 +47,6 @@ } private: - CSSMatrixComponent(DOMMatrixReadOnly* matrix, bool is2D) - : CSSTransformComponent(is2D), matrix_(DOMMatrix::Create(matrix)) {} - Member<DOMMatrix> matrix_; DISALLOW_COPY_AND_ASSIGN(CSSMatrixComponent); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_array.h b/third_party/blink/renderer/core/css/cssom/css_numeric_array.h index fbd9c5ea..529f6a4 100644 --- a/third_party/blink/renderer/core/css/cssom/css_numeric_array.h +++ b/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
@@ -17,13 +17,17 @@ public: // blink internal static CSSNumericArray* Create(CSSNumericValueVector values) { - return new CSSNumericArray(std::move(values)); + return MakeGarbageCollected<CSSNumericArray>(std::move(values)); } static CSSNumericArray* FromNumberishes( const HeapVector<CSSNumberish>& values) { - return new CSSNumericArray(CSSNumberishesToNumericValues(values)); + return MakeGarbageCollected<CSSNumericArray>( + CSSNumberishesToNumericValues(values)); } + explicit CSSNumericArray(CSSNumericValueVector values) + : values_(std::move(values)) {} + void Trace(blink::Visitor* visitor) override { visitor->Trace(values_); ScriptWrappable::Trace(visitor); @@ -39,9 +43,6 @@ const CSSNumericValueVector& Values() const { return values_; } private: - explicit CSSNumericArray(CSSNumericValueVector values) - : values_(std::move(values)) {} - CSSNumericValueVector values_; DISALLOW_COPY_AND_ASSIGN(CSSNumericArray); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_perspective.cc b/third_party/blink/renderer/core/css/cssom/css_perspective.cc index e6969ce5..e992b7f3 100644 --- a/third_party/blink/renderer/core/css/cssom/css_perspective.cc +++ b/third_party/blink/renderer/core/css/cssom/css_perspective.cc
@@ -26,7 +26,7 @@ exception_state.ThrowTypeError("Must pass length to CSSPerspective"); return nullptr; } - return new CSSPerspective(length); + return MakeGarbageCollected<CSSPerspective>(length); } void CSSPerspective::setLength(CSSNumericValue* length, @@ -43,7 +43,7 @@ DCHECK_EQ(value.length(), 1U); CSSNumericValue* length = CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0))); - return new CSSPerspective(length); + return MakeGarbageCollected<CSSPerspective>(length); } DOMMatrix* CSSPerspective::toMatrix(ExceptionState& exception_state) const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_perspective.h b/third_party/blink/renderer/core/css/cssom/css_perspective.h index 3e78565..ff15be0 100644 --- a/third_party/blink/renderer/core/css/cssom/css_perspective.h +++ b/third_party/blink/renderer/core/css/cssom/css_perspective.h
@@ -28,6 +28,8 @@ // Blink-internal ways of creating CSSPerspectives. static CSSPerspective* FromCSSValue(const CSSFunctionValue&); + CSSPerspective(CSSNumericValue* length); + // Getters and setters for attributes defined in the IDL. CSSNumericValue* length() { return length_.Get(); } void setLength(CSSNumericValue*, ExceptionState&); @@ -49,8 +51,6 @@ } private: - CSSPerspective(CSSNumericValue* length); - Member<CSSNumericValue> length_; DISALLOW_COPY_AND_ASSIGN(CSSPerspective); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_position_value.cc b/third_party/blink/renderer/core/css/cssom/css_position_value.cc index 81c2b3cc..1ed55ac3 100644 --- a/third_party/blink/renderer/core/css/cssom/css_position_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_position_value.cc
@@ -86,14 +86,14 @@ "Must pass length or percentage to y in CSSPositionValue"); return nullptr; } - return new CSSPositionValue(x, y); + return MakeGarbageCollected<CSSPositionValue>(x, y); } CSSPositionValue* CSSPositionValue::Create(CSSNumericValue* x, CSSNumericValue* y) { if (!IsValidPositionCoord(x) || !IsValidPositionCoord(y)) return nullptr; - return new CSSPositionValue(x, y); + return MakeGarbageCollected<CSSPositionValue>(x, y); } CSSPositionValue* CSSPositionValue::FromCSSValue(const CSSValue& value) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_position_value.h b/third_party/blink/renderer/core/css/cssom/css_position_value.h index 4b7201564..4d9d1ac 100644 --- a/third_party/blink/renderer/core/css/cssom/css_position_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_position_value.h
@@ -29,6 +29,8 @@ static CSSPositionValue* FromCSSValue(const CSSValue&); + CSSPositionValue(CSSNumericValue* x, CSSNumericValue* y) : x_(x), y_(y) {} + // Getters and setters defined in the IDL. CSSNumericValue* x() { return x_.Get(); } CSSNumericValue* y() { return y_.Get(); } @@ -50,8 +52,6 @@ static bool IsValidCoordinate(CSSNumericValue* coord); protected: - CSSPositionValue(CSSNumericValue* x, CSSNumericValue* y) : x_(x), y_(y) {} - Member<CSSNumericValue> x_; Member<CSSNumericValue> y_; DISALLOW_COPY_AND_ASSIGN(CSSPositionValue);
diff --git a/third_party/blink/renderer/core/css/cssom/css_rotate.cc b/third_party/blink/renderer/core/css/cssom/css_rotate.cc index 51bd5f85..f746471 100644 --- a/third_party/blink/renderer/core/css/cssom/css_rotate.cc +++ b/third_party/blink/renderer/core/css/cssom/css_rotate.cc
@@ -75,8 +75,9 @@ exception_state.ThrowTypeError("Must pass an angle to CSSRotate"); return nullptr; } - return new CSSRotate(CSSUnitValue::Create(0), CSSUnitValue::Create(0), - CSSUnitValue::Create(1), angle, true /* is2D */); + return MakeGarbageCollected<CSSRotate>( + CSSUnitValue::Create(0), CSSUnitValue::Create(0), CSSUnitValue::Create(1), + angle, true /* is2D */); } CSSRotate* CSSRotate::Create(const CSSNumberish& x, @@ -97,19 +98,21 @@ exception_state.ThrowTypeError("Must pass an angle to CSSRotate"); return nullptr; } - return new CSSRotate(x_value, y_value, z_value, angle, false /* is2D */); + return MakeGarbageCollected<CSSRotate>(x_value, y_value, z_value, angle, + false /* is2D */); } CSSRotate* CSSRotate::Create(CSSNumericValue* angle) { - return new CSSRotate(CSSUnitValue::Create(0), CSSUnitValue::Create(0), - CSSUnitValue::Create(1), angle, true /* is2D */); + return MakeGarbageCollected<CSSRotate>( + CSSUnitValue::Create(0), CSSUnitValue::Create(0), CSSUnitValue::Create(1), + angle, true /* is2D */); } CSSRotate* CSSRotate::Create(CSSNumericValue* x, CSSNumericValue* y, CSSNumericValue* z, CSSNumericValue* angle) { - return new CSSRotate(x, y, z, angle, false /* is2D */); + return MakeGarbageCollected<CSSRotate>(x, y, z, angle, false /* is2D */); } CSSRotate* CSSRotate::FromCSSValue(const CSSFunctionValue& value) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_rotate.h b/third_party/blink/renderer/core/css/cssom/css_rotate.h index 7b3659a..f0a5f04 100644 --- a/third_party/blink/renderer/core/css/cssom/css_rotate.h +++ b/third_party/blink/renderer/core/css/cssom/css_rotate.h
@@ -38,6 +38,12 @@ CSSNumericValue* angle); static CSSRotate* FromCSSValue(const CSSFunctionValue&); + CSSRotate(CSSNumericValue* x, + CSSNumericValue* y, + CSSNumericValue* z, + CSSNumericValue* angle, + bool is2D); + // Getters and setters for attributes defined in the IDL. CSSNumericValue* angle() { return angle_.Get(); } void setAngle(CSSNumericValue* angle, ExceptionState&); @@ -63,12 +69,6 @@ } private: - CSSRotate(CSSNumericValue* x, - CSSNumericValue* y, - CSSNumericValue* z, - CSSNumericValue* angle, - bool is2D); - Member<CSSNumericValue> angle_; Member<CSSNumericValue> x_; Member<CSSNumericValue> y_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_scale.h b/third_party/blink/renderer/core/css/cssom/css_scale.h index 76bcf77..e564e330 100644 --- a/third_party/blink/renderer/core/css/cssom/css_scale.h +++ b/third_party/blink/renderer/core/css/cssom/css_scale.h
@@ -33,15 +33,21 @@ // Blink-internal ways of creating CSSScales. static CSSScale* Create(CSSNumericValue* x, CSSNumericValue* y) { - return new CSSScale(x, y, CSSUnitValue::Create(1), true /* is2D */); + return MakeGarbageCollected<CSSScale>(x, y, CSSUnitValue::Create(1), + true /* is2D */); } static CSSScale* Create(CSSNumericValue* x, CSSNumericValue* y, CSSNumericValue* z) { - return new CSSScale(x, y, z, false /* is2D */); + return MakeGarbageCollected<CSSScale>(x, y, z, false /* is2D */); } static CSSScale* FromCSSValue(const CSSFunctionValue&); + CSSScale(CSSNumericValue* x, + CSSNumericValue* y, + CSSNumericValue* z, + bool is2D); + // Getters and setters for attributes defined in the IDL. void x(CSSNumberish& x) { x.SetCSSNumericValue(x_); } void y(CSSNumberish& y) { y.SetCSSNumericValue(y_); } @@ -64,11 +70,6 @@ } private: - CSSScale(CSSNumericValue* x, - CSSNumericValue* y, - CSSNumericValue* z, - bool is2D); - Member<CSSNumericValue> x_; Member<CSSNumericValue> y_; Member<CSSNumericValue> z_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew.cc b/third_party/blink/renderer/core/css/cssom/css_skew.cc index 9bf1634..22584e4 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew.cc +++ b/third_party/blink/renderer/core/css/cssom/css_skew.cc
@@ -30,7 +30,7 @@ exception_state.ThrowTypeError("CSSSkew does not support non-angles"); return nullptr; } - return new CSSSkew(ax, ay); + return MakeGarbageCollected<CSSSkew>(ax, ay); } void CSSSkew::setAx(CSSNumericValue* value, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew.h b/third_party/blink/renderer/core/css/cssom/css_skew.h index 6b4d7d7..9fddbe91 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew.h +++ b/third_party/blink/renderer/core/css/cssom/css_skew.h
@@ -24,12 +24,14 @@ // Constructor defined in the IDL. static CSSSkew* Create(CSSNumericValue*, CSSNumericValue*, ExceptionState&); static CSSSkew* Create(CSSNumericValue* ax, CSSNumericValue* ay) { - return new CSSSkew(ax, ay); + return MakeGarbageCollected<CSSSkew>(ax, ay); } // Internal ways of creating CSSSkew. static CSSSkew* FromCSSValue(const CSSFunctionValue&); + CSSSkew(CSSNumericValue* ax, CSSNumericValue* ay); + // Getters and setters for the ax and ay attributes defined in the IDL. CSSNumericValue* ax() { return ax_.Get(); } CSSNumericValue* ay() { return ay_.Get(); } @@ -54,8 +56,6 @@ } private: - CSSSkew(CSSNumericValue* ax, CSSNumericValue* ay); - Member<CSSNumericValue> ax_; Member<CSSNumericValue> ay_; DISALLOW_COPY_AND_ASSIGN(CSSSkew);
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew_x.cc b/third_party/blink/renderer/core/css/cssom/css_skew_x.cc index 424665d..cfaa123 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew_x.cc +++ b/third_party/blink/renderer/core/css/cssom/css_skew_x.cc
@@ -29,7 +29,7 @@ exception_state.ThrowTypeError("CSSSkewX does not support non-angles"); return nullptr; } - return new CSSSkewX(ax); + return MakeGarbageCollected<CSSSkewX>(ax); } void CSSSkewX::setAx(CSSNumericValue* value, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew_x.h b/third_party/blink/renderer/core/css/cssom/css_skew_x.h index ce9aec9..7e16aac 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew_x.h +++ b/third_party/blink/renderer/core/css/cssom/css_skew_x.h
@@ -23,11 +23,15 @@ public: // Constructor defined in the IDL. static CSSSkewX* Create(CSSNumericValue*, ExceptionState&); - static CSSSkewX* Create(CSSNumericValue* ax) { return new CSSSkewX(ax); } + static CSSSkewX* Create(CSSNumericValue* ax) { + return MakeGarbageCollected<CSSSkewX>(ax); + } // Internal ways of creating CSSSkewX. static CSSSkewX* FromCSSValue(const CSSFunctionValue&); + CSSSkewX(CSSNumericValue* ax); + // Getters and setters for the ax attributes defined in the IDL. CSSNumericValue* ax() { return ax_.Get(); } void setAx(CSSNumericValue*, ExceptionState&); @@ -49,8 +53,6 @@ } private: - CSSSkewX(CSSNumericValue* ax); - Member<CSSNumericValue> ax_; DISALLOW_COPY_AND_ASSIGN(CSSSkewX); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew_y.cc b/third_party/blink/renderer/core/css/cssom/css_skew_y.cc index f064f89..d491642 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew_y.cc +++ b/third_party/blink/renderer/core/css/cssom/css_skew_y.cc
@@ -29,7 +29,7 @@ exception_state.ThrowTypeError("CSSSkewY does not support non-angles"); return nullptr; } - return new CSSSkewY(ay); + return MakeGarbageCollected<CSSSkewY>(ay); } void CSSSkewY::setAy(CSSNumericValue* value, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_skew_y.h b/third_party/blink/renderer/core/css/cssom/css_skew_y.h index cb13366..10378a7 100644 --- a/third_party/blink/renderer/core/css/cssom/css_skew_y.h +++ b/third_party/blink/renderer/core/css/cssom/css_skew_y.h
@@ -23,11 +23,15 @@ public: // Constructor defined in the IDL. static CSSSkewY* Create(CSSNumericValue*, ExceptionState&); - static CSSSkewY* Create(CSSNumericValue* ay) { return new CSSSkewY(ay); } + static CSSSkewY* Create(CSSNumericValue* ay) { + return MakeGarbageCollected<CSSSkewY>(ay); + } // Internal ways of creating CSSSkewY. static CSSSkewY* FromCSSValue(const CSSFunctionValue&); + CSSSkewY(CSSNumericValue* ay); + // Getters and setters for the ay attributes defined in the IDL. CSSNumericValue* ay() { return ay_.Get(); } void setAy(CSSNumericValue*, ExceptionState&); @@ -49,8 +53,6 @@ } private: - CSSSkewY(CSSNumericValue* ay); - Member<CSSNumericValue> ay_; DISALLOW_COPY_AND_ASSIGN(CSSSkewY); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.cc b/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.cc index 444ce68..9a585936 100644 --- a/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.cc
@@ -30,7 +30,8 @@ CSSUnparsedValue* fallback) { if (!variable.StartsWith("--")) return nullptr; - return new CSSStyleVariableReferenceValue(variable, fallback); + return MakeGarbageCollected<CSSStyleVariableReferenceValue>(variable, + fallback); } void CSSStyleVariableReferenceValue::setVariable(
diff --git a/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h b/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h index 87fd19e..2173b0c 100644 --- a/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h
@@ -32,6 +32,10 @@ const String& variable, CSSUnparsedValue* fallback = nullptr); + CSSStyleVariableReferenceValue(const String& variable, + CSSUnparsedValue* fallback) + : variable_(variable), fallback_(fallback) {} + const String& variable() const { return variable_; } void setVariable(const String&, ExceptionState&); @@ -44,10 +48,6 @@ } protected: - CSSStyleVariableReferenceValue(const String& variable, - CSSUnparsedValue* fallback) - : variable_(variable), fallback_(fallback) {} - String variable_; Member<CSSUnparsedValue> fallback_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_transform_value.cc b/third_party/blink/renderer/core/css/cssom/css_transform_value.cc index 3a85ef3..3247963 100644 --- a/third_party/blink/renderer/core/css/cssom/css_transform_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_transform_value.cc
@@ -28,7 +28,7 @@ const HeapVector<Member<CSSTransformComponent>>& transform_components) { if (transform_components.IsEmpty()) return nullptr; - return new CSSTransformValue(transform_components); + return MakeGarbageCollected<CSSTransformValue>(transform_components); } CSSTransformValue* CSSTransformValue::FromCSSValue(const CSSValue& css_value) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_transform_value.h b/third_party/blink/renderer/core/css/cssom/css_transform_value.h index 8a6dc7a523..c7bcc5a 100644 --- a/third_party/blink/renderer/core/css/cssom/css_transform_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_transform_value.h
@@ -30,6 +30,10 @@ static CSSTransformValue* FromCSSValue(const CSSValue&); + CSSTransformValue( + const HeapVector<Member<CSSTransformComponent>>& transform_components) + : CSSStyleValue(), transform_components_(transform_components) {} + bool is2D() const; DOMMatrix* toMatrix(ExceptionState&) const; @@ -53,10 +57,6 @@ } private: - CSSTransformValue( - const HeapVector<Member<CSSTransformComponent>>& transform_components) - : CSSStyleValue(), transform_components_(transform_components) {} - HeapVector<Member<CSSTransformComponent>> transform_components_; DISALLOW_COPY_AND_ASSIGN(CSSTransformValue); };
diff --git a/third_party/blink/renderer/core/css/cssom/css_translate.cc b/third_party/blink/renderer/core/css/cssom/css_translate.cc index f571a1e47..3a40305 100644 --- a/third_party/blink/renderer/core/css/cssom/css_translate.cc +++ b/third_party/blink/renderer/core/css/cssom/css_translate.cc
@@ -92,7 +92,7 @@ "Must pass length or percentage to X and Y of CSSTranslate"); return nullptr; } - return new CSSTranslate( + return MakeGarbageCollected<CSSTranslate>( x, y, CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels), true /* is2D */); } @@ -107,11 +107,11 @@ "Must pass length or percentage to X, Y and Z of CSSTranslate"); return nullptr; } - return new CSSTranslate(x, y, z, false /* is2D */); + return MakeGarbageCollected<CSSTranslate>(x, y, z, false /* is2D */); } CSSTranslate* CSSTranslate::Create(CSSNumericValue* x, CSSNumericValue* y) { - return new CSSTranslate( + return MakeGarbageCollected<CSSTranslate>( x, y, CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kPixels), true /* is2D */); } @@ -119,7 +119,7 @@ CSSTranslate* CSSTranslate::Create(CSSNumericValue* x, CSSNumericValue* y, CSSNumericValue* z) { - return new CSSTranslate(x, y, z, false /* is2D */); + return MakeGarbageCollected<CSSTranslate>(x, y, z, false /* is2D */); } CSSTranslate* CSSTranslate::FromCSSValue(const CSSFunctionValue& value) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_translate.h b/third_party/blink/renderer/core/css/cssom/css_translate.h index 34ff0ba7..e28fa08e 100644 --- a/third_party/blink/renderer/core/css/cssom/css_translate.h +++ b/third_party/blink/renderer/core/css/cssom/css_translate.h
@@ -40,6 +40,11 @@ CSSNumericValue* z); static CSSTranslate* FromCSSValue(const CSSFunctionValue&); + CSSTranslate(CSSNumericValue* x, + CSSNumericValue* y, + CSSNumericValue* z, + bool is2D); + // Getters and setters for attributes defined in the IDL. CSSNumericValue* x() { return x_; } CSSNumericValue* y() { return y_; } @@ -62,11 +67,6 @@ } private: - CSSTranslate(CSSNumericValue* x, - CSSNumericValue* y, - CSSNumericValue* z, - bool is2D); - Member<CSSNumericValue> x_; Member<CSSNumericValue> y_; Member<CSSNumericValue> z_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_unit_value.cc b/third_party/blink/renderer/core/css/cssom/css_unit_value.cc index c7a9652..5af88ff8 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unit_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_unit_value.cc
@@ -97,13 +97,13 @@ exception_state.ThrowTypeError("Invalid unit: " + unit_name); return nullptr; } - return new CSSUnitValue(value, unit); + return MakeGarbageCollected<CSSUnitValue>(value, unit); } CSSUnitValue* CSSUnitValue::Create(double value, CSSPrimitiveValue::UnitType unit) { DCHECK(IsValidUnit(unit)); - return new CSSUnitValue(value, unit); + return MakeGarbageCollected<CSSUnitValue>(value, unit); } CSSUnitValue* CSSUnitValue::FromCSSValue(const CSSPrimitiveValue& value) { @@ -113,7 +113,7 @@ if (!IsValidUnit(unit)) return nullptr; - return new CSSUnitValue(value.GetDoubleValue(), unit); + return MakeGarbageCollected<CSSUnitValue>(value.GetDoubleValue(), unit); } String CSSUnitValue::unit() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_unit_value.h b/third_party/blink/renderer/core/css/cssom/css_unit_value.h index 9535978f..3d5b8ddf 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unit_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_unit_value.h
@@ -28,6 +28,11 @@ CSSPrimitiveValue::UnitType = CSSPrimitiveValue::UnitType::kNumber); static CSSUnitValue* FromCSSValue(const CSSPrimitiveValue&); + CSSUnitValue(double value, CSSPrimitiveValue::UnitType unit) + : CSSNumericValue(CSSNumericValueType(unit)), + value_(value), + unit_(unit) {} + // Setters and getters for attributes defined in the IDL. void setValue(double new_value) { value_ = new_value; } double value() const { return value_; } @@ -52,11 +57,6 @@ CSSCalcExpressionNode* ToCalcExpressionNode() const final; private: - CSSUnitValue(double value, CSSPrimitiveValue::UnitType unit) - : CSSNumericValue(CSSNumericValueType(unit)), - value_(value), - unit_(unit) {} - double ConvertFixedLength(CSSPrimitiveValue::UnitType) const; double ConvertAngle(CSSPrimitiveValue::UnitType) const;
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h index a8b7d226..dc29d1e 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
@@ -23,7 +23,7 @@ public: static CSSUnparsedValue* Create( const HeapVector<CSSUnparsedSegment>& tokens) { - return new CSSUnparsedValue(tokens); + return MakeGarbageCollected<CSSUnparsedValue>(tokens); } // Blink-internal constructor @@ -34,6 +34,9 @@ static CSSUnparsedValue* FromCSSValue(const CSSCustomPropertyDeclaration&); static CSSUnparsedValue* FromCSSVariableData(const CSSVariableData&); + CSSUnparsedValue(const HeapVector<CSSUnparsedSegment>& tokens) + : CSSStyleValue(), tokens_(tokens) {} + const CSSValue* ToCSSValue() const override; StyleValueType GetType() const override { return kUnparsedType; } @@ -50,10 +53,6 @@ CSSStyleValue::Trace(visitor); } - protected: - CSSUnparsedValue(const HeapVector<CSSUnparsedSegment>& tokens) - : CSSStyleValue(), tokens_(tokens) {} - private: static CSSUnparsedValue* FromString(const String& string) { HeapVector<CSSUnparsedSegment> tokens;
diff --git a/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h b/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h index 5a384a1..ce971b4 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h
@@ -20,15 +20,23 @@ CSSPropertyID property, const AtomicString& custom_property_name, const String& css_text) { - return new CSSUnsupportedStyleValue(property, custom_property_name, - css_text); + return MakeGarbageCollected<CSSUnsupportedStyleValue>( + property, custom_property_name, css_text); } static CSSUnsupportedStyleValue* Create( CSSPropertyID property, const AtomicString& custom_property_name, const CSSValue& value) { - return new CSSUnsupportedStyleValue(property, custom_property_name, - value.CssText()); + return MakeGarbageCollected<CSSUnsupportedStyleValue>( + property, custom_property_name, value.CssText()); + } + + CSSUnsupportedStyleValue(CSSPropertyID property, + const AtomicString& custom_property_name, + const String& css_text) + : property_(property), custom_property_name_(custom_property_name) { + SetCSSText(css_text); + DCHECK_EQ(property == CSSPropertyVariable, !custom_property_name.IsNull()); } StyleValueType GetType() const override { @@ -46,14 +54,6 @@ String toString() const final { return CSSText(); } private: - CSSUnsupportedStyleValue(CSSPropertyID property, - const AtomicString& custom_property_name, - const String& css_text) - : property_(property), custom_property_name_(custom_property_name) { - SetCSSText(css_text); - DCHECK_EQ(property == CSSPropertyVariable, !custom_property_name.IsNull()); - } - const CSSPropertyID property_; // Name is set when property_ is CSSPropertyVariable, otherwise it's // g_null_atom.
diff --git a/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc b/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc index d0bb96c..97005aba 100644 --- a/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc
@@ -25,12 +25,12 @@ } // Use absolute URL for CSSImageValue but keep relative URL for // getter and serialization. - return new CSSURLImageValue( + return MakeGarbageCollected<CSSURLImageValue>( *CSSImageValue::Create(url, parsed_url, Referrer())); } CSSURLImageValue* CSSURLImageValue::FromCSSValue(const CSSImageValue& value) { - return new CSSURLImageValue(value); + return MakeGarbageCollected<CSSURLImageValue>(value); } const String& CSSURLImageValue::url() const {
diff --git a/third_party/blink/renderer/core/css/cssom/css_url_image_value.h b/third_party/blink/renderer/core/css/cssom/css_url_image_value.h index 81ce5e2..9635cb3 100644 --- a/third_party/blink/renderer/core/css/cssom/css_url_image_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_url_image_value.h
@@ -21,6 +21,8 @@ static CSSURLImageValue* FromCSSValue(const CSSImageValue&); + explicit CSSURLImageValue(const CSSImageValue& value) : value_(value) {} + const String& url() const; // CSSStyleImageValue @@ -40,8 +42,6 @@ void Trace(blink::Visitor*) override; private: - explicit CSSURLImageValue(const CSSImageValue& value) : value_(value) {} - scoped_refptr<Image> GetImage() const; Member<const CSSImageValue> value_;
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc index 99f6c8f1..432a8856 100644 --- a/third_party/blink/renderer/core/css/font_face.cc +++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -113,7 +113,7 @@ } } - return new CSSFontFace(font_face, ranges); + return MakeGarbageCollected<CSSFontFace>(font_face, ranges); } } // namespace
diff --git a/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc b/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc index 9f9aa84..40f2db6 100644 --- a/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc +++ b/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc
@@ -209,7 +209,7 @@ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorStyleInvalidatorInvalidateEvent::InvalidationList( + inspector_style_invalidator_invalidate_event::InvalidationList( node, pending_invalidations.Descendants())); } }
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.cc b/third_party/blink/renderer/core/css/parser/css_parser_context.cc index fbbe2c8..c6e1dc48 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_context.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_context.cc
@@ -32,7 +32,7 @@ else policy_disposition = kCheckContentSecurityPolicy; - return new CSSParserContext( + return MakeGarbageCollected<CSSParserContext>( context.Url(), false /* is_opaque_response_from_service_worker */, WTF::TextEncoding(), kHTMLStandardMode, kHTMLStandardMode, kLiveProfile, referrer, true, false, context.GetSecureContextMode(), policy_disposition, @@ -59,7 +59,7 @@ CSSParserContext* CSSParserContext::Create( const CSSParserContext* other, const Document* use_counter_document) { - return new CSSParserContext( + return MakeGarbageCollected<CSSParserContext>( other->base_url_, other->is_opaque_response_from_service_worker_, other->charset_, other->mode_, other->match_mode_, other->profile_, other->referrer_, other->is_html_document_, @@ -76,7 +76,7 @@ ReferrerPolicy referrer_policy, const WTF::TextEncoding& charset, const Document* use_counter_document) { - return new CSSParserContext( + return MakeGarbageCollected<CSSParserContext>( base_url, is_opaque_response_from_service_worker, charset, other->mode_, other->match_mode_, other->profile_, Referrer(base_url.StrippedForUseAsReferrer(), referrer_policy), @@ -92,7 +92,7 @@ SecureContextMode secure_context_mode, SelectorProfile profile, const Document* use_counter_document) { - return new CSSParserContext( + return MakeGarbageCollected<CSSParserContext>( KURL(), false /* is_opaque_response_from_service_worker */, WTF::TextEncoding(), mode, mode, profile, Referrer(), false, false, secure_context_mode, kDoNotCheckContentSecurityPolicy, @@ -142,7 +142,7 @@ else policy_disposition = kCheckContentSecurityPolicy; - return new CSSParserContext( + return MakeGarbageCollected<CSSParserContext>( base_url_override, is_opaque_response_from_service_worker, charset, mode, match_mode, profile, referrer, document.IsHTMLDocument(), use_legacy_background_size_shorthand_behavior,
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.h b/third_party/blink/renderer/core/css/parser/css_parser_context.h index 3ce3e98..31df30f 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_context.h +++ b/third_party/blink/renderer/core/css/parser/css_parser_context.h
@@ -65,6 +65,19 @@ // This is used for workers, where we don't have a document. static CSSParserContext* Create(const ExecutionContext&); + CSSParserContext(const KURL& base_url, + bool is_opaque_response_from_service_worker, + const WTF::TextEncoding& charset, + CSSParserMode, + CSSParserMode match_mode, + SelectorProfile, + const Referrer&, + bool is_html_document, + bool use_legacy_background_size_shorthand_behavior, + SecureContextMode, + ContentSecurityPolicyDisposition, + const Document* use_counter_document); + bool operator==(const CSSParserContext&) const; bool operator!=(const CSSParserContext& other) const { return !(*this == other); @@ -121,19 +134,6 @@ void Trace(blink::Visitor*); private: - CSSParserContext(const KURL& base_url, - bool is_opaque_response_from_service_worker, - const WTF::TextEncoding& charset, - CSSParserMode, - CSSParserMode match_mode, - SelectorProfile, - const Referrer&, - bool is_html_document, - bool use_legacy_background_size_shorthand_behavior, - SecureContextMode, - ContentSecurityPolicyDisposition, - const Document* use_counter_document); - KURL base_url_; const bool is_opaque_response_from_service_worker_; WTF::TextEncoding charset_;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc index 83ad105..adc604a 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -258,8 +258,8 @@ CSSParserTokenStream stream(tokenizer); CSSParserImpl parser(context, style_sheet); if (defer_property_parsing == CSSDeferPropertyParsing::kYes) { - parser.lazy_state_ = - new CSSLazyParsingState(context, string, parser.style_sheet_); + parser.lazy_state_ = MakeGarbageCollected<CSSLazyParsingState>( + context, string, parser.style_sheet_); } ParseSheetResult result = ParseSheetResult::kSucceeded; bool first_rule_valid = parser.ConsumeRuleList( @@ -833,7 +833,8 @@ DCHECK(style_sheet_); return StyleRule::CreateLazy( std::move(selector_list), - new CSSLazyPropertyParserImpl(stream.Offset() - 1, lazy_state_)); + MakeGarbageCollected<CSSLazyPropertyParserImpl>(stream.Offset() - 1, + lazy_state_)); } ConsumeDeclarationList(stream, StyleRule::kStyle);
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h index 112aa5b..fe4ae0d 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -64,8 +64,10 @@ public: static StyleResolver* Create(Document& document) { - return new StyleResolver(document); + return MakeGarbageCollected<StyleResolver>(document); } + + explicit StyleResolver(Document&); ~StyleResolver(); void Dispose(); @@ -75,6 +77,8 @@ const ComputedStyle* layout_parent_style = nullptr, RuleMatchingBehavior = kMatchAllRules); + static scoped_refptr<ComputedStyle> InitialStyleForElement(Document&); + static AnimatableValue* CreateAnimatableValueSnapshot( Element&, const ComputedStyle& base_style, @@ -136,10 +140,6 @@ void Trace(blink::Visitor*); private: - explicit StyleResolver(Document&); - - static scoped_refptr<ComputedStyle> InitialStyleForElement(Document&); - // FIXME: This should probably go away, folded into FontBuilder. void UpdateFont(StyleResolverState&);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index c8b3879..f6c8774 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -111,9 +111,10 @@ }; static StyleEngine* Create(Document& document) { - return new StyleEngine(document); + return MakeGarbageCollected<StyleEngine>(document); } + StyleEngine(Document&); ~StyleEngine() override; const HeapVector<TraceWrapperMember<StyleSheet>>& @@ -363,7 +364,6 @@ void FontsNeedUpdate(FontSelector*) override; private: - StyleEngine(Document&); bool NeedsActiveStyleSheetUpdate() const { return all_tree_scopes_dirty_ || tree_scopes_removed_ || document_scope_dirty_ || dirty_tree_scopes_.size() ||
diff --git a/third_party/blink/renderer/core/css/style_media.h b/third_party/blink/renderer/core/css/style_media.h index f5385fe..546e6897 100644 --- a/third_party/blink/renderer/core/css/style_media.h +++ b/third_party/blink/renderer/core/css/style_media.h
@@ -41,15 +41,16 @@ USING_GARBAGE_COLLECTED_MIXIN(StyleMedia); public: - static StyleMedia* Create(LocalFrame* frame) { return new StyleMedia(frame); } + static StyleMedia* Create(LocalFrame* frame) { + return MakeGarbageCollected<StyleMedia>(frame); + } + + explicit StyleMedia(LocalFrame*); AtomicString type() const; bool matchMedium(const String&) const; void Trace(blink::Visitor*) override; - - private: - explicit StyleMedia(LocalFrame*); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h index 7a06d7b..ff8cf27 100644 --- a/third_party/blink/renderer/core/css/style_rule.h +++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -100,13 +100,18 @@ // Adopts the selector list static StyleRule* Create(CSSSelectorList selector_list, CSSPropertyValueSet* properties) { - return new StyleRule(std::move(selector_list), properties); + return MakeGarbageCollected<StyleRule>(std::move(selector_list), + properties); } static StyleRule* CreateLazy(CSSSelectorList selector_list, CSSLazyPropertyParser* lazy_property_parser) { - return new StyleRule(std::move(selector_list), lazy_property_parser); + return MakeGarbageCollected<StyleRule>(std::move(selector_list), + lazy_property_parser); } + StyleRule(CSSSelectorList, CSSPropertyValueSet*); + StyleRule(CSSSelectorList, CSSLazyPropertyParser*); + StyleRule(const StyleRule&); ~StyleRule(); const CSSSelectorList& SelectorList() const { return selector_list_; } @@ -117,7 +122,7 @@ selector_list_ = std::move(selectors); } - StyleRule* Copy() const { return new StyleRule(*this); } + StyleRule* Copy() const { return MakeGarbageCollected<StyleRule>(*this); } static unsigned AverageSizeInBytes(); @@ -131,10 +136,6 @@ friend class CSSLazyParsingTest; bool HasParsedProperties() const; - StyleRule(CSSSelectorList, CSSPropertyValueSet*); - StyleRule(CSSSelectorList, CSSLazyPropertyParser*); - StyleRule(const StyleRule&); - // Whether or not we should consider this for matching rules. Usually we try // to avoid considering empty property sets, as an optimization. This is // not possible for lazy properties, which always need to be considered. The @@ -154,22 +155,23 @@ class CORE_EXPORT StyleRuleFontFace : public StyleRuleBase { public: static StyleRuleFontFace* Create(CSSPropertyValueSet* properties) { - return new StyleRuleFontFace(properties); + return MakeGarbageCollected<StyleRuleFontFace>(properties); } + StyleRuleFontFace(CSSPropertyValueSet*); + StyleRuleFontFace(const StyleRuleFontFace&); ~StyleRuleFontFace(); const CSSPropertyValueSet& Properties() const { return *properties_; } MutableCSSPropertyValueSet& MutableProperties(); - StyleRuleFontFace* Copy() const { return new StyleRuleFontFace(*this); } + StyleRuleFontFace* Copy() const { + return MakeGarbageCollected<StyleRuleFontFace>(*this); + } void TraceAfterDispatch(blink::Visitor*); private: - StyleRuleFontFace(CSSPropertyValueSet*); - StyleRuleFontFace(const StyleRuleFontFace&); - Member<CSSPropertyValueSet> properties_; // Cannot be null. }; @@ -178,9 +180,12 @@ // Adopts the selector list static StyleRulePage* Create(CSSSelectorList selector_list, CSSPropertyValueSet* properties) { - return new StyleRulePage(std::move(selector_list), properties); + return MakeGarbageCollected<StyleRulePage>(std::move(selector_list), + properties); } + StyleRulePage(CSSSelectorList, CSSPropertyValueSet*); + StyleRulePage(const StyleRulePage&); ~StyleRulePage(); const CSSSelector* Selector() const { return selector_list_.First(); } @@ -191,14 +196,13 @@ selector_list_ = std::move(selectors); } - StyleRulePage* Copy() const { return new StyleRulePage(*this); } + StyleRulePage* Copy() const { + return MakeGarbageCollected<StyleRulePage>(*this); + } void TraceAfterDispatch(blink::Visitor*); private: - StyleRulePage(CSSSelectorList, CSSPropertyValueSet*); - StyleRulePage(const StyleRulePage&); - Member<CSSPropertyValueSet> properties_; // Cannot be null. CSSSelectorList selector_list_; }; @@ -244,20 +248,22 @@ static StyleRuleMedia* Create( scoped_refptr<MediaQuerySet> media, HeapVector<Member<StyleRuleBase>>& adopt_rules) { - return new StyleRuleMedia(media, adopt_rules); + return MakeGarbageCollected<StyleRuleMedia>(media, adopt_rules); } - MediaQuerySet* MediaQueries() const { return media_queries_.get(); } - - StyleRuleMedia* Copy() const { return new StyleRuleMedia(*this); } - - void TraceAfterDispatch(blink::Visitor*); - - private: StyleRuleMedia(scoped_refptr<MediaQuerySet>, HeapVector<Member<StyleRuleBase>>& adopt_rules); StyleRuleMedia(const StyleRuleMedia&); + MediaQuerySet* MediaQueries() const { return media_queries_.get(); } + + StyleRuleMedia* Copy() const { + return MakeGarbageCollected<StyleRuleMedia>(*this); + } + + void TraceAfterDispatch(blink::Visitor*); + + private: scoped_refptr<MediaQuerySet> media_queries_; }; @@ -267,23 +273,25 @@ const String& condition_text, bool condition_is_supported, HeapVector<Member<StyleRuleBase>>& adopt_rules) { - return new StyleRuleSupports(condition_text, condition_is_supported, - adopt_rules); + return MakeGarbageCollected<StyleRuleSupports>( + condition_text, condition_is_supported, adopt_rules); } + StyleRuleSupports(const String& condition_text, + bool condition_is_supported, + HeapVector<Member<StyleRuleBase>>& adopt_rules); + StyleRuleSupports(const StyleRuleSupports&); + bool ConditionIsSupported() const { return condition_is_supported_; } - StyleRuleSupports* Copy() const { return new StyleRuleSupports(*this); } + StyleRuleSupports* Copy() const { + return MakeGarbageCollected<StyleRuleSupports>(*this); + } void TraceAfterDispatch(blink::Visitor* visitor) { StyleRuleCondition::TraceAfterDispatch(visitor); } private: - StyleRuleSupports(const String& condition_text, - bool condition_is_supported, - HeapVector<Member<StyleRuleBase>>& adopt_rules); - StyleRuleSupports(const StyleRuleSupports&); - String condition_text_; bool condition_is_supported_; }; @@ -291,35 +299,39 @@ class StyleRuleViewport : public StyleRuleBase { public: static StyleRuleViewport* Create(CSSPropertyValueSet* properties) { - return new StyleRuleViewport(properties); + return MakeGarbageCollected<StyleRuleViewport>(properties); } + StyleRuleViewport(CSSPropertyValueSet*); + StyleRuleViewport(const StyleRuleViewport&); ~StyleRuleViewport(); const CSSPropertyValueSet& Properties() const { return *properties_; } MutableCSSPropertyValueSet& MutableProperties(); - StyleRuleViewport* Copy() const { return new StyleRuleViewport(*this); } + StyleRuleViewport* Copy() const { + return MakeGarbageCollected<StyleRuleViewport>(*this); + } void TraceAfterDispatch(blink::Visitor*); private: - StyleRuleViewport(CSSPropertyValueSet*); - StyleRuleViewport(const StyleRuleViewport&); - Member<CSSPropertyValueSet> properties_; // Cannot be null }; // This should only be used within the CSS Parser class StyleRuleCharset : public StyleRuleBase { public: - static StyleRuleCharset* Create() { return new StyleRuleCharset(); } + static StyleRuleCharset* Create() { + return MakeGarbageCollected<StyleRuleCharset>(); + } + + StyleRuleCharset() : StyleRuleBase(kCharset) {} void TraceAfterDispatch(blink::Visitor* visitor) { StyleRuleBase::TraceAfterDispatch(visitor); } private: - StyleRuleCharset() : StyleRuleBase(kCharset) {} }; #define DEFINE_STYLE_RULE_TYPE_CASTS(Type) \
diff --git a/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h b/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h index 618b296..255798de 100644 --- a/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h +++ b/third_party/blink/renderer/core/css/style_rule_css_style_declaration.h
@@ -39,17 +39,18 @@ static StyleRuleCSSStyleDeclaration* Create( MutableCSSPropertyValueSet& property_set, CSSRule* parent_rule) { - return new StyleRuleCSSStyleDeclaration(property_set, parent_rule); + return MakeGarbageCollected<StyleRuleCSSStyleDeclaration>(property_set, + parent_rule); } + StyleRuleCSSStyleDeclaration(MutableCSSPropertyValueSet&, CSSRule*); + ~StyleRuleCSSStyleDeclaration() override; + void Reattach(MutableCSSPropertyValueSet&); void Trace(blink::Visitor*) override; protected: - StyleRuleCSSStyleDeclaration(MutableCSSPropertyValueSet&, CSSRule*); - ~StyleRuleCSSStyleDeclaration() override; - CSSStyleSheet* ParentStyleSheet() const override; CSSRule* parentRule() const override { return parent_rule_; }
diff --git a/third_party/blink/renderer/core/css/style_rule_import.cc b/third_party/blink/renderer/core/css/style_rule_import.cc index 63d4ff1..c53f603 100644 --- a/third_party/blink/renderer/core/css/style_rule_import.cc +++ b/third_party/blink/renderer/core/css/style_rule_import.cc
@@ -34,14 +34,14 @@ StyleRuleImport* StyleRuleImport::Create(const String& href, scoped_refptr<MediaQuerySet> media) { - return new StyleRuleImport(href, media); + return MakeGarbageCollected<StyleRuleImport>(href, media); } StyleRuleImport::StyleRuleImport(const String& href, scoped_refptr<MediaQuerySet> media) : StyleRuleBase(kImport), parent_style_sheet_(nullptr), - style_sheet_client_(new ImportedStyleSheetClient(this)), + style_sheet_client_(MakeGarbageCollected<ImportedStyleSheetClient>(this)), str_href_(href), media_queries_(media), loading_(false) {
diff --git a/third_party/blink/renderer/core/css/style_rule_import.h b/third_party/blink/renderer/core/css/style_rule_import.h index 4e90a9c..0e21894 100644 --- a/third_party/blink/renderer/core/css/style_rule_import.h +++ b/third_party/blink/renderer/core/css/style_rule_import.h
@@ -38,6 +38,7 @@ static StyleRuleImport* Create(const String& href, scoped_refptr<MediaQuerySet>); + StyleRuleImport(const String& href, scoped_refptr<MediaQuerySet>); ~StyleRuleImport(); StyleSheetContents* ParentStyleSheet() const { return parent_style_sheet_; } @@ -89,8 +90,6 @@ void NotifyFinished(Resource*); - StyleRuleImport(const String& href, scoped_refptr<MediaQuerySet>); - void Dispose(); Member<StyleSheetContents> parent_style_sheet_;
diff --git a/third_party/blink/renderer/core/css/style_rule_keyframe.h b/third_party/blink/renderer/core/css/style_rule_keyframe.h index 0f33b880..bf0ac2f38 100644 --- a/third_party/blink/renderer/core/css/style_rule_keyframe.h +++ b/third_party/blink/renderer/core/css/style_rule_keyframe.h
@@ -17,9 +17,11 @@ public: static StyleRuleKeyframe* Create(std::unique_ptr<Vector<double>> keys, CSSPropertyValueSet* properties) { - return new StyleRuleKeyframe(std::move(keys), properties); + return MakeGarbageCollected<StyleRuleKeyframe>(std::move(keys), properties); } + StyleRuleKeyframe(std::unique_ptr<Vector<double>>, CSSPropertyValueSet*); + // Exposed to JavaScript. String KeyText() const; bool SetKeyText(const String&); @@ -35,8 +37,6 @@ void TraceAfterDispatch(blink::Visitor*); private: - StyleRuleKeyframe(std::unique_ptr<Vector<double>>, CSSPropertyValueSet*); - Member<CSSPropertyValueSet> properties_; Vector<double> keys_; };
diff --git a/third_party/blink/renderer/core/css/style_rule_namespace.h b/third_party/blink/renderer/core/css/style_rule_namespace.h index 8a0208b..bebb5e01 100644 --- a/third_party/blink/renderer/core/css/style_rule_namespace.h +++ b/third_party/blink/renderer/core/css/style_rule_namespace.h
@@ -14,11 +14,14 @@ class StyleRuleNamespace final : public StyleRuleBase { public: static StyleRuleNamespace* Create(AtomicString prefix, AtomicString uri) { - return new StyleRuleNamespace(prefix, uri); + return MakeGarbageCollected<StyleRuleNamespace>(prefix, uri); } + StyleRuleNamespace(AtomicString prefix, AtomicString uri) + : StyleRuleBase(kNamespace), prefix_(prefix), uri_(uri) {} + StyleRuleNamespace* Copy() const { - return new StyleRuleNamespace(prefix_, uri_); + return MakeGarbageCollected<StyleRuleNamespace>(prefix_, uri_); } AtomicString Prefix() const { return prefix_; } @@ -29,9 +32,6 @@ } private: - StyleRuleNamespace(AtomicString prefix, AtomicString uri) - : StyleRuleBase(kNamespace), prefix_(prefix), uri_(uri) {} - AtomicString prefix_; AtomicString uri_; };
diff --git a/third_party/blink/renderer/core/css/style_sheet_collection.h b/third_party/blink/renderer/core/css/style_sheet_collection.h index b8fd00326..bc47cfb4 100644 --- a/third_party/blink/renderer/core/css/style_sheet_collection.h +++ b/third_party/blink/renderer/core/css/style_sheet_collection.h
@@ -50,7 +50,11 @@ friend class ActiveDocumentStyleSheetCollector; friend class ImportedDocumentStyleSheetCollector; - static StyleSheetCollection* Create() { return new StyleSheetCollection; } + static StyleSheetCollection* Create() { + return MakeGarbageCollected<StyleSheetCollection>(); + } + + StyleSheetCollection(); const ActiveStyleSheetVector& ActiveAuthorStyleSheets() const { return active_author_style_sheets_; @@ -74,8 +78,6 @@ void Dispose(); protected: - StyleSheetCollection(); - HeapVector<TraceWrapperMember<StyleSheet>> style_sheets_for_style_sheet_list_; ActiveStyleSheetVector active_author_style_sheets_; bool sheet_list_dirty_ = true;
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.cc b/third_party/blink/renderer/core/css/style_sheet_contents.cc index 38d11f45..540ee7c 100644 --- a/third_party/blink/renderer/core/css/style_sheet_contents.cc +++ b/third_party/blink/renderer/core/css/style_sheet_contents.cc
@@ -332,8 +332,9 @@ void StyleSheetContents::ParseAuthorStyleSheet( const CSSStyleSheetResource* cached_style_sheet, const SecurityOrigin* security_origin) { - TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", - InspectorParseAuthorStyleSheetEvent::Data(cached_style_sheet)); + TRACE_EVENT1( + "blink,devtools.timeline", "ParseAuthorStyleSheet", "data", + inspector_parse_author_style_sheet_event::Data(cached_style_sheet)); TimeTicks start_time = CurrentTimeTicks(); bool is_same_origin_request =
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.h b/third_party/blink/renderer/core/css/style_sheet_contents.h index acf6156..81e5155 100644 --- a/third_party/blink/renderer/core/css/style_sheet_contents.h +++ b/third_party/blink/renderer/core/css/style_sheet_contents.h
@@ -50,20 +50,27 @@ : public GarbageCollectedFinalized<StyleSheetContents> { public: static StyleSheetContents* Create(const CSSParserContext* context) { - return new StyleSheetContents(nullptr, String(), context); + return MakeGarbageCollected<StyleSheetContents>(nullptr, String(), context); } static StyleSheetContents* Create(const String& original_url, const CSSParserContext* context) { - return new StyleSheetContents(nullptr, original_url, context); + return MakeGarbageCollected<StyleSheetContents>(nullptr, original_url, + context); } static StyleSheetContents* Create(StyleRuleImport* owner_rule, const String& original_url, const CSSParserContext* context) { - return new StyleSheetContents(owner_rule, original_url, context); + return MakeGarbageCollected<StyleSheetContents>(owner_rule, original_url, + context); } static const Document* SingleOwnerDocument(const StyleSheetContents*); + StyleSheetContents(StyleRuleImport* owner_rule, + const String& original_url, + const CSSParserContext*); + StyleSheetContents(const StyleSheetContents&); + StyleSheetContents() = delete; ~StyleSheetContents(); const CSSParserContext* ParserContext() const { return parser_context_; } @@ -174,7 +181,9 @@ bool WrapperInsertRule(StyleRuleBase*, unsigned index); bool WrapperDeleteRule(unsigned index); - StyleSheetContents* Copy() const { return new StyleSheetContents(*this); } + StyleSheetContents* Copy() const { + return MakeGarbageCollected<StyleSheetContents>(*this); + } void RegisterClient(CSSStyleSheet*); void UnregisterClient(CSSStyleSheet*); @@ -214,11 +223,6 @@ void Trace(blink::Visitor*); private: - StyleSheetContents(StyleRuleImport* owner_rule, - const String& original_url, - const CSSParserContext*); - StyleSheetContents(const StyleSheetContents&); - StyleSheetContents() = delete; StyleSheetContents& operator=(const StyleSheetContents&) = delete; void NotifyRemoveFontFaceRule(const StyleRuleFontFace*);
diff --git a/third_party/blink/renderer/core/css/style_sheet_list.cc b/third_party/blink/renderer/core/css/style_sheet_list.cc index 58d4fab2f..2990d6a 100644 --- a/third_party/blink/renderer/core/css/style_sheet_list.cc +++ b/third_party/blink/renderer/core/css/style_sheet_list.cc
@@ -31,7 +31,7 @@ StyleSheetList* StyleSheetList::Create() { DCHECK(RuntimeEnabledFeatures::ConstructableStylesheetsEnabled()); - return new StyleSheetList(); + return MakeGarbageCollected<StyleSheetList>(); } StyleSheetList* StyleSheetList::Create( @@ -41,7 +41,7 @@ exception_state.ThrowTypeError("Illegal constructor"); return nullptr; } - return new StyleSheetList(style_sheet_vector); + return MakeGarbageCollected<StyleSheetList>(style_sheet_vector); } StyleSheetList::StyleSheetList(
diff --git a/third_party/blink/renderer/core/css/style_sheet_list.h b/third_party/blink/renderer/core/css/style_sheet_list.h index 3ec4f37a4..4533e7c 100644 --- a/third_party/blink/renderer/core/css/style_sheet_list.h +++ b/third_party/blink/renderer/core/css/style_sheet_list.h
@@ -42,9 +42,13 @@ ExceptionState&); static StyleSheetList* Create(TreeScope* tree_scope) { - return new StyleSheetList(tree_scope); + return MakeGarbageCollected<StyleSheetList>(tree_scope); } + explicit StyleSheetList(const HeapVector<Member<CSSStyleSheet>>&); + explicit StyleSheetList(TreeScope*); + StyleSheetList() {} + unsigned length(); StyleSheet* item(unsigned index); @@ -59,9 +63,6 @@ void Trace(blink::Visitor*) override; private: - explicit StyleSheetList(const HeapVector<Member<CSSStyleSheet>>&); - explicit StyleSheetList(TreeScope*); - StyleSheetList() {} const HeapVector<TraceWrapperMember<StyleSheet>>& StyleSheets() const; Member<TreeScope> tree_scope_;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 8069d99f..4b5a31e 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1951,7 +1951,7 @@ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScheduleStyleRecalculation", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorRecalculateStylesEvent::Data(GetFrame())); + inspector_recalculate_styles_event::Data(GetFrame())); ++style_version_; } @@ -2225,7 +2225,7 @@ CHECK(Lifecycle().StateAllowsTreeMutations()); TRACE_EVENT_BEGIN1("blink,devtools.timeline", "UpdateLayoutTree", "beginData", - InspectorRecalculateStylesEvent::Data(GetFrame())); + inspector_recalculate_styles_event::Data(GetFrame())); unsigned start_element_count = GetStyleEngine().StyleForElementCount(); @@ -6108,7 +6108,7 @@ TRACE_EVENT_INSTANT1("devtools.timeline", "MarkDOMContent", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorMarkLoadEvent::Data(frame)); + inspector_mark_load_event::Data(frame)); probe::domContentLoadedEventFired(frame); frame->GetIdlenessDetector()->DomContentLoadedEventFired(); } @@ -7701,7 +7701,8 @@ (disposition == mojom::FeaturePolicyDisposition::kReport ? "report" : "enforce"), SourceLocation::Capture()); - Report* report = new Report("feature-policy", Url().GetString(), body); + Report* report = + new Report("feature-policy-violation", Url().GetString(), body); ReportingContext::From(this)->QueueReport(report); bool is_null;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 303805fa..54a6c817 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2145,7 +2145,8 @@ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() && hasAttribute(html_names::kInvisibleAttr)) { - auto style = ComputedStyle::Create(); + auto style = + GetDocument().GetStyleResolver()->InitialStyleForElement(GetDocument()); style->SetDisplay(EDisplay::kNone); return style; } @@ -2679,6 +2680,10 @@ return HasRareData() && GetElementRareData()->DidAttachInternals(); } +ElementInternals& Element::EnsureElementInternals() { + return EnsureElementRareData().EnsureElementInternals(ToHTMLElement(*this)); +} + ShadowRoot* Element::createShadowRoot(ExceptionState& exception_state) { if (ShadowRoot* root = GetShadowRoot()) { if (root->IsUserAgent()) {
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 110d7c9..bb30ec1d 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -59,6 +59,7 @@ class Document; class DisplayLockContext; class ElementAnimations; +class ElementInternals; class ElementIntersectionObserverData; class ElementRareData; class ExceptionState; @@ -810,6 +811,7 @@ const AtomicString& IsValue() const; void SetDidAttachInternals(); bool DidAttachInternals() const; + ElementInternals& EnsureElementInternals(); bool ContainsFullScreenElement() const { return HasElementFlag(ElementFlags::kContainsFullScreenElement);
diff --git a/third_party/blink/renderer/core/dom/element_rare_data.cc b/third_party/blink/renderer/core/dom/element_rare_data.cc index 106d136..b3d84095 100644 --- a/third_party/blink/renderer/core/dom/element_rare_data.cc +++ b/third_party/blink/renderer/core/dom/element_rare_data.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h" +#include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/resize_observer/resize_observation.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -41,7 +42,7 @@ struct SameSizeAsElementRareData : NodeRareData { IntSize scroll_offset; void* pointers_or_strings[5]; - Member<void*> members[15]; + Member<void*> members[16]; bool flags[1]; }; @@ -94,6 +95,13 @@ return *resize_observer_data_; } +ElementInternals& ElementRareData::EnsureElementInternals(HTMLElement& target) { + if (element_internals_) + return *element_internals_; + element_internals_ = MakeGarbageCollected<ElementInternals>(target); + return *element_internals_; +} + void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) { visitor->Trace(dataset_); visitor->Trace(class_list_); @@ -108,6 +116,7 @@ visitor->Trace(display_lock_context_); visitor->Trace(v0_custom_element_definition_); visitor->Trace(custom_element_definition_); + visitor->Trace(element_internals_); visitor->Trace(intersection_observer_data_); visitor->Trace(resize_observer_data_); NodeRareData::TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/dom/element_rare_data.h b/third_party/blink/renderer/core/dom/element_rare_data.h index 8357f1a..5469573 100644 --- a/third_party/blink/renderer/core/dom/element_rare_data.h +++ b/third_party/blink/renderer/core/dom/element_rare_data.h
@@ -49,6 +49,7 @@ namespace blink { class Element; +class HTMLElement; class ResizeObservation; class ResizeObserver; @@ -157,6 +158,7 @@ const AtomicString& IsValue() const { return is_value_; } void SetDidAttachInternals() { did_attach_internals_ = true; } bool DidAttachInternals() const { return did_attach_internals_; } + ElementInternals& EnsureElementInternals(HTMLElement& target); AccessibleNode* GetAccessibleNode() const { return accessible_node_.Get(); } AccessibleNode* EnsureAccessibleNode(Element* owner_element) { @@ -231,6 +233,7 @@ Member<V0CustomElementDefinition> v0_custom_element_definition_; Member<CustomElementDefinition> custom_element_definition_; AtomicString is_value_; + TraceWrapperMember<ElementInternals> element_internals_; Member<PseudoElementData> pseudo_element_data_;
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc index d46dc15a..e217aa9 100644 --- a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc +++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -198,7 +198,7 @@ #endif DCHECK(event_->target()); TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", - InspectorEventDispatchEvent::Data(*event_)); + inspector_event_dispatch_event::Data(*event_)); EventDispatchHandlingState* pre_dispatch_event_handler_result = nullptr; if (DispatchEventPreProcess(activation_target, pre_dispatch_event_handler_result) ==
diff --git a/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc b/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc index d5f54e11..02b71b6 100644 --- a/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc +++ b/third_party/blink/renderer/core/dom/frame_request_callback_collection.cc
@@ -22,7 +22,7 @@ TRACE_EVENT_INSTANT1("devtools.timeline", "RequestAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); probe::AsyncTaskScheduledBreakable(context_, "requestAnimationFrame", callback); return id; @@ -36,7 +36,7 @@ callbacks_.EraseAt(i); TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); return; } } @@ -46,7 +46,7 @@ callback); TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorAnimationFrameEvent::Data(context_, id)); + inspector_animation_frame_event::Data(context_, id)); callback->SetIsCancelled(true); // will be removed at the end of executeCallbacks() return; @@ -74,7 +74,7 @@ if (!callback->IsCancelled()) { TRACE_EVENT1( "devtools.timeline", "FireAnimationFrame", "data", - InspectorAnimationFrameEvent::Data(context_, callback->Id())); + inspector_animation_frame_event::Data(context_, callback->Id())); probe::AsyncTask async_task(context_, callback); probe::UserCallback probe(context_, "requestAnimationFrame", AtomicString(), true);
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index d9852b61..89e4681 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1194,7 +1194,7 @@ TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "StyleRecalcInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorStyleRecalcInvalidationTrackingEvent::Data(this, reason)); + inspector_style_recalc_invalidation_tracking_event::Data(this, reason)); StyleChangeType existing_change_type = GetStyleChangeType(); if (change_type > existing_change_type)
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc index 6933a7b..d9bb0cb 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
@@ -134,7 +134,7 @@ ScheduleCallback(std::move(callback_wrapper), timeout_millis); TRACE_EVENT_INSTANT1("devtools.timeline", "RequestIdleCallback", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorIdleCallbackRequestEvent::Data( + inspector_idle_callback_request_event::Data( GetExecutionContext(), id, timeout_millis)); return id; } @@ -160,7 +160,7 @@ TRACE_EVENT_INSTANT1( "devtools.timeline", "CancelIdleCallback", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorIdleCallbackCancelEvent::Data(GetExecutionContext(), id)); + inspector_idle_callback_cancel_event::Data(GetExecutionContext(), id)); if (!IsValidCallbackId(id)) return; @@ -211,7 +211,7 @@ TRACE_EVENT1( "devtools.timeline", "FireIdleCallback", "data", - InspectorIdleCallbackFireEvent::Data( + inspector_idle_callback_fire_event::Data( GetExecutionContext(), id, allotted_time.InMillisecondsF(), callback_type == IdleDeadline::CallbackType::kCalledByTimeout)); idle_task->invoke(IdleDeadline::Create(deadline, callback_type));
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc index 190110b5..61cf148b2 100644 --- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc +++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc
@@ -346,7 +346,7 @@ const WebAssociatedURLLoaderOptions& options) : client_(nullptr), options_(options), - observer_(new Observer(this, document)) {} + observer_(MakeGarbageCollected<Observer>(this, document)) {} WebAssociatedURLLoaderImpl::~WebAssociatedURLLoaderImpl() { Cancel();
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn index 020882f..7dd2850 100644 --- a/third_party/blink/renderer/core/frame/BUILD.gn +++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -44,8 +44,6 @@ "dom_window.h", "dom_window_base64.cc", "dom_window_base64.h", - "dom_window_timers.cc", - "dom_window_timers.h", "embedded_content_view.h", "event_handler_registry.cc", "event_handler_registry.h", @@ -184,5 +182,7 @@ "web_view_frame_widget.cc", "web_view_frame_widget.h", "window_event_handlers.h", + "window_or_worker_global_scope.cc", + "window_or_worker_global_scope.h", ] }
diff --git a/third_party/blink/renderer/core/frame/dom_timer.cc b/third_party/blink/renderer/core/frame/dom_timer.cc index 11a63103..92c91b4 100644 --- a/third_party/blink/renderer/core/frame/dom_timer.cc +++ b/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -69,7 +69,7 @@ DOMTimer* timer = context->Timers()->RemoveTimeoutByID(timeout_id); TRACE_EVENT_INSTANT1("devtools.timeline", "TimerRemove", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorTimerRemoveEvent::Data(context, timeout_id)); + inspector_timer_remove_event::Data(context, timeout_id)); // Eagerly unregister as ExecutionContext observer. if (timer) timer->ClearContext(); @@ -104,8 +104,8 @@ PauseIfNeeded(); TRACE_EVENT_INSTANT1("devtools.timeline", "TimerInstall", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorTimerInstallEvent::Data(context, timeout_id, - interval, single_shot)); + inspector_timer_install_event::Data( + context, timeout_id, interval, single_shot)); probe::AsyncTaskScheduledBreakable( context, single_shot ? "setTimeout" : "setInterval", this); } @@ -145,7 +145,7 @@ UserGestureIndicator gesture_indicator(std::move(user_gesture_token_)); TRACE_EVENT1("devtools.timeline", "TimerFire", "data", - InspectorTimerFireEvent::Data(context, timeout_id_)); + inspector_timer_fire_event::Data(context, timeout_id_)); const bool is_interval = !RepeatInterval().is_zero(); probe::UserCallback probe(context, is_interval ? "setInterval" : "setTimeout", g_null_atom, true);
diff --git a/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h b/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h index ebe0794f..d7b1b76 100644 --- a/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h +++ b/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h
@@ -14,21 +14,21 @@ DEFINE_WRAPPERTYPEINFO(); public: - FeaturePolicyViolationReportBody(const String& feature, + FeaturePolicyViolationReportBody(const String& feature_id, const String& message, const String& disposition, std::unique_ptr<SourceLocation> location) : MessageReportBody(message, std::move(location)), - feature_(feature), + feature_id_(feature_id), disposition_(disposition) {} - String feature() const { return feature_; } + String featureId() const { return feature_id_; } String disposition() const { return disposition_; } ~FeaturePolicyViolationReportBody() override = default; private: - const String feature_; + const String feature_id_; const String disposition_; };
diff --git a/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl b/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl index 968088b0..b5184ea 100644 --- a/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl +++ b/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://github.com/WICG/reporting/blob/master/EXPLAINER.md#reportingobserver---observing-reports-from-javascript +// https://wicg.github.io/feature-policy/#reporting [ NoInterfaceObject ] interface FeaturePolicyViolationReportBody : ReportBody { - readonly attribute DOMString feature; - readonly attribute DOMString disposition; - readonly attribute DOMString message; + readonly attribute DOMString featureId; readonly attribute DOMString? sourceFile; readonly attribute unsigned long? lineNumber; readonly attribute unsigned long? columnNumber; + readonly attribute DOMString disposition; + readonly attribute DOMString? message; };
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 72a4111..1ead7338 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1416,7 +1416,7 @@ TRACE_EVENT_INSTANT1("devtools.timeline", "MarkLoad", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorMarkLoadEvent::Data(GetFrame())); + inspector_mark_load_event::Data(GetFrame())); probe::loadEventFired(GetFrame()); } @@ -1432,7 +1432,7 @@ event.SetEventPhase(Event::kAtTarget); TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", - InspectorEventDispatchEvent::Data(event)); + inspector_event_dispatch_event::Data(event)); return FireEventListeners(event); }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 1d7958bd..b395cbd 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -788,7 +788,7 @@ Document* document = frame_->GetDocument(); TRACE_EVENT_BEGIN1("devtools.timeline", "Layout", "beginData", - InspectorLayoutEvent::BeginData(this)); + inspector_layout_event::BeginData(this)); probe::UpdateLayout probe(document); PerformPreLayoutTasks(); @@ -934,7 +934,7 @@ // FIXME: The notion of a single root for layout is no longer applicable. // Remove or update this code. crbug.com/460596 TRACE_EVENT_END1("devtools.timeline", "Layout", "endData", - InspectorLayoutEvent::EndData(root_for_this_layout)); + inspector_layout_event::EndData(root_for_this_layout)); probe::didChangeViewport(frame_.Get()); nested_layout_count_--; @@ -1360,7 +1360,7 @@ TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "ScrollInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorScrollInvalidationTrackingEvent::Data(*layout_object)); + inspector_scroll_invalidation_tracking_event::Data(*layout_object)); // If the fixed layer has a blur/drop-shadow filter applied on at least one // of its parents, we cannot scroll using the fast path, otherwise the @@ -1712,7 +1712,7 @@ return; TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorInvalidateLayoutEvent::Data(frame_.Get())); + inspector_invalidate_layout_event::Data(frame_.Get())); ClearLayoutSubtreeRootsAndMarkContainingBlocks(); @@ -1758,7 +1758,7 @@ } TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorInvalidateLayoutEvent::Data(frame_.Get())); + inspector_invalidate_layout_event::Data(frame_.Get())); } bool LocalFrameView::LayoutPending() const { @@ -2423,9 +2423,9 @@ { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorSetLayerTreeId::Data(frame_.Get())); + inspector_set_layer_tree_id::Data(frame_.Get())); TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", - InspectorUpdateLayerTreeEvent::Data(frame_.Get())); + inspector_update_layer_tree_event::Data(frame_.Get())); run_more_lifecycle_phases = RunCompositingLifecyclePhase(target_state); if (!run_more_lifecycle_phases)
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index 70afaaf6..254df48 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -234,4 +234,4 @@ Window implements GlobalEventHandlers; Window implements WindowBase64; Window implements WindowEventHandlers; -Window implements WindowTimers; +Window implements WindowOrWorkerGlobalScope;
diff --git a/third_party/blink/renderer/core/frame/dom_window_timers.cc b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc similarity index 83% rename from third_party/blink/renderer/core/frame/dom_window_timers.cc rename to third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc index 6f3f65c..a845b1a1 100644 --- a/third_party/blink/renderer/core/frame/dom_window_timers.cc +++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
@@ -30,7 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/core/frame/dom_window_timers.h" +#include "third_party/blink/renderer/core/frame/window_or_worker_global_scope.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h" @@ -80,11 +80,12 @@ return false; } -int DOMWindowTimers::setTimeout(ScriptState* script_state, - EventTarget& event_target, - const ScriptValue& handler, - int timeout, - const Vector<ScriptValue>& arguments) { +int WindowOrWorkerGlobalScope::setTimeout( + ScriptState* script_state, + EventTarget& event_target, + const ScriptValue& handler, + int timeout, + const Vector<ScriptValue>& arguments) { ExecutionContext* execution_context = event_target.GetExecutionContext(); if (!IsAllowed(script_state, execution_context, false, g_empty_string)) return 0; @@ -99,7 +100,7 @@ TimeDelta::FromMilliseconds(timeout), true); } -int DOMWindowTimers::setTimeout( +int WindowOrWorkerGlobalScope::setTimeout( ScriptState* script_state, EventTarget& event_target, const StringOrTrustedScript& string_or_trusted_script, @@ -118,11 +119,12 @@ arguments); } -int DOMWindowTimers::setTimeoutFromString(ScriptState* script_state, - EventTarget& event_target, - const String& handler, - int timeout, - const Vector<ScriptValue>&) { +int WindowOrWorkerGlobalScope::setTimeoutFromString( + ScriptState* script_state, + EventTarget& event_target, + const String& handler, + int timeout, + const Vector<ScriptValue>&) { ExecutionContext* execution_context = event_target.GetExecutionContext(); if (!IsAllowed(script_state, execution_context, true, handler)) return 0; @@ -141,11 +143,12 @@ TimeDelta::FromMilliseconds(timeout), true); } -int DOMWindowTimers::setInterval(ScriptState* script_state, - EventTarget& event_target, - const ScriptValue& handler, - int timeout, - const Vector<ScriptValue>& arguments) { +int WindowOrWorkerGlobalScope::setInterval( + ScriptState* script_state, + EventTarget& event_target, + const ScriptValue& handler, + int timeout, + const Vector<ScriptValue>& arguments) { ExecutionContext* execution_context = event_target.GetExecutionContext(); if (!IsAllowed(script_state, execution_context, false, g_empty_string)) return 0; @@ -155,7 +158,7 @@ TimeDelta::FromMilliseconds(timeout), false); } -int DOMWindowTimers::setInterval( +int WindowOrWorkerGlobalScope::setInterval( ScriptState* script_state, EventTarget& event_target, const StringOrTrustedScript& string_or_trusted_script, @@ -174,11 +177,12 @@ arguments); } -int DOMWindowTimers::setIntervalFromString(ScriptState* script_state, - EventTarget& event_target, - const String& handler, - int timeout, - const Vector<ScriptValue>&) { +int WindowOrWorkerGlobalScope::setIntervalFromString( + ScriptState* script_state, + EventTarget& event_target, + const String& handler, + int timeout, + const Vector<ScriptValue>&) { ExecutionContext* execution_context = event_target.GetExecutionContext(); if (!IsAllowed(script_state, execution_context, true, handler)) return 0; @@ -192,12 +196,14 @@ TimeDelta::FromMilliseconds(timeout), false); } -void DOMWindowTimers::clearTimeout(EventTarget& event_target, int timeout_id) { +void WindowOrWorkerGlobalScope::clearTimeout(EventTarget& event_target, + int timeout_id) { if (ExecutionContext* context = event_target.GetExecutionContext()) DOMTimer::RemoveByID(context, timeout_id); } -void DOMWindowTimers::clearInterval(EventTarget& event_target, int timeout_id) { +void WindowOrWorkerGlobalScope::clearInterval(EventTarget& event_target, + int timeout_id) { if (ExecutionContext* context = event_target.GetExecutionContext()) DOMTimer::RemoveByID(context, timeout_id); }
diff --git a/third_party/blink/renderer/core/frame/dom_window_timers.h b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h similarity index 91% rename from third_party/blink/renderer/core/frame/dom_window_timers.h rename to third_party/blink/renderer/core/frame/window_or_worker_global_scope.h index 634b86c..1ec0e79 100644 --- a/third_party/blink/renderer/core/frame/dom_window_timers.h +++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
@@ -30,8 +30,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_TIMERS_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_TIMERS_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_OR_WORKER_GLOBAL_SCOPE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_OR_WORKER_GLOBAL_SCOPE_H_ #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -45,8 +45,8 @@ class ScriptValue; class StringOrTrustedScript; -class DOMWindowTimers { - STATIC_ONLY(DOMWindowTimers); +class WindowOrWorkerGlobalScope { + STATIC_ONLY(WindowOrWorkerGlobalScope); public: static int setTimeout(ScriptState*, @@ -87,4 +87,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_TIMERS_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_OR_WORKER_GLOBAL_SCOPE_H_
diff --git a/third_party/blink/renderer/core/frame/window_timers.idl b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl similarity index 97% rename from third_party/blink/renderer/core/frame/window_timers.idl rename to third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl index d5183a8e..d99f659 100644 --- a/third_party/blink/renderer/core/frame/window_timers.idl +++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
@@ -29,11 +29,10 @@ // https://html.spec.whatwg.org/C/timers-and-user-prompts.html#timers [ - ImplementedAs=DOMWindowTimers, LegacyTreatAsPartialInterface, NoInterfaceObject, // Always used on target of 'implements' Exposed=(Window,Worker) -] interface WindowTimers { +] interface WindowOrWorkerGlobalScope { // TODO(yukishiino): Use TimerHandler (or Function at least) to implement // setTimeout and setInterval. // https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc index 34691d42..30979be 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc +++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/html/custom/custom_element_reaction.h" #include "third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h" #include "third_party/blink/renderer/core/html/custom/custom_element_upgrade_reaction.h" +#include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html_element_factory.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -30,12 +31,14 @@ CustomElementDefinition::CustomElementDefinition( const CustomElementDescriptor& descriptor, const HashSet<AtomicString>& observed_attributes, - const Vector<String>& disabled_features) + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag) : descriptor_(descriptor), observed_attributes_(observed_attributes), has_style_attribute_changed_callback_( observed_attributes.Contains(html_names::kStyleAttr.LocalName())), - disable_internals_(disabled_features.Contains(String("internals"))) {} + disable_internals_(disabled_features.Contains(String("internals"))), + is_form_associated_(form_association_flag == FormAssociationFlag::kYes) {} CustomElementDefinition::~CustomElementDefinition() = default; @@ -209,6 +212,9 @@ } element->SetCustomElementDefinition(this); + + if (IsFormAssociated()) + ToHTMLElement(element)->EnsureElementInternals().DidUpgrade(); AddDefaultStylesTo(*element); }
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.h b/third_party/blink/renderer/core/html/custom/custom_element_definition.h index 8a0ef82..f94bf3a 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_definition.h +++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.h
@@ -23,8 +23,14 @@ class Element; class ExceptionState; class HTMLElement; +class HTMLFormElement; class QualifiedName; +enum class FormAssociationFlag { + kNo, + kYes, +}; + class CORE_EXPORT CustomElementDefinition : public GarbageCollectedFinalized<CustomElementDefinition>, public NameClient { @@ -68,6 +74,8 @@ virtual bool HasAdoptedCallback() const = 0; bool HasAttributeChangedCallback(const QualifiedName&) const; bool HasStyleAttributeChangedCallback() const; + virtual bool HasFormAssociatedCallback() const = 0; + virtual bool HasDisabledStateChangedCallback() const = 0; virtual void RunConnectedCallback(Element*) = 0; virtual void RunDisconnectedCallback(Element*) = 0; @@ -78,6 +86,10 @@ const QualifiedName&, const AtomicString& old_value, const AtomicString& new_value) = 0; + virtual void RunFormAssociatedCallback(Element* element, + HTMLFormElement* nullable_form) = 0; + virtual void RunDisabledStateChangedCallback(Element* element, + bool is_disabled) = 0; void EnqueueUpgradeReaction(Element*, bool upgrade_invisible_elements = false); @@ -104,6 +116,7 @@ return !default_style_sheets_.IsEmpty(); } bool DisableInternals() const { return disable_internals_; } + bool IsFormAssociated() const { return is_form_associated_; } class CORE_EXPORT ConstructionStackScope final { STACK_ALLOCATED(); @@ -124,7 +137,8 @@ CustomElementDefinition(const CustomElementDescriptor&, const HashSet<AtomicString>& observed_attributes, - const Vector<String>& disabled_features); + const Vector<String>& disabled_features, + FormAssociationFlag form_association_flag); void AddDefaultStylesTo(Element&); @@ -142,6 +156,7 @@ bool has_style_attribute_changed_callback_; bool added_default_style_sheet_ = false; bool disable_internals_ = false; + bool is_form_associated_ = false; HeapVector<Member<CSSStyleSheet>> default_style_sheets_;
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.idl b/third_party/blink/renderer/core/html/custom/custom_element_registry.idl index 5f67775e..8061cb7 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_registry.idl +++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.idl
@@ -16,3 +16,6 @@ // Blink specific types. HTML standard does not explicitly define these types. callback CustomElementAdoptedCallback = void (Document oldOwner, Document newOwner); callback CustomElementAttributeChangedCallback = void (DOMString localName, DOMString? oldValue, DOMString? newValue, USVString? attrNamespace); +callback CustomElementFormAssociatedCallback = void (HTMLFormElement? form); +callback CustomElementDisabledStateChangedCallback = void (boolean disabled); +
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h index e17761a..9f6b8183 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h +++ b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
@@ -53,7 +53,8 @@ const Vector<String>& disabled_features) : CustomElementDefinition(descriptor, std::move(observed_attributes), - disabled_features) {} + disabled_features, + FormAssociationFlag::kNo) {} ~TestCustomElementDefinition() override = default; @@ -76,6 +77,8 @@ bool HasConnectedCallback() const override { return false; } bool HasDisconnectedCallback() const override { return false; } bool HasAdoptedCallback() const override { return false; } + bool HasFormAssociatedCallback() const override { return false; } + bool HasDisabledStateChangedCallback() const override { return false; } void RunConnectedCallback(Element*) override { NOTREACHED() << "definition does not have connected callback"; @@ -97,6 +100,14 @@ const AtomicString& new_value) override { NOTREACHED() << "definition does not have attribute changed callback"; } + void RunFormAssociatedCallback(Element* element, + HTMLFormElement* nullable_form) override { + NOTREACHED() << "definition does not have formAssociatedCallback"; + } + void RunDisabledStateChangedCallback(Element* element, + bool is_disabled) override { + NOTREACHED() << "definition does not have disabledStateChangedCallback"; + } DISALLOW_COPY_AND_ASSIGN(TestCustomElementDefinition); };
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.cc b/third_party/blink/renderer/core/html/custom/element_internals.cc index d5805d07..8898bb1 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.cc +++ b/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/html/custom/element_internals.h" +#include "third_party/blink/renderer/core/dom/node_lists_node_data.h" +#include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/html_element.h" namespace blink { @@ -12,7 +14,42 @@ void ElementInternals::Trace(Visitor* visitor) { visitor->Trace(target_); + ListedElement::Trace(visitor); ScriptWrappable::Trace(visitor); } +HTMLFormElement* ElementInternals::form() const { + return ListedElement::Form(); +} + +void ElementInternals::DidUpgrade() { + ContainerNode* parent = Target().parentNode(); + if (!parent) + return; + InsertedInto(*parent); + if (auto* owner_form = form()) { + if (auto* lists = owner_form->NodeLists()) + lists->InvalidateCaches(nullptr); + } + for (ContainerNode* node = parent; node; node = node->parentNode()) { + if (IsHTMLFieldSetElement(node)) { + // TODO(tkent): Invalidate only HTMLFormControlsCollections. + if (auto* lists = node->NodeLists()) + lists->InvalidateCaches(nullptr); + } + } +} + +bool ElementInternals::IsFormControlElement() const { + return false; +} + +bool ElementInternals::IsElementInternals() const { + return true; +} + +bool ElementInternals::IsEnumeratable() const { + return true; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.h b/third_party/blink/renderer/core/html/custom/element_internals.h index b3ab9537..c061d6a 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.h +++ b/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -5,24 +5,45 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_ELEMENT_INTERNALS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_ELEMENT_INTERNALS_H_ +#include "third_party/blink/renderer/core/html/forms/listed_element.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { class HTMLElement; -class ElementInternals : public ScriptWrappable { +class ElementInternals : public ScriptWrappable, public ListedElement { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(ElementInternals); public: ElementInternals(HTMLElement& target); void Trace(Visitor* visitor) override; + HTMLElement& Target() const { return *target_; } + void DidUpgrade(); + + // IDL attributes/operations + HTMLFormElement* form() const; + private: + // ListedElement overrides: + bool IsFormControlElement() const override; + bool IsElementInternals() const override; + bool IsEnumeratable() const override; + Member<HTMLElement> target_; DISALLOW_COPY_AND_ASSIGN(ElementInternals); }; +template <> +struct DowncastTraits<ElementInternals> { + static bool AllowFrom(const ListedElement& listed_element) { + return listed_element.IsElementInternals(); + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_ELEMENT_INTERNALS_H_
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.idl b/third_party/blink/renderer/core/html/custom/element_internals.idl index 539d9b02..82df900 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.idl +++ b/third_party/blink/renderer/core/html/custom/element_internals.idl
@@ -9,6 +9,7 @@ RuntimeEnabled=ElementInternals ] interface ElementInternals { - // TODO(tkent): Add operations. + // Attributes and operations for form-associated custom elements. + readonly attribute HTMLFormElement? form; };
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc index 1e4ab9d..471e80e6 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/html/forms/form_controller.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" #include "third_party/blink/renderer/core/html/forms/form_data_event.h" @@ -625,6 +626,8 @@ ListedElement* listed_element = nullptr; if (element.IsFormControlElement()) listed_element = ToHTMLFormControlElement(&element); + else if (element.IsFormAssociatedCustomElement()) + listed_element = &element.EnsureElementInternals(); else if (auto* object = ToHTMLObjectElementOrNull(element)) listed_element = object; else
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc index 12e1d4c7..6382a75 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/dom/id_target_observer.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" +#include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/validity_state.h" @@ -280,9 +281,15 @@ return false; } +bool ListedElement::IsElementInternals() const { + return false; +} + const HTMLElement& ToHTMLElement(const ListedElement& listed_element) { if (listed_element.IsFormControlElement()) return ToHTMLFormControlElement(listed_element); + if (listed_element.IsElementInternals()) + return To<ElementInternals>(listed_element).Target(); return ToHTMLObjectElementFromListedElement(listed_element); }
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.h b/third_party/blink/renderer/core/html/forms/listed_element.h index 0da13d5..be8c995 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.h +++ b/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -53,6 +53,7 @@ virtual bool IsFormControlElement() const = 0; virtual bool IsFormControlElementWithState() const; + virtual bool IsElementInternals() const; virtual bool IsEnumeratable() const = 0; // Returns the 'name' attribute value. If this element has no name @@ -89,6 +90,9 @@ virtual void setCustomValidity(const String&); void FormAttributeTargetChanged(); + void InsertedInto(ContainerNode&); + void RemovedFrom(ContainerNode&); + void DidMoveToNewDocument(Document& old_document); typedef HeapVector<Member<ListedElement>> List; @@ -97,10 +101,6 @@ protected: ListedElement(); - void InsertedInto(ContainerNode&); - void RemovedFrom(ContainerNode&); - void DidMoveToNewDocument(Document& old_document); - // FIXME: Remove usage of setForm. resetFormOwner should be enough, and // setForm is confusing. void SetForm(HTMLFormElement*);
diff --git a/third_party/blink/renderer/core/html/html_collection.cc b/third_party/blink/renderer/core/html/html_collection.cc index f6f929d4..ca67e17 100644 --- a/third_party/blink/renderer/core/html/html_collection.cc +++ b/third_party/blink/renderer/core/html/html_collection.cc
@@ -259,7 +259,9 @@ return element.HasTagName(kATag) && element.FastHasAttribute(kNameAttr); case kFormControls: DCHECK(IsHTMLFieldSetElement(html_collection.ownerNode())); - return IsHTMLObjectElement(element) || IsHTMLFormControlElement(element); + return IsHTMLObjectElement(element) || + IsHTMLFormControlElement(element) || + element.IsFormAssociatedCustomElement(); case kClassCollectionType: case kTagCollectionType: case kTagCollectionNSType:
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 44891e8c9..838de66 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1120,10 +1120,24 @@ InActiveDocument() && FastHasAttribute(kNonceAttr)) { setAttribute(kNonceAttr, g_empty_atom); } + if (IsFormAssociatedCustomElement()) + EnsureElementInternals().InsertedInto(insertion_point); return kInsertionDone; } +void HTMLElement::RemovedFrom(ContainerNode& insertion_point) { + Element::RemovedFrom(insertion_point); + if (IsFormAssociatedCustomElement()) + EnsureElementInternals().RemovedFrom(insertion_point); +} + +void HTMLElement::DidMoveToNewDocument(Document& old_document) { + if (IsFormAssociatedCustomElement()) + EnsureElementInternals().DidMoveToNewDocument(old_document); + Element::DidMoveToNewDocument(old_document); +} + void HTMLElement::AddHTMLLengthToStyle(MutableCSSPropertyValueSet* style, CSSPropertyID property_id, const String& value, @@ -1435,7 +1449,12 @@ return nullptr; } SetDidAttachInternals(); - return MakeGarbageCollected<ElementInternals>(*this); + return &EnsureElementInternals(); +} + +bool HTMLElement::IsFormAssociatedCustomElement() const { + return GetCustomElementState() == CustomElementState::kCustom && + GetCustomElementDefinition()->IsFormAssociated(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index d28661d..dae88c9 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -131,7 +131,8 @@ Element* unclosedOffsetParent(); ElementInternals* attachInternals(ExceptionState& exception_state); - virtual FormAssociated* ToFormAssociatedOrNull() { return nullptr; }; + virtual FormAssociated* ToFormAssociatedOrNull() { return nullptr; } + bool IsFormAssociatedCustomElement() const; protected: HTMLElement(const QualifiedName& tag_name, Document&, ConstructionType); @@ -165,6 +166,8 @@ void CalculateAndAdjustDirectionality(); InsertionNotificationRequest InsertedInto(ContainerNode&) override; + void RemovedFrom(ContainerNode& insertion_point) override; + void DidMoveToNewDocument(Document& old_document) override; private: String DebugNodeName() const final;
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc index 5320cada..09062dd51 100644 --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -2399,7 +2399,7 @@ void InspectorCSSAgent::SetCoverageEnabled(bool enabled) { if (enabled == !!tracker_) return; - tracker_ = enabled ? new StyleRuleUsageTracker() : nullptr; + tracker_ = enabled ? MakeGarbageCollected<StyleRuleUsageTracker>() : nullptr; for (Document* document : dom_agent_->Documents()) document->GetStyleEngine().SetRuleUsageTracker(tracker_);
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc index f6d6085..428913d 100644 --- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc +++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -188,7 +188,7 @@ if (current_rule_data_) current_rule_data_stack_.pop_back(); - CSSRuleSourceData* data = new CSSRuleSourceData(type); + CSSRuleSourceData* data = MakeGarbageCollected<CSSRuleSourceData>(type); data->rule_header_range.start = offset; current_rule_data_ = data; current_rule_data_stack_.push_back(data); @@ -1952,7 +1952,8 @@ const String& text = ElementStyleText(); CSSRuleSourceData* rule_source_data = nullptr; if (text.IsEmpty()) { - rule_source_data = new CSSRuleSourceData(StyleRule::kStyle); + rule_source_data = + MakeGarbageCollected<CSSRuleSourceData>(StyleRule::kStyle); rule_source_data->rule_body_range.start = 0; rule_source_data->rule_body_range.end = 0; } else {
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index 76dc0fa6..a2a44cb 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -113,7 +113,7 @@ TRACE_EVENT_INSTANT1( "devtools.timeline", "ResourceSendRequest", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorSendRequestEvent::Data(loader, identifier, frame, request)); + inspector_send_request_event::Data(loader, identifier, frame, request)); } void InspectorTraceEvents::DidReceiveResourceResponse( @@ -122,10 +122,10 @@ const ResourceResponse& response, Resource*) { LocalFrame* frame = loader ? loader->GetFrame() : nullptr; - TRACE_EVENT_INSTANT1( - "devtools.timeline", "ResourceReceiveResponse", TRACE_EVENT_SCOPE_THREAD, - "data", - InspectorReceiveResponseEvent::Data(loader, identifier, frame, response)); + TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", + TRACE_EVENT_SCOPE_THREAD, "data", + inspector_receive_response_event::Data( + loader, identifier, frame, response)); } void InspectorTraceEvents::DidReceiveData(unsigned long identifier, @@ -135,7 +135,7 @@ LocalFrame* frame = loader ? loader->GetFrame() : nullptr; TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceivedData", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorReceiveDataEvent::Data( + inspector_receive_data_event::Data( loader, identifier, frame, encoded_data_length)); probe::AsyncTask async_task(frame ? frame->GetDocument() : nullptr, AsyncId(identifier), "data"); @@ -150,9 +150,9 @@ LocalFrame* frame = loader ? loader->GetFrame() : nullptr; TRACE_EVENT_INSTANT1( "devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorResourceFinishEvent::Data(loader, identifier, finish_time, false, - encoded_data_length, - decoded_body_length)); + inspector_resource_finish_event::Data(loader, identifier, finish_time, + false, encoded_data_length, + decoded_body_length)); probe::AsyncTask async_task(frame ? frame->GetDocument() : nullptr, AsyncId(identifier)); } @@ -162,7 +162,7 @@ const ResourceError&) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorResourceFinishEvent::Data( + inspector_resource_finish_event::Data( loader, identifier, TimeTicks(), true, 0, 0)); } @@ -171,7 +171,7 @@ void InspectorTraceEvents::Did(const probe::ExecuteScript&) { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorUpdateCountersEvent::Data()); + inspector_update_counters_event::Data()); } void InspectorTraceEvents::Will(const probe::ParseHTML& probe) { @@ -188,7 +188,7 @@ InspectorParseHtmlEndData(probe.parser->LineNumber().ZeroBasedInt() - 1)); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorUpdateCountersEvent::Data()); + inspector_update_counters_event::Data()); } void InspectorTraceEvents::Will(const probe::CallFunction& probe) { @@ -196,7 +196,7 @@ return; TRACE_EVENT_BEGIN1( "devtools.timeline", "FunctionCall", "data", - InspectorFunctionCallEvent::Data(probe.context, probe.function)); + inspector_function_call_event::Data(probe.context, probe.function)); } void InspectorTraceEvents::Did(const probe::CallFunction& probe) { @@ -205,7 +205,7 @@ TRACE_EVENT_END0("devtools.timeline", "FunctionCall"); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorUpdateCountersEvent::Data()); + inspector_update_counters_event::Data()); } void InspectorTraceEvents::PaintTiming(Document* document, @@ -412,7 +412,7 @@ } // namespace -namespace InspectorScheduleStyleInvalidationTrackingEvent { +namespace inspector_schedule_style_invalidation_tracking_event { std::unique_ptr<TracedValue> FillCommonPart( ContainerNode& node, const InvalidationSet& invalidation_set, @@ -427,15 +427,16 @@ SourceLocation::Capture()->ToTracedValue(value.get(), "stackTrace"); return value; } -} // namespace InspectorScheduleStyleInvalidationTrackingEvent +} // namespace inspector_schedule_style_invalidation_tracking_event -const char InspectorScheduleStyleInvalidationTrackingEvent::kAttribute[] = +const char inspector_schedule_style_invalidation_tracking_event::kAttribute[] = "attribute"; -const char InspectorScheduleStyleInvalidationTrackingEvent::kClass[] = "class"; -const char InspectorScheduleStyleInvalidationTrackingEvent::kId[] = "id"; -const char InspectorScheduleStyleInvalidationTrackingEvent::kPseudo[] = +const char inspector_schedule_style_invalidation_tracking_event::kClass[] = + "class"; +const char inspector_schedule_style_invalidation_tracking_event::kId[] = "id"; +const char inspector_schedule_style_invalidation_tracking_event::kPseudo[] = "pseudo"; -const char InspectorScheduleStyleInvalidationTrackingEvent::kRuleSet[] = +const char inspector_schedule_style_invalidation_tracking_event::kRuleSet[] = "ruleset"; const char* ResourcePriorityString(ResourceLoadPriority priority) { @@ -463,7 +464,7 @@ } std::unique_ptr<TracedValue> -InspectorScheduleStyleInvalidationTrackingEvent::IdChange( +inspector_schedule_style_invalidation_tracking_event::IdChange( Element& element, const InvalidationSet& invalidation_set, const AtomicString& id) { @@ -474,7 +475,7 @@ } std::unique_ptr<TracedValue> -InspectorScheduleStyleInvalidationTrackingEvent::ClassChange( +inspector_schedule_style_invalidation_tracking_event::ClassChange( Element& element, const InvalidationSet& invalidation_set, const AtomicString& class_name) { @@ -485,7 +486,7 @@ } std::unique_ptr<TracedValue> -InspectorScheduleStyleInvalidationTrackingEvent::AttributeChange( +inspector_schedule_style_invalidation_tracking_event::AttributeChange( Element& element, const InvalidationSet& invalidation_set, const QualifiedName& attribute_name) { @@ -496,7 +497,7 @@ } std::unique_ptr<TracedValue> -InspectorScheduleStyleInvalidationTrackingEvent::PseudoChange( +inspector_schedule_style_invalidation_tracking_event::PseudoChange( Element& element, const InvalidationSet& invalidation_set, CSSSelector::PseudoType pseudo_type) { @@ -507,7 +508,7 @@ } std::unique_ptr<TracedValue> -InspectorScheduleStyleInvalidationTrackingEvent::RuleSetInvalidation( +inspector_schedule_style_invalidation_tracking_event::RuleSetInvalidation( ContainerNode& root_node, const InvalidationSet& invalidation_set) { std::unique_ptr<TracedValue> value = @@ -519,27 +520,25 @@ return ToHexString(&set); } -const char InspectorStyleInvalidatorInvalidateEvent:: +const char inspector_style_invalidator_invalidate_event:: kElementHasPendingInvalidationList[] = "Element has pending invalidation list"; -const char InspectorStyleInvalidatorInvalidateEvent::kInvalidateCustomPseudo[] = - "Invalidate custom pseudo element"; -const char InspectorStyleInvalidatorInvalidateEvent:: +const char + inspector_style_invalidator_invalidate_event::kInvalidateCustomPseudo[] = + "Invalidate custom pseudo element"; +const char inspector_style_invalidator_invalidate_event:: kInvalidationSetMatchedAttribute[] = "Invalidation set matched attribute"; +const char inspector_style_invalidator_invalidate_event:: + kInvalidationSetMatchedClass[] = "Invalidation set matched class"; const char - InspectorStyleInvalidatorInvalidateEvent::kInvalidationSetMatchedClass[] = - "Invalidation set matched class"; -const char - InspectorStyleInvalidatorInvalidateEvent::kInvalidationSetMatchedId[] = + inspector_style_invalidator_invalidate_event::kInvalidationSetMatchedId[] = "Invalidation set matched id"; -const char - InspectorStyleInvalidatorInvalidateEvent::kInvalidationSetMatchedTagName[] = - "Invalidation set matched tagName"; -const char - InspectorStyleInvalidatorInvalidateEvent::kInvalidationSetMatchedPart[] = - "Invalidation set matched part"; +const char inspector_style_invalidator_invalidate_event:: + kInvalidationSetMatchedTagName[] = "Invalidation set matched tagName"; +const char inspector_style_invalidator_invalidate_event:: + kInvalidationSetMatchedPart[] = "Invalidation set matched part"; -namespace InspectorStyleInvalidatorInvalidateEvent { +namespace inspector_style_invalidator_invalidate_event { std::unique_ptr<TracedValue> FillCommonPart(ContainerNode& node, const char* reason) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -549,16 +548,16 @@ value->SetString("reason", reason); return value; } -} // namespace InspectorStyleInvalidatorInvalidateEvent +} // namespace inspector_style_invalidator_invalidate_event -std::unique_ptr<TracedValue> InspectorStyleInvalidatorInvalidateEvent::Data( +std::unique_ptr<TracedValue> inspector_style_invalidator_invalidate_event::Data( Element& element, const char* reason) { return FillCommonPart(element, reason); } std::unique_ptr<TracedValue> -InspectorStyleInvalidatorInvalidateEvent::SelectorPart( +inspector_style_invalidator_invalidate_event::SelectorPart( Element& element, const char* reason, const InvalidationSet& invalidation_set, @@ -572,7 +571,7 @@ } std::unique_ptr<TracedValue> -InspectorStyleInvalidatorInvalidateEvent::InvalidationList( +inspector_style_invalidator_invalidate_event::InvalidationList( ContainerNode& node, const Vector<scoped_refptr<InvalidationSet>>& invalidation_list) { std::unique_ptr<TracedValue> value = @@ -585,7 +584,7 @@ } std::unique_ptr<TracedValue> -InspectorStyleRecalcInvalidationTrackingEvent::Data( +inspector_style_recalc_invalidation_tracking_event::Data( Node* node, const StyleChangeReasonForTracing& reason) { DCHECK(node); @@ -600,7 +599,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorLayoutEvent::BeginData( +std::unique_ptr<TracedValue> inspector_layout_event::BeginData( LocalFrameView* frame_view) { bool is_partial; unsigned needs_layout_objects; @@ -646,7 +645,7 @@ SetNodeInfo(value, node, id_field_name, name_field_name); } -std::unique_ptr<TracedValue> InspectorLayoutEvent::EndData( +std::unique_ptr<TracedValue> inspector_layout_event::EndData( LayoutObject* root_for_this_layout) { Vector<FloatQuad> quads; root_for_this_layout->AbsoluteQuads(quads); @@ -697,7 +696,7 @@ const char kDisplayLockCommitting[] = "Display lock committing"; } // namespace layout_invalidation_reason -std::unique_ptr<TracedValue> InspectorLayoutInvalidationTrackingEvent::Data( +std::unique_ptr<TracedValue> inspector_layout_invalidation_tracking_event::Data( const LayoutObject* layout_object, LayoutInvalidationReasonForTracing reason) { DCHECK(layout_object); @@ -710,7 +709,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintInvalidationTrackingEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_invalidation_tracking_event::Data( const LayoutObject& layout_object) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", @@ -723,7 +722,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorScrollInvalidationTrackingEvent::Data( +std::unique_ptr<TracedValue> inspector_scroll_invalidation_tracking_event::Data( const LayoutObject& layout_object) { static const char kScrollInvalidationReason[] = "Scroll with viewport-constrained element"; @@ -737,7 +736,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorChangeResourcePriorityEvent::Data( +std::unique_ptr<TracedValue> inspector_change_resource_priority_event::Data( DocumentLoader* loader, unsigned long identifier, const ResourceLoadPriority& load_priority) { @@ -749,7 +748,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorSendRequestEvent::Data( +std::unique_ptr<TracedValue> inspector_send_request_event::Data( DocumentLoader* loader, unsigned long identifier, LocalFrame* frame, @@ -802,7 +801,7 @@ } } // namespace -std::unique_ptr<TracedValue> InspectorReceiveResponseEvent::Data( +std::unique_ptr<TracedValue> inspector_receive_response_event::Data( DocumentLoader* loader, unsigned long identifier, LocalFrame* frame, @@ -827,7 +826,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorReceiveDataEvent::Data( +std::unique_ptr<TracedValue> inspector_receive_data_event::Data( DocumentLoader* loader, unsigned long identifier, LocalFrame* frame, @@ -841,7 +840,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorResourceFinishEvent::Data( +std::unique_ptr<TracedValue> inspector_resource_finish_event::Data( DocumentLoader* loader, unsigned long identifier, TimeTicks finish_time, @@ -875,7 +874,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorTimerInstallEvent::Data( +std::unique_ptr<TracedValue> inspector_timer_install_event::Data( ExecutionContext* context, int timer_id, TimeDelta timeout, @@ -887,7 +886,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorTimerRemoveEvent::Data( +std::unique_ptr<TracedValue> inspector_timer_remove_event::Data( ExecutionContext* context, int timer_id) { std::unique_ptr<TracedValue> value = GenericTimerData(context, timer_id); @@ -895,13 +894,13 @@ return value; } -std::unique_ptr<TracedValue> InspectorTimerFireEvent::Data( +std::unique_ptr<TracedValue> inspector_timer_fire_event::Data( ExecutionContext* context, int timer_id) { return GenericTimerData(context, timer_id); } -std::unique_ptr<TracedValue> InspectorAnimationFrameEvent::Data( +std::unique_ptr<TracedValue> inspector_animation_frame_event::Data( ExecutionContext* context, int callback_id) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -926,7 +925,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorIdleCallbackRequestEvent::Data( +std::unique_ptr<TracedValue> inspector_idle_callback_request_event::Data( ExecutionContext* context, int id, double timeout) { @@ -935,13 +934,13 @@ return value; } -std::unique_ptr<TracedValue> InspectorIdleCallbackCancelEvent::Data( +std::unique_ptr<TracedValue> inspector_idle_callback_cancel_event::Data( ExecutionContext* context, int id) { return GenericIdleCallbackEvent(context, id); } -std::unique_ptr<TracedValue> InspectorIdleCallbackFireEvent::Data( +std::unique_ptr<TracedValue> inspector_idle_callback_fire_event::Data( ExecutionContext* context, int id, double allotted_milliseconds, @@ -952,14 +951,14 @@ return value; } -std::unique_ptr<TracedValue> InspectorParseAuthorStyleSheetEvent::Data( +std::unique_ptr<TracedValue> inspector_parse_author_style_sheet_event::Data( const CSSStyleSheetResource* cached_style_sheet) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("styleSheetUrl", cached_style_sheet->Url().GetString()); return value; } -std::unique_ptr<TracedValue> InspectorXhrReadyStateChangeEvent::Data( +std::unique_ptr<TracedValue> inspector_xhr_ready_state_change_event::Data( ExecutionContext* context, XMLHttpRequest* request) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -971,7 +970,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorXhrLoadEvent::Data( +std::unique_ptr<TracedValue> inspector_xhr_load_event::Data( ExecutionContext* context, XMLHttpRequest* request) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1000,20 +999,22 @@ quad->SetP4(LocalCoordToFloatPoint(view, absolute.P4())); } -const char InspectorLayerInvalidationTrackingEvent:: +const char inspector_layer_invalidation_tracking_event:: kSquashingLayerGeometryWasUpdated[] = "Squashing layer geometry was updated"; -const char InspectorLayerInvalidationTrackingEvent::kAddedToSquashingLayer[] = - "The layer may have been added to an already-existing squashing layer"; const char - InspectorLayerInvalidationTrackingEvent::kRemovedFromSquashingLayer[] = + inspector_layer_invalidation_tracking_event::kAddedToSquashingLayer[] = + "The layer may have been added to an already-existing squashing layer"; +const char + inspector_layer_invalidation_tracking_event::kRemovedFromSquashingLayer[] = "Removed the layer from a squashing layer"; -const char InspectorLayerInvalidationTrackingEvent::kReflectionLayerChanged[] = - "Reflection layer change"; -const char InspectorLayerInvalidationTrackingEvent::kNewCompositedLayer[] = +const char + inspector_layer_invalidation_tracking_event::kReflectionLayerChanged[] = + "Reflection layer change"; +const char inspector_layer_invalidation_tracking_event::kNewCompositedLayer[] = "Assigned a new composited layer"; -std::unique_ptr<TracedValue> InspectorLayerInvalidationTrackingEvent::Data( +std::unique_ptr<TracedValue> inspector_layer_invalidation_tracking_event::Data( const PaintLayer* layer, const char* reason) { const LayoutObject& paint_invalidation_container = @@ -1027,7 +1028,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_event::Data( LayoutObject* layout_object, const LayoutRect& clip_rect, const GraphicsLayer* graphics_layer) { @@ -1070,19 +1071,21 @@ frame_data->SetString("parent", IdentifiersFactory::FrameId(parent)); } -std::unique_ptr<TracedValue> InspectorCommitLoadEvent::Data(LocalFrame* frame) { +std::unique_ptr<TracedValue> inspector_commit_load_event::Data( + LocalFrame* frame) { std::unique_ptr<TracedValue> frame_data = FrameEventData(frame); FillCommonFrameData(frame_data.get(), frame); return frame_data; } -std::unique_ptr<TracedValue> InspectorMarkLoadEvent::Data(LocalFrame* frame) { +std::unique_ptr<TracedValue> inspector_mark_load_event::Data( + LocalFrame* frame) { std::unique_ptr<TracedValue> frame_data = FrameEventData(frame); frame_data->SetString("frame", IdentifiersFactory::FrameId(frame)); return frame_data; } -std::unique_ptr<TracedValue> InspectorScrollLayerEvent::Data( +std::unique_ptr<TracedValue> inspector_scroll_layer_event::Data( LayoutObject* layout_object) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", @@ -1091,7 +1094,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorUpdateLayerTreeEvent::Data( +std::unique_ptr<TracedValue> inspector_update_layer_tree_event::Data( LocalFrame* frame) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", IdentifiersFactory::FrameId(frame)); @@ -1109,7 +1112,7 @@ } } // namespace -std::unique_ptr<TracedValue> InspectorEvaluateScriptEvent::Data( +std::unique_ptr<TracedValue> inspector_evaluate_script_event::Data( LocalFrame* frame, const String& url, const TextPosition& text_position) { @@ -1119,7 +1122,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorParseScriptEvent::Data( +std::unique_ptr<TracedValue> inspector_parse_script_event::Data( unsigned long identifier, const String& url) { String request_id = IdentifiersFactory::RequestId(nullptr, identifier); @@ -1129,7 +1132,7 @@ return value; } -InspectorCompileScriptEvent::V8CacheResult::ProduceResult::ProduceResult( +inspector_compile_script_event::V8CacheResult::ProduceResult::ProduceResult( v8::ScriptCompiler::CompileOptions produce_options, int cache_size) : produce_options(produce_options), cache_size(cache_size) { @@ -1137,7 +1140,7 @@ produce_options == v8::ScriptCompiler::kEagerCompile); } -InspectorCompileScriptEvent::V8CacheResult::ConsumeResult::ConsumeResult( +inspector_compile_script_event::V8CacheResult::ConsumeResult::ConsumeResult( v8::ScriptCompiler::CompileOptions consume_options, int cache_size, bool rejected) @@ -1147,13 +1150,13 @@ DCHECK_EQ(consume_options, v8::ScriptCompiler::kConsumeCodeCache); } -InspectorCompileScriptEvent::V8CacheResult::V8CacheResult( +inspector_compile_script_event::V8CacheResult::V8CacheResult( base::Optional<ProduceResult> produce_result, base::Optional<ConsumeResult> consume_result) : produce_result(std::move(produce_result)), consume_result(std::move(consume_result)) {} -std::unique_ptr<TracedValue> InspectorCompileScriptEvent::Data( +std::unique_ptr<TracedValue> inspector_compile_script_event::Data( const String& url, const TextPosition& text_position, const V8CacheResult& cache_result, @@ -1185,7 +1188,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorFunctionCallEvent::Data( +std::unique_ptr<TracedValue> inspector_function_call_event::Data( ExecutionContext* context, const v8::Local<v8::Function>& function) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1210,7 +1213,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintImageEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_image_event::Data( const LayoutImage& layout_image, const FloatRect& src_rect, const FloatRect& dest_rect) { @@ -1229,7 +1232,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintImageEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_image_event::Data( const LayoutObject& owning_layout_object, const StyleImage& style_image) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1239,7 +1242,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintImageEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_image_event::Data( Node* node, const StyleImage& style_image, const FloatRect& src_rect, @@ -1260,7 +1263,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorPaintImageEvent::Data( +std::unique_ptr<TracedValue> inspector_paint_image_event::Data( const LayoutObject* owning_layout_object, const ImageResourceContent& image_resource) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1275,7 +1278,7 @@ return heap_statistics.used_heap_size(); } -std::unique_ptr<TracedValue> InspectorUpdateCountersEvent::Data() { +std::unique_ptr<TracedValue> inspector_update_counters_event::Data() { std::unique_ptr<TracedValue> value = TracedValue::Create(); if (IsMainThread()) { value->SetInteger("documents", InstanceCounters::CounterValue( @@ -1290,7 +1293,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorInvalidateLayoutEvent::Data( +std::unique_ptr<TracedValue> inspector_invalidate_layout_event::Data( LocalFrame* frame) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", IdentifiersFactory::FrameId(frame)); @@ -1298,7 +1301,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorRecalculateStylesEvent::Data( +std::unique_ptr<TracedValue> inspector_recalculate_styles_event::Data( LocalFrame* frame) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", IdentifiersFactory::FrameId(frame)); @@ -1306,7 +1309,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorEventDispatchEvent::Data( +std::unique_ptr<TracedValue> inspector_event_dispatch_event::Data( const Event& event) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("type", event.type()); @@ -1314,7 +1317,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorTimeStampEvent::Data( +std::unique_ptr<TracedValue> inspector_time_stamp_event::Data( ExecutionContext* context, const String& message) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1324,7 +1327,8 @@ return value; } -std::unique_ptr<TracedValue> InspectorTracingSessionIdForWorkerEvent::Data( +std::unique_ptr<TracedValue> +inspector_tracing_session_id_for_worker_event::Data( const base::UnguessableToken& worker_devtools_token, const base::UnguessableToken& parent_devtools_token, const KURL& url, @@ -1339,7 +1343,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorTracingStartedInFrame::Data( +std::unique_ptr<TracedValue> inspector_tracing_started_in_frame::Data( const String& session_id, LocalFrame* frame) { std::unique_ptr<TracedValue> value = TracedValue::Create(); @@ -1359,7 +1363,8 @@ return value; } -std::unique_ptr<TracedValue> InspectorSetLayerTreeId::Data(LocalFrame* frame) { +std::unique_ptr<TracedValue> inspector_set_layer_tree_id::Data( + LocalFrame* frame) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", IdentifiersFactory::FrameId(frame)); WebLayerTreeView* layerTreeView = @@ -1369,7 +1374,7 @@ return value; } -std::unique_ptr<TracedValue> InspectorAnimationEvent::Data( +std::unique_ptr<TracedValue> inspector_animation_event::Data( const Animation& animation) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("id", String::Number(animation.SequenceNumber())); @@ -1384,14 +1389,14 @@ return value; } -std::unique_ptr<TracedValue> InspectorAnimationStateEvent::Data( +std::unique_ptr<TracedValue> inspector_animation_state_event::Data( const Animation& animation) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("state", animation.playState()); return value; } -std::unique_ptr<TracedValue> InspectorHitTestEvent::EndData( +std::unique_ptr<TracedValue> inspector_hit_test_event::EndData( const HitTestRequest& request, const HitTestLocation& location, const HitTestResult& result) { @@ -1413,7 +1418,8 @@ return value; } -std::unique_ptr<TracedValue> InspectorAsyncTask::Data(const StringView& name) { +std::unique_ptr<TracedValue> inspector_async_task::Data( + const StringView& name) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("name", name.ToString()); return value;
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/third_party/blink/renderer/core/inspector/inspector_trace_events.h index a89abe40..b52199f 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.h +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -126,12 +126,12 @@ DISALLOW_COPY_AND_ASSIGN(InspectorTraceEvents); }; -namespace InspectorLayoutEvent { +namespace inspector_layout_event { std::unique_ptr<TracedValue> BeginData(LocalFrameView*); std::unique_ptr<TracedValue> EndData(LayoutObject* root_for_this_layout); -} // namespace InspectorLayoutEvent +} // namespace inspector_layout_event -namespace InspectorScheduleStyleInvalidationTrackingEvent { +namespace inspector_schedule_style_invalidation_tracking_event { extern const char kAttribute[]; extern const char kClass[]; extern const char kId[]; @@ -152,23 +152,23 @@ CSSSelector::PseudoType); std::unique_ptr<TracedValue> RuleSetInvalidation(ContainerNode&, const InvalidationSet&); -} // namespace InspectorScheduleStyleInvalidationTrackingEvent +} // namespace inspector_schedule_style_invalidation_tracking_event #define TRACE_SCHEDULE_STYLE_INVALIDATION(element, invalidationSet, \ changeType, ...) \ TRACE_EVENT_INSTANT1( \ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), \ "ScheduleStyleInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", \ - InspectorScheduleStyleInvalidationTrackingEvent::changeType( \ + inspector_schedule_style_invalidation_tracking_event::changeType( \ (element), (invalidationSet), ##__VA_ARGS__)); -namespace InspectorStyleRecalcInvalidationTrackingEvent { +namespace inspector_style_recalc_invalidation_tracking_event { std::unique_ptr<TracedValue> Data(Node*, const StyleChangeReasonForTracing&); } String DescendantInvalidationSetToIdString(const InvalidationSet&); -namespace InspectorStyleInvalidatorInvalidateEvent { +namespace inspector_style_invalidator_invalidate_event { extern const char kElementHasPendingInvalidationList[]; extern const char kInvalidateCustomPseudo[]; extern const char kInvalidationSetMatchedAttribute[]; @@ -185,24 +185,24 @@ std::unique_ptr<TracedValue> InvalidationList( ContainerNode&, const Vector<scoped_refptr<InvalidationSet>>&); -} // namespace InspectorStyleInvalidatorInvalidateEvent +} // namespace inspector_style_invalidator_invalidate_event #define TRACE_STYLE_INVALIDATOR_INVALIDATION(element, reason) \ TRACE_EVENT_INSTANT1( \ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), \ "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, \ "data", \ - InspectorStyleInvalidatorInvalidateEvent::Data( \ - (element), (InspectorStyleInvalidatorInvalidateEvent::reason))) + inspector_style_invalidator_invalidate_event::Data( \ + (element), (inspector_style_invalidator_invalidate_event::reason))) -#define TRACE_STYLE_INVALIDATOR_INVALIDATION_SELECTORPART( \ - element, reason, invalidationSet, singleSelectorPart) \ - TRACE_EVENT_INSTANT1( \ - TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), \ - "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, \ - "data", \ - InspectorStyleInvalidatorInvalidateEvent::SelectorPart( \ - (element), (InspectorStyleInvalidatorInvalidateEvent::reason), \ +#define TRACE_STYLE_INVALIDATOR_INVALIDATION_SELECTORPART( \ + element, reason, invalidationSet, singleSelectorPart) \ + TRACE_EVENT_INSTANT1( \ + TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), \ + "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, \ + "data", \ + inspector_style_invalidator_invalidate_event::SelectorPart( \ + (element), (inspector_style_invalidator_invalidate_event::reason), \ (invalidationSet), (singleSelectorPart))) // From a web developer's perspective: what caused this layout? This is strictly @@ -249,47 +249,47 @@ // not depend on this value. typedef const char LayoutInvalidationReasonForTracing[]; -namespace InspectorLayoutInvalidationTrackingEvent { +namespace inspector_layout_invalidation_tracking_event { std::unique_ptr<TracedValue> CORE_EXPORT Data(const LayoutObject*, LayoutInvalidationReasonForTracing); } -namespace InspectorPaintInvalidationTrackingEvent { +namespace inspector_paint_invalidation_tracking_event { std::unique_ptr<TracedValue> Data(const LayoutObject&); } -namespace InspectorScrollInvalidationTrackingEvent { +namespace inspector_scroll_invalidation_tracking_event { std::unique_ptr<TracedValue> Data(const LayoutObject&); } -namespace InspectorChangeResourcePriorityEvent { +namespace inspector_change_resource_priority_event { std::unique_ptr<TracedValue> Data(DocumentLoader*, unsigned long identifier, const ResourceLoadPriority&); } -namespace InspectorSendRequestEvent { +namespace inspector_send_request_event { std::unique_ptr<TracedValue> Data(DocumentLoader*, unsigned long identifier, LocalFrame*, const ResourceRequest&); } -namespace InspectorReceiveResponseEvent { +namespace inspector_receive_response_event { std::unique_ptr<TracedValue> Data(DocumentLoader*, unsigned long identifier, LocalFrame*, const ResourceResponse&); } -namespace InspectorReceiveDataEvent { +namespace inspector_receive_data_event { std::unique_ptr<TracedValue> Data(DocumentLoader*, unsigned long identifier, LocalFrame*, int encoded_data_length); } -namespace InspectorResourceFinishEvent { +namespace inspector_resource_finish_event { std::unique_ptr<TracedValue> Data(DocumentLoader*, unsigned long identifier, TimeTicks finish_time, @@ -298,53 +298,53 @@ int64_t decoded_body_length); } -namespace InspectorTimerInstallEvent { +namespace inspector_timer_install_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int timer_id, TimeDelta timeout, bool single_shot); } -namespace InspectorTimerRemoveEvent { +namespace inspector_timer_remove_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int timer_id); } -namespace InspectorTimerFireEvent { +namespace inspector_timer_fire_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int timer_id); } -namespace InspectorIdleCallbackRequestEvent { +namespace inspector_idle_callback_request_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int id, double timeout); } -namespace InspectorIdleCallbackCancelEvent { +namespace inspector_idle_callback_cancel_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int id); } -namespace InspectorIdleCallbackFireEvent { +namespace inspector_idle_callback_fire_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int id, double allotted_milliseconds, bool timed_out); } -namespace InspectorAnimationFrameEvent { +namespace inspector_animation_frame_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, int callback_id); } -namespace InspectorParseAuthorStyleSheetEvent { +namespace inspector_parse_author_style_sheet_event { std::unique_ptr<TracedValue> Data(const CSSStyleSheetResource*); } -namespace InspectorXhrReadyStateChangeEvent { +namespace inspector_xhr_ready_state_change_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, XMLHttpRequest*); } -namespace InspectorXhrLoadEvent { +namespace inspector_xhr_load_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, XMLHttpRequest*); } -namespace InspectorLayerInvalidationTrackingEvent { +namespace inspector_layer_invalidation_tracking_event { extern const char kSquashingLayerGeometryWasUpdated[]; extern const char kAddedToSquashingLayer[]; extern const char kRemovedFromSquashingLayer[]; @@ -352,21 +352,21 @@ extern const char kNewCompositedLayer[]; std::unique_ptr<TracedValue> Data(const PaintLayer*, const char* reason); -} // namespace InspectorLayerInvalidationTrackingEvent +} // namespace inspector_layer_invalidation_tracking_event #define TRACE_LAYER_INVALIDATION(LAYER, REASON) \ TRACE_EVENT_INSTANT1( \ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), \ "LayerInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", \ - InspectorLayerInvalidationTrackingEvent::Data((LAYER), (REASON))); + inspector_layer_invalidation_tracking_event::Data((LAYER), (REASON))); -namespace InspectorPaintEvent { +namespace inspector_paint_event { std::unique_ptr<TracedValue> Data(LayoutObject*, const LayoutRect& clip_rect, const GraphicsLayer*); } -namespace InspectorPaintImageEvent { +namespace inspector_paint_image_event { std::unique_ptr<TracedValue> Data(const LayoutImage&, const FloatRect& src_rect, const FloatRect& dest_rect); @@ -377,35 +377,35 @@ const FloatRect& dest_rect); std::unique_ptr<TracedValue> Data(const LayoutObject*, const ImageResourceContent&); -} // namespace InspectorPaintImageEvent +} // namespace inspector_paint_image_event -namespace InspectorCommitLoadEvent { +namespace inspector_commit_load_event { std::unique_ptr<TracedValue> Data(LocalFrame*); } -namespace InspectorMarkLoadEvent { +namespace inspector_mark_load_event { std::unique_ptr<TracedValue> Data(LocalFrame*); } -namespace InspectorScrollLayerEvent { +namespace inspector_scroll_layer_event { std::unique_ptr<TracedValue> Data(LayoutObject*); } -namespace InspectorUpdateLayerTreeEvent { +namespace inspector_update_layer_tree_event { std::unique_ptr<TracedValue> Data(LocalFrame*); } -namespace InspectorEvaluateScriptEvent { +namespace inspector_evaluate_script_event { std::unique_ptr<TracedValue> Data(LocalFrame*, const String& url, const WTF::TextPosition&); } -namespace InspectorParseScriptEvent { +namespace inspector_parse_script_event { std::unique_ptr<TracedValue> Data(unsigned long identifier, const String& url); } -namespace InspectorCompileScriptEvent { +namespace inspector_compile_script_event { struct V8CacheResult { struct ProduceResult { @@ -434,34 +434,34 @@ const V8CacheResult&, bool streamed, ScriptStreamer::NotStreamingReason); -} // namespace InspectorCompileScriptEvent +} // namespace inspector_compile_script_event -namespace InspectorFunctionCallEvent { +namespace inspector_function_call_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, const v8::Local<v8::Function>&); } -namespace InspectorUpdateCountersEvent { +namespace inspector_update_counters_event { std::unique_ptr<TracedValue> Data(); } -namespace InspectorInvalidateLayoutEvent { +namespace inspector_invalidate_layout_event { std::unique_ptr<TracedValue> Data(LocalFrame*); } -namespace InspectorRecalculateStylesEvent { +namespace inspector_recalculate_styles_event { std::unique_ptr<TracedValue> Data(LocalFrame*); } -namespace InspectorEventDispatchEvent { +namespace inspector_event_dispatch_event { std::unique_ptr<TracedValue> Data(const Event&); } -namespace InspectorTimeStampEvent { +namespace inspector_time_stamp_event { std::unique_ptr<TracedValue> Data(ExecutionContext*, const String& message); } -namespace InspectorTracingSessionIdForWorkerEvent { +namespace inspector_tracing_session_id_for_worker_event { std::unique_ptr<TracedValue> Data( const base::UnguessableToken& worker_devtools_token, const base::UnguessableToken& parent_devtools_token, @@ -469,29 +469,29 @@ PlatformThreadId worker_thread_id); } -namespace InspectorTracingStartedInFrame { +namespace inspector_tracing_started_in_frame { std::unique_ptr<TracedValue> Data(const String& session_id, LocalFrame*); } -namespace InspectorSetLayerTreeId { +namespace inspector_set_layer_tree_id { std::unique_ptr<TracedValue> Data(LocalFrame* local_root); } -namespace InspectorAnimationEvent { +namespace inspector_animation_event { std::unique_ptr<TracedValue> Data(const Animation&); } -namespace InspectorAnimationStateEvent { +namespace inspector_animation_state_event { std::unique_ptr<TracedValue> Data(const Animation&); } -namespace InspectorHitTestEvent { +namespace inspector_hit_test_event { std::unique_ptr<TracedValue> EndData(const HitTestRequest&, const HitTestLocation&, const HitTestResult&); } -namespace InspectorAsyncTask { +namespace inspector_async_task { std::unique_ptr<TracedValue> Data(const StringView&); }
diff --git a/third_party/blink/renderer/core/inspector/thread_debugger.cc b/third_party/blink/renderer/core/inspector/thread_debugger.cc index 4c97d0fb6..e11b51a3 100644 --- a/third_party/blink/renderer/core/inspector/thread_debugger.cc +++ b/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -477,9 +477,9 @@ ExecutionContext* ec = CurrentExecutionContext(isolate_); // TODO(dgozman): we can save on a copy here if TracedValue would take a // StringView. - TRACE_EVENT_INSTANT1("devtools.timeline", "TimeStamp", - TRACE_EVENT_SCOPE_THREAD, "data", - InspectorTimeStampEvent::Data(ec, ToCoreString(title))); + TRACE_EVENT_INSTANT1( + "devtools.timeline", "TimeStamp", TRACE_EVENT_SCOPE_THREAD, "data", + inspector_time_stamp_event::Data(ec, ToCoreString(title))); probe::consoleTimeStamp(ec, ToCoreString(title)); }
diff --git a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc index e288d48f..d163b7c8 100644 --- a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc +++ b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
@@ -175,7 +175,7 @@ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "TracingSessionIdForWorker", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorTracingSessionIdForWorkerEvent::Data( + inspector_tracing_session_id_for_worker_event::Data( worker_devtools_token_, parent_devtools_token_, url_, worker_thread_id_)); }
diff --git a/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc b/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc index 3dddc9b..bd21421 100644 --- a/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc +++ b/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc
@@ -314,7 +314,7 @@ if (V8ScriptRunner::CallAsConstructor( isolate, constructor, ExecutionContext::From(script_state_), 0, {}) .ToLocal(&layout_instance)) { - instance = new Instance(this, layout_instance); + instance = MakeGarbageCollected<Instance>(this, layout_instance); } else { constructor_has_failed_ = true; }
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc index 8bc8cf5..1147dce 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
@@ -113,7 +113,7 @@ &layout, &exception_state)) return; - CSSLayoutDefinition* definition = new CSSLayoutDefinition( + CSSLayoutDefinition* definition = MakeGarbageCollected<CSSLayoutDefinition>( ScriptController()->GetScriptState(), constructor, intrinsic_sizes, layout, native_invalidation_properties, custom_invalidation_properties, child_native_invalidation_properties,
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc index 903dbc2..fa87ab4 100644 --- a/third_party/blink/renderer/core/layout/layout_image.cc +++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -336,7 +336,7 @@ return false; // Check for image with alpha. TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", - "data", InspectorPaintImageEvent::Data(this, *image_content)); + "data", inspector_paint_image_event::Data(this, *image_content)); return image_content->GetImage()->CurrentFrameKnownToBeOpaque(); }
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index b2e8188..7c972e51 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -3000,7 +3000,7 @@ TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "LayoutInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorLayoutInvalidationTrackingEvent::Data(this, reason)); + inspector_layout_invalidation_tracking_event::Data(this, reason)); if (mark_parents == kMarkContainerChain && (!layouter || layouter->Root() != this)) MarkContainerChainForLayout(!layouter, layouter);
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 3c006349..0b71fa97 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -197,8 +197,8 @@ } TRACE_EVENT_END1("blink,devtools.timeline", "HitTest", "endData", - InspectorHitTestEvent::EndData(result.GetHitTestRequest(), - location, result)); + inspector_hit_test_event::EndData(result.GetHitTestRequest(), + location, result)); return hit_layer; }
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 7a3dc85..15c42d4 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1081,7 +1081,7 @@ interactive_detector->SetNavigationStartTime(GetTiming().NavigationStart()); TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", - InspectorCommitLoadEvent::Data(frame_)); + inspector_commit_load_event::Data(frame_)); // Needs to run before dispatching preloads, as it may evict the memory cache. probe::didCommitLoad(frame_, this);
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 284187d..677d1949 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -518,7 +518,7 @@ if (IsDetached()) return; TRACE_EVENT1("devtools.timeline", "ResourceChangePriority", "data", - InspectorChangeResourcePriorityEvent::Data( + inspector_change_resource_priority_event::Data( MasterDocumentLoader(), identifier, load_priority)); probe::didChangeResourcePriority(GetFrame(), MasterDocumentLoader(), identifier, load_priority);
diff --git a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc index ca623be2..6ab3d4a 100644 --- a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc +++ b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
@@ -61,7 +61,8 @@ ResourceLoaderOptions options; TextResourceDecoderOptions decoder_options( TextResourceDecoderOptions::kCSSContent, encoding); - return new CSSStyleSheetResource(request, options, decoder_options); + return MakeGarbageCollected<CSSStyleSheetResource>(request, options, + decoder_options); } CSSStyleSheetResource::CSSStyleSheetResource(
diff --git a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h index a3b3ae4..e16ace2 100644 --- a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h +++ b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h
@@ -50,6 +50,9 @@ static CSSStyleSheetResource* CreateForTest(const KURL&, const WTF::TextEncoding&); + CSSStyleSheetResource(const ResourceRequest&, + const ResourceLoaderOptions&, + const TextResourceDecoderOptions&); ~CSSStyleSheetResource() override; void Trace(blink::Visitor*) override; @@ -70,12 +73,10 @@ const ResourceRequest& request, const ResourceLoaderOptions& options, const TextResourceDecoderOptions& decoder_options) const override { - return new CSSStyleSheetResource(request, options, decoder_options); + return MakeGarbageCollected<CSSStyleSheetResource>(request, options, + decoder_options); } }; - CSSStyleSheetResource(const ResourceRequest&, - const ResourceLoaderOptions&, - const TextResourceDecoderOptions&); bool CanUseSheet(const CSSParserContext*, MIMETypeCheck) const; void NotifyFinished() override;
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource.cc b/third_party/blink/renderer/core/loader/resource/script_resource.cc index a66e4ce..fd1eb534 100644 --- a/third_party/blink/renderer/core/loader/resource/script_resource.cc +++ b/third_party/blink/renderer/core/loader/resource/script_resource.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h" #include "third_party/blink/renderer/platform/loader/subresource_integrity.h" #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/shared_buffer.h" namespace blink { @@ -80,7 +81,12 @@ ScriptResource* resource = ToScriptResource( fetcher->RequestResource(params, ScriptResourceFactory(), client)); - if (streaming_allowed != kAllowStreaming) { + if (streaming_allowed == kAllowStreaming) { + // Start streaming the script as soon as we get it. + if (RuntimeEnabledFeatures::ScriptStreamingOnPreloadEnabled()) { + resource->StartStreaming(fetcher->Context().GetLoadingTaskRunner()); + } + } else { // Advance the |streaming_state_| to kStreamingNotAllowed by calling // SetClientIsWaitingForFinished unless it is explicitly allowed.' //
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index d7d7d24a..e0a47c38 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -437,9 +437,9 @@ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", - InspectorPaintImageEvent::Data(node, *info.image, - FloatRect(image->Rect()), - FloatRect(image_border.Rect()))); + inspector_paint_image_event::Data( + node, *info.image, FloatRect(image->Rect()), + FloatRect(image_border.Rect()))); // Since there is no way for the developer to specify decode behavior, use // kSync by default. @@ -554,7 +554,7 @@ image) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", - InspectorPaintImageEvent::Data( + inspector_paint_image_event::Data( node, *info.image, FloatRect(image->Rect()), FloatRect(scrolled_paint_rect))); context.DrawTiledImage(image,
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 997375ff..e4511c78 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1120,7 +1120,7 @@ .InvalidatePaintIncludingNonCompositingDescendants(); TRACE_LAYER_INVALIDATION(layers[i].paint_layer, - InspectorLayerInvalidationTrackingEvent:: + inspector_layer_invalidation_tracking_event:: kSquashingLayerGeometryWasUpdated); layers_needing_paint_invalidation.push_back(layers[i].paint_layer); } @@ -3373,8 +3373,8 @@ TRACE_EVENT1( "devtools.timeline,rail", "Paint", "data", - InspectorPaintEvent::Data(&owning_layer_.GetLayoutObject(), - LayoutRect(interest_rect), graphics_layer)); + inspector_paint_event::Data(&owning_layer_.GetLayoutObject(), + LayoutRect(interest_rect), graphics_layer)); PaintLayerFlags paint_layer_flags = 0; if (graphics_layer_painting_phase & kGraphicsLayerPaintBackground)
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc index e048a9f2..a4e6f78 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
@@ -253,7 +253,8 @@ // Issue a paint invalidation, since |layer| may have been added to an // already-existing squashing layer. TRACE_LAYER_INVALIDATION( - layer, InspectorLayerInvalidationTrackingEvent::kAddedToSquashingLayer); + layer, + inspector_layer_invalidation_tracking_event::kAddedToSquashingLayer); layers_needing_paint_invalidation.push_back(layer); layers_changed_ = true; } else if (composited_layer_update == kRemoveFromSquashingLayer) { @@ -269,9 +270,9 @@ // If we need to issue paint invalidations, do so now that we've removed it // from a squashed layer. - TRACE_LAYER_INVALIDATION( - layer, - InspectorLayerInvalidationTrackingEvent::kRemovedFromSquashingLayer); + TRACE_LAYER_INVALIDATION(layer, + inspector_layer_invalidation_tracking_event:: + kRemovedFromSquashingLayer); layers_needing_paint_invalidation.push_back(layer); layers_changed_ = true; @@ -303,7 +304,8 @@ if (compositor_->AllocateOrClearCompositedLayerMapping( layer, composited_layer_update)) { TRACE_LAYER_INVALIDATION( - layer, InspectorLayerInvalidationTrackingEvent::kNewCompositedLayer); + layer, + inspector_layer_invalidation_tracking_event::kNewCompositedLayer); layers_needing_paint_invalidation.push_back(layer); layers_changed_ = true; if (ScrollingCoordinator* scrolling_coordinator =
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc index d5f2881b..52e06df 100644 --- a/third_party/blink/renderer/core/paint/frame_painter.cc +++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -68,7 +68,7 @@ FramePaintTiming frame_paint_timing(context, &GetFrameView().GetFrame()); TRACE_EVENT1( "devtools.timeline,rail", "Paint", "data", - InspectorPaintEvent::Data(layout_view, LayoutRect(rect), nullptr)); + inspector_paint_event::Data(layout_view, LayoutRect(rect), nullptr)); bool is_top_level_painter = !in_paint_contents_; in_paint_contents_ = true;
diff --git a/third_party/blink/renderer/core/paint/image_painter.cc b/third_party/blink/renderer/core/paint/image_painter.cc index d064c56..bc9c41e 100644 --- a/third_party/blink/renderer/core/paint/image_painter.cc +++ b/third_party/blink/renderer/core/paint/image_painter.cc
@@ -175,8 +175,8 @@ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", - InspectorPaintImageEvent::Data(layout_image_, src_rect, - FloatRect(dest_rect))); + inspector_paint_image_event::Data(layout_image_, src_rect, + FloatRect(dest_rect))); ScopedInterpolationQuality interpolation_quality_scope( context, layout_image_.StyleRef().GetInterpolationQuality());
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc index aa56f62..5c32e136 100644 --- a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc +++ b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
@@ -100,9 +100,9 @@ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", - InspectorPaintImageEvent::Data(node, *style_image, - FloatRect(image->Rect()), - FloatRect(border_image_rect))); + inspector_paint_image_event::Data(node, *style_image, + FloatRect(image->Rect()), + FloatRect(border_image_rect))); ScopedInterpolationQuality interpolation_quality_scope( graphics_context, style.GetInterpolationQuality());
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc index a3972144..806cacc 100644 --- a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -199,7 +199,7 @@ TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "PaintInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorPaintInvalidationTrackingEvent::Data(object_)); + inspector_paint_invalidation_tracking_event::Data(object_)); } client.Invalidate(reason);
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index af706af..8e0479a3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -428,7 +428,7 @@ bool is_root_layer = Layer()->IsRootLayer(); TRACE_EVENT1("devtools.timeline", "ScrollLayer", "data", - InspectorScrollLayerEvent::Data(GetLayoutBox())); + inspector_scroll_layer_event::Data(GetLayoutBox())); // FIXME(420741): Resolve circular dependency between scroll offset and // compositing state, and remove this disabler.
diff --git a/third_party/blink/renderer/core/probe/core_probes.cc b/third_party/blink/renderer/core/probe/core_probes.cc index c45771c..e559212 100644 --- a/third_party/blink/renderer/core/probe/core_probes.cc +++ b/third_party/blink/renderer/core/probe/core_probes.cc
@@ -79,7 +79,7 @@ void* task) { TRACE_EVENT_FLOW_BEGIN1("devtools.timeline.async", "AsyncTask", TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task)), - "data", InspectorAsyncTask::Data(name)); + "data", inspector_async_task::Data(name)); if (ThreadDebugger* debugger = ThreadDebugger::From(ToIsolate(context))) debugger->AsyncTaskScheduled(name, AsyncId(task), true); }
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index 0ba774c..90748133 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -23,11 +23,58 @@ ScriptValue Call(ScriptValue value) override { return value; } }; -ReadableStream::ReadableStream(ScriptState* script_state, - v8::Local<v8::Object> object) - : object_(script_state->GetIsolate(), object) { +void ReadableStream::Init(ScriptState* script_state, + ScriptValue underlying_source, + ScriptValue strategy, + ExceptionState& exception_state) { + ScriptValue value = ReadableStreamOperations::CreateReadableStream( + script_state, underlying_source, strategy, exception_state); + if (exception_state.HadException()) + return; + + DCHECK(value.IsObject()); + InitWithInternalStream(script_state, value.V8Value().As<v8::Object>(), + exception_state); +} + +void ReadableStream::InitWithInternalStream(ScriptState* script_state, + v8::Local<v8::Object> object, + ExceptionState& exception_state) { DCHECK(ReadableStreamOperations::IsReadableStreamForDCheck( script_state, ScriptValue(script_state, object))); + object_.Set(script_state->GetIsolate(), object); + + v8::Isolate* isolate = script_state->GetIsolate(); + v8::TryCatch block(isolate); + v8::Local<v8::Value> wrapper = ToV8(this, script_state); + if (wrapper.IsEmpty()) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + + v8::Local<v8::Context> context = script_state->GetContext(); + v8::Local<v8::Object> bindings = + context->GetExtrasBindingObject().As<v8::Object>(); + v8::Local<v8::Value> symbol_value; + if (!bindings->Get(context, V8String(isolate, "internalReadableStreamSymbol")) + .ToLocal(&symbol_value)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + + if (wrapper.As<v8::Object>() + ->Set(context, symbol_value.As<v8::Symbol>(), object) + .IsNothing()) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + + // This is needed because sometimes a ReadableStream can be detached from + // the owner object such as Response. + if (!RetainWrapperDuringConstruction(this, script_state)) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "Cannot queue task to retain wrapper"); + } } ReadableStream* ReadableStream::Create(ScriptState* script_state, @@ -52,27 +99,10 @@ ScriptValue underlying_source, ScriptValue strategy, ExceptionState& exception_state) { - ScriptValue value = ReadableStreamOperations::CreateReadableStream( - script_state, underlying_source, strategy, exception_state); - - if (value.IsEmpty()) + auto* stream = MakeGarbageCollected<ReadableStream>(); + stream->Init(script_state, underlying_source, strategy, exception_state); + if (exception_state.HadException()) return nullptr; - - DCHECK(value.V8Value()->IsObject()); - return CreateFromInternalStream(script_state, value, exception_state); -} - -ReadableStream* ReadableStream::CreateFromInternalStream( - ScriptState* script_state, - v8::Local<v8::Object> object, - ExceptionState& exception_state) { - auto* stream = MakeGarbageCollected<ReadableStream>(script_state, object); - - v8::TryCatch block(script_state->GetIsolate()); - if (!stream->Init(script_state)) { - exception_state.RethrowV8Exception(block.Exception()); - return nullptr; - } return stream; } @@ -85,6 +115,17 @@ script_state, object.V8Value().As<v8::Object>(), exception_state); } +ReadableStream* ReadableStream::CreateFromInternalStream( + ScriptState* script_state, + v8::Local<v8::Object> object, + ExceptionState& exception_state) { + auto* stream = MakeGarbageCollected<ReadableStream>(); + stream->InitWithInternalStream(script_state, object, exception_state); + if (exception_state.HadException()) + return nullptr; + return stream; +} + ReadableStream* ReadableStream::CreateWithCountQueueingStrategy( ScriptState* script_state, UnderlyingSourceBase* underlying_source, @@ -97,16 +138,16 @@ ScriptValue value = ReadableStreamOperations::CreateReadableStream( script_state, underlying_source, strategy); - if (value.IsEmpty()) return nullptr; + ExceptionState exception_state(script_state->GetIsolate(), + ExceptionState::kConstructionContext, + "ReadableStream"); DCHECK(value.V8Value()->IsObject()); - v8::Local<v8::Object> object = value.V8Value().As<v8::Object>(); - auto* stream = MakeGarbageCollected<ReadableStream>(script_state, object); - - if (!stream->Init(script_state)) - return nullptr; + auto* stream = CreateFromInternalStream(script_state, value, exception_state); + if (exception_state.HadException()) + exception_state.ClearException(); return stream; } @@ -383,12 +424,15 @@ DCHECK(v8_branch1->IsObject()); DCHECK(v8_branch2->IsObject()); - ReadableStream* temp_branch1 = CreateFromInternalStream( + ReadableStream* temp_branch1 = MakeGarbageCollected<ReadableStream>(); + ReadableStream* temp_branch2 = MakeGarbageCollected<ReadableStream>(); + + temp_branch1->InitWithInternalStream( script_state, v8_branch1.As<v8::Object>(), exception_state); if (exception_state.HadException()) return; - ReadableStream* temp_branch2 = CreateFromInternalStream( + temp_branch2->InitWithInternalStream( script_state, v8_branch2.As<v8::Object>(), exception_state); if (exception_state.HadException()) return; @@ -476,31 +520,4 @@ object_.NewLocal(script_state->GetIsolate())); } -bool ReadableStream::Init(ScriptState* script_state) { - v8::Isolate* isolate = script_state->GetIsolate(); - v8::Local<v8::Object> internal_stream = object_.NewLocal(isolate); - v8::Local<v8::Value> wrapper = ToV8(this, script_state); - if (wrapper.IsEmpty()) - return false; - - v8::Local<v8::Context> context = script_state->GetContext(); - v8::Local<v8::Object> bindings = - context->GetExtrasBindingObject().As<v8::Object>(); - v8::Local<v8::Value> symbol_value; - if (!bindings->Get(context, V8String(isolate, "internalReadableStreamSymbol")) - .ToLocal(&symbol_value)) { - return false; - } - - if (wrapper.As<v8::Object>() - ->Set(context, symbol_value.As<v8::Symbol>(), internal_stream) - .IsNothing()) { - return false; - } - - // This is needed because sometimes a ReadableStream can be detached from - // the owner object such as Response. - return RetainWrapperDuringConstruction(this, script_state); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream.h b/third_party/blink/renderer/core/streams/readable_stream.h index 37e3148c..7ba0452 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.h +++ b/third_party/blink/renderer/core/streams/readable_stream.h
@@ -25,9 +25,22 @@ DEFINE_WRAPPERTYPEINFO(); public: - // Use one of Create functions. This is public only for MakeGarbageCollected. - ReadableStream(ScriptState*, v8::Local<v8::Object> object); + // Call one of Init functions before using the instance. + ReadableStream() = default; + ~ReadableStream() override = default; + // If an error happens, |exception_state.HadException()| will be true, and + // |this| will not be usable after that. + void Init(ScriptState*, + ScriptValue underlying_source, + ScriptValue strategy, + ExceptionState& exception_state); + void InitWithInternalStream(ScriptState*, + v8::Local<v8::Object> object, + ExceptionState& exception_state); + + // Create* functions call Init* internally and returns null when an error + // happens. static ReadableStream* Create(ScriptState*, ExceptionState&); static ReadableStream* Create(ScriptState*, ScriptValue underlying_source, @@ -49,8 +62,6 @@ UnderlyingSourceBase* underlying_source, size_t high_water_mark); - ~ReadableStream() override = default; - void Trace(Visitor* visitor) override; // IDL defined functions @@ -109,8 +120,6 @@ private: class NoopFunction; - bool Init(ScriptState*); - TraceWrapperV8Reference<v8::Object> object_; };
diff --git a/third_party/blink/renderer/core/streams/readable_stream.idl b/third_party/blink/renderer/core/streams/readable_stream.idl index de50c87d..9fbe8e9f 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.idl +++ b/third_party/blink/renderer/core/streams/readable_stream.idl
@@ -5,7 +5,8 @@ // https://streams.spec.whatwg.org/#rs-class [ Exposed=(Window,Worker,Worklet), - Constructor(optional any underlyingSource, optional any strategy), + // TODO(yhirano): Remove CustomConstructor. See https://crbug.com/906476. + CustomConstructor(optional any underlyingSource, optional any strategy), RaisesException=Constructor, ConstructorCallWith=ScriptState ] interface ReadableStream {
diff --git a/third_party/blink/renderer/core/style/style_fetched_image.h b/third_party/blink/renderer/core/style/style_fetched_image.h index f464719..ccdf41f 100644 --- a/third_party/blink/renderer/core/style/style_fetched_image.h +++ b/third_party/blink/renderer/core/style/style_fetched_image.h
@@ -43,8 +43,13 @@ static StyleFetchedImage* Create(const Document& document, FetchParameters& params, bool is_lazyload_deferred) { - return new StyleFetchedImage(document, params, is_lazyload_deferred); + return MakeGarbageCollected<StyleFetchedImage>(document, params, + is_lazyload_deferred); } + + StyleFetchedImage(const Document&, + FetchParameters&, + bool is_lazyload_deferred); ~StyleFetchedImage() override; WrappedImagePtr Data() const override; @@ -79,10 +84,6 @@ void Trace(blink::Visitor*) override; private: - StyleFetchedImage(const Document&, - FetchParameters&, - bool is_lazyload_deferred); - bool IsEqual(const StyleImage&) const override; void Dispose();
diff --git a/third_party/blink/renderer/core/style/style_fetched_image_set.h b/third_party/blink/renderer/core/style/style_fetched_image_set.h index 3872da13..d032039 100644 --- a/third_party/blink/renderer/core/style/style_fetched_image_set.h +++ b/third_party/blink/renderer/core/style/style_fetched_image_set.h
@@ -50,8 +50,14 @@ float image_scale_factor, CSSImageSetValue* value, const KURL& url) { - return new StyleFetchedImageSet(image, image_scale_factor, value, url); + return MakeGarbageCollected<StyleFetchedImageSet>(image, image_scale_factor, + value, url); } + + StyleFetchedImageSet(ImageResourceContent*, + float image_scale_factor, + CSSImageSetValue*, + const KURL&); ~StyleFetchedImageSet() override; CSSValue* CssValue() const override; @@ -83,11 +89,6 @@ void Trace(blink::Visitor*) override; private: - StyleFetchedImageSet(ImageResourceContent*, - float image_scale_factor, - CSSImageSetValue*, - const KURL&); - bool IsEqual(const StyleImage& other) const override; void Dispose();
diff --git a/third_party/blink/renderer/core/style/style_filter_data.h b/third_party/blink/renderer/core/style/style_filter_data.h index 4a9afca..98b5b13a 100644 --- a/third_party/blink/renderer/core/style/style_filter_data.h +++ b/third_party/blink/renderer/core/style/style_filter_data.h
@@ -33,9 +33,16 @@ class StyleFilterData final : public GarbageCollected<StyleFilterData> { public: - static StyleFilterData* Create() { return new StyleFilterData; } + static StyleFilterData* Create() { + return MakeGarbageCollected<StyleFilterData>(); + } - StyleFilterData* Copy() const { return new StyleFilterData(*this); } + StyleFilterData(); + explicit StyleFilterData(const StyleFilterData&); + + StyleFilterData* Copy() const { + return MakeGarbageCollected<StyleFilterData>(*this); + } bool operator==(const StyleFilterData&) const; bool operator!=(const StyleFilterData& o) const { return !(*this == o); } @@ -43,10 +50,6 @@ void Trace(blink::Visitor* visitor) { visitor->Trace(operations_); } FilterOperations operations_; - - private: - StyleFilterData(); - explicit StyleFilterData(const StyleFilterData&); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_generated_image.h b/third_party/blink/renderer/core/style/style_generated_image.h index c155958..f1046f2 100644 --- a/third_party/blink/renderer/core/style/style_generated_image.h +++ b/third_party/blink/renderer/core/style/style_generated_image.h
@@ -39,9 +39,11 @@ class CORE_EXPORT StyleGeneratedImage final : public StyleImage { public: static StyleGeneratedImage* Create(const CSSImageGeneratorValue& value) { - return new StyleGeneratedImage(value); + return MakeGarbageCollected<StyleGeneratedImage>(value); } + StyleGeneratedImage(const CSSImageGeneratorValue&); + WrappedImagePtr Data() const override { return image_generator_value_.Get(); } CSSValue* CssValue() const override; @@ -64,8 +66,6 @@ void Trace(blink::Visitor*) override; private: - StyleGeneratedImage(const CSSImageGeneratorValue&); - bool IsEqual(const StyleImage&) const override; // TODO(sashab): Replace this with <const CSSImageGeneratorValue> once
diff --git a/third_party/blink/renderer/core/style/style_pending_image.h b/third_party/blink/renderer/core/style/style_pending_image.h index 1ef61e4..c779060 100644 --- a/third_party/blink/renderer/core/style/style_pending_image.h +++ b/third_party/blink/renderer/core/style/style_pending_image.h
@@ -44,7 +44,12 @@ class StylePendingImage final : public StyleImage { public: static StylePendingImage* Create(const CSSValue& value) { - return new StylePendingImage(value); + return MakeGarbageCollected<StylePendingImage>(value); + } + + explicit StylePendingImage(const CSSValue& value) + : value_(const_cast<CSSValue*>(&value)) { + is_pending_image_ = true; } WrappedImagePtr Data() const override { return value_.Get(); } @@ -98,11 +103,6 @@ } private: - explicit StylePendingImage(const CSSValue& value) - : value_(const_cast<CSSValue*>(&value)) { - is_pending_image_ = true; - } - bool IsEqual(const StyleImage& other) const override; // TODO(sashab): Replace this with <const CSSValue> once Member<>
diff --git a/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc b/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc index 50673ab..fba813e9 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc
@@ -76,8 +76,7 @@ {SVGFEBlendElement::kModeColor, "color"}, {SVGFEBlendElement::kModeLuminosity, "luminosity"}, }; - static const SVGEnumerationMap entries(enum_items, - SVGFEBlendElement::kModeLighten); + static const SVGEnumerationMap entries(enum_items); return entries; }
diff --git a/third_party/blink/renderer/core/svg/svg_fe_blend_element.h b/third_party/blink/renderer/core/svg/svg_fe_blend_element.h index 455d398..cc6cf833 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_blend_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_blend_element.h
@@ -38,20 +38,17 @@ kModeScreen = 3, kModeDarken = 4, kModeLighten = 5, - - // The following modes do not map to IDL constants on - // SVGFEBlendElement. - kModeOverlay, - kModeColorDodge, - kModeColorBurn, - kModeHardLight, - kModeSoftLight, - kModeDifference, - kModeExclusion, - kModeHue, - kModeSaturation, - kModeColor, - kModeLuminosity, + kModeOverlay = 6, + kModeColorDodge = 7, + kModeColorBurn = 8, + kModeHardLight = 9, + kModeSoftLight = 10, + kModeDifference = 11, + kModeExclusion = 12, + kModeHue = 13, + kModeSaturation = 14, + kModeColor = 15, + kModeLuminosity = 16, }; DECLARE_NODE_FACTORY(SVGFEBlendElement);
diff --git a/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl b/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl index 88bc48c9..5f7487b 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl
@@ -36,6 +36,17 @@ [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_SCREEN = 3; [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_DARKEN = 4; [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_OVERLAY = 6; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_COLOR_DODGE = 7; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_COLOR_BURN = 8; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_HARD_LIGHT = 9; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_SOFT_LIGHT = 10; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_DIFFERENCE = 11; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_EXCLUSION = 12; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_HUE = 13; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_SATURATION = 14; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_COLOR = 15; + [MeasureAs=SVG1DOMFilter] const unsigned short SVG_FEBLEND_MODE_LUMINOSITY = 16; [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedString in1; [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedString in2;
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.idl b/third_party/blink/renderer/core/workers/shared_worker_global_scope.idl index 9b3d13b..c26b4c4 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.idl +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.idl
@@ -34,7 +34,7 @@ Global=(Worker,SharedWorker), Exposed=SharedWorker ] interface SharedWorkerGlobalScope : WorkerGlobalScope { - readonly attribute DOMString name; + [Replaceable] readonly attribute DOMString name; // TODO(foolip): readonly attribute ApplicationCache applicationCache; void close();
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.idl b/third_party/blink/renderer/core/workers/worker_global_scope.idl index 8ff553b..0f8adc9b 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.idl +++ b/third_party/blink/renderer/core/workers/worker_global_scope.idl
@@ -80,6 +80,6 @@ }; WorkerGlobalScope implements WindowBase64; -WorkerGlobalScope implements WindowTimers; +WorkerGlobalScope implements WindowOrWorkerGlobalScope; // TODO(fserb): this needs to be enabled once we get out of RuntimeEnabled. //WorkerGlobalScope implements FontFaceSource;
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index bb4bad2..07243dc 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -574,9 +574,9 @@ ScopedEventDispatchProtect protect(&event_dispatch_recursion_level_); if (async_ || (state_ <= kOpened || state_ == kDone)) { - TRACE_EVENT1( - "devtools.timeline", "XHRReadyStateChange", "data", - InspectorXhrReadyStateChangeEvent::Data(GetExecutionContext(), this)); + TRACE_EVENT1("devtools.timeline", "XHRReadyStateChange", "data", + inspector_xhr_ready_state_change_event::Data( + GetExecutionContext(), this)); XMLHttpRequestProgressEventThrottle::DeferredEventAction action = XMLHttpRequestProgressEventThrottle::kIgnore; if (state_ == kDone) { @@ -591,7 +591,7 @@ if (state_ == kDone && !error_) { TRACE_EVENT1("devtools.timeline", "XHRLoad", "data", - InspectorXhrLoadEvent::Data(GetExecutionContext(), this)); + inspector_xhr_load_event::Data(GetExecutionContext(), this)); DispatchProgressEventFromSnapshot(event_type_names::kLoad); DispatchProgressEventFromSnapshot(event_type_names::kLoadend); }
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc index 21fc27d1..ca7c69f 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc
@@ -143,7 +143,7 @@ if (target_->readyState() == XMLHttpRequest::kLoading && has_dispatched_progress_progress_event_) { TRACE_EVENT1("devtools.timeline", "XHRReadyStateChange", "data", - InspectorXhrReadyStateChangeEvent::Data( + inspector_xhr_ready_state_change_event::Data( target_->GetExecutionContext(), target_)); probe::AsyncTask async_task(target_->GetExecutionContext(), target_, "progress", target_->IsAsync());
diff --git a/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js b/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js index f0c0a2e..0706be5 100644 --- a/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js +++ b/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js
@@ -507,7 +507,9 @@ if (this._deferredNode) { valueElement = createElement('span'); element.appendChild(valueElement); - Common.Linkifier.linkify(this._deferredNode).then(linkfied => valueElement.appendChild(linkfied)); + this._deferredNode.resolvePromise().then(node => { + Common.Linkifier.linkify(node).then(linkfied => valueElement.appendChild(linkfied)); + }); } else if (this._idref) { element.classList.add('invalid'); valueElement = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`No node with this ID.`);
diff --git a/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc b/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc index b3756c4..21c49031 100644 --- a/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc +++ b/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc
@@ -45,7 +45,8 @@ CSSAnimationWorklet* supplement = Supplement<LocalDOMWindow>::From<CSSAnimationWorklet>(window); if (!supplement) { - supplement = new CSSAnimationWorklet(window.GetFrame()->GetDocument()); + supplement = MakeGarbageCollected<CSSAnimationWorklet>( + window.GetFrame()->GetDocument()); ProvideTo(window, supplement); } return *supplement;
diff --git a/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h b/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h index 3593675..f628f3f 100644 --- a/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h +++ b/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h
@@ -27,6 +27,8 @@ static AnimationWorklet* animationWorklet(ScriptState*); + explicit CSSAnimationWorklet(Document*); + void ContextDestroyed(ExecutionContext*) override; void Trace(blink::Visitor*) override; @@ -34,8 +36,6 @@ private: static CSSAnimationWorklet& From(LocalDOMWindow&); - explicit CSSAnimationWorklet(Document*); - Member<AnimationWorklet> animation_worklet_; };
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc index 966b8d5..3f6ce68 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
@@ -3,21 +3,56 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/background_fetch/background_fetch_record.h" - #include "third_party/blink/renderer/core/fetch/request.h" #include "third_party/blink/renderer/core/fetch/response.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" namespace blink { BackgroundFetchRecord::BackgroundFetchRecord(Request* request, - Response* response, - bool aborted) - : request_(request), response_(response), aborted_(aborted) { + ScriptState* script_state) + : request_(request), script_state_(script_state) { DCHECK(request_); + DCHECK(script_state_); } BackgroundFetchRecord::~BackgroundFetchRecord() = default; +void BackgroundFetchRecord::ResolveResponseReadyProperty() { + if (!response_ready_property_ || + response_ready_property_->GetState() != + ScriptPromisePropertyBase::State::kPending) { + return; + } + + switch (record_state_) { + case State::kPending: + return; + case State::kAborted: + response_ready_property_->Reject(DOMException::Create( + DOMExceptionCode::kAbortError, + "The fetch was aborted before the record was processed.")); + return; + case State::kSettled: + if (response_) { + response_ready_property_->Resolve(response_); + return; + } + + if (!script_state_->ContextIsValid()) + return; + + // TODO(crbug.com/875201):Per https://wicg.github.io/background-fetch/ + // #background-fetch-response-exposed, this should be resolved with a + // TypeError. Figure out a way to do so. + // Rejecting this with a TypeError here doesn't work because the + // RejectedType is a DOMException. Update this with the correct error + // once confirmed, or change the RejectedType. + response_ready_property_->Reject(DOMException::Create( + DOMExceptionCode::kUnknownError, "The response is not available.")); + } +} + ScriptPromise BackgroundFetchRecord::responseReady(ScriptState* script_state) { if (!response_ready_property_) { response_ready_property_ = @@ -25,34 +60,47 @@ ResponseReadyProperty::kResponseReady); } - if (response_) { - DCHECK(response_); - response_ready_property_->Resolve(response_); - return response_ready_property_->Promise(script_state->World()); - } + ResolveResponseReadyProperty(); - if (aborted_) { - return ScriptPromise::RejectWithDOMException( - script_state, - DOMException::Create( - DOMExceptionCode::kAbortError, - "The fetch was aborted before the record was processed.")); - } - - return ScriptPromise::Reject( - script_state, - V8ThrowException::CreateTypeError(script_state->GetIsolate(), - "The response is not available.")); + return response_ready_property_->Promise(script_state->World()); } Request* BackgroundFetchRecord::request() const { return request_; } +void BackgroundFetchRecord::UpdateState( + BackgroundFetchRecord::State updated_state) { + DCHECK_EQ(record_state_, State::kPending); + + record_state_ = updated_state; + ResolveResponseReadyProperty(); +} + +void BackgroundFetchRecord::SetResponse( + mojom::blink::FetchAPIResponsePtr& response) { + DCHECK(record_state_ == State::kPending); + + if (!response_) { + if (!script_state_->ContextIsValid()) + return; + response_ = Response::Create(script_state_, *response); + } + + DCHECK(response_); + + ResolveResponseReadyProperty(); +} + +bool BackgroundFetchRecord::IsRecordPending() { + return record_state_ == State::kPending; +} + void BackgroundFetchRecord::Trace(blink::Visitor* visitor) { visitor->Trace(request_); visitor->Trace(response_); visitor->Trace(response_ready_property_); + visitor->Trace(script_state_); ScriptWrappable::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h index 38c8786..9cfbe00 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_RECORD_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_RECORD_H_ +#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -16,17 +17,35 @@ class Request; class Response; +class ScriptState; class MODULES_EXPORT BackgroundFetchRecord final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - BackgroundFetchRecord(Request* request, Response* response, bool aborted); + // The record can be in one of these states. |kSettled| can mean success or + // failure based on whether or not |response_| is a nullptr. + enum class State { + kPending, + kAborted, + kSettled, + }; + + BackgroundFetchRecord(Request* request, ScriptState* script_state); ~BackgroundFetchRecord() override; Request* request() const; ScriptPromise responseReady(ScriptState* script_state); + // Updates |record_state_| from kPending to kAborted or kSettled. Must be + // called when |record_state_| is kPending. + void UpdateState(State updated_state); + + // Sets |response_| to response. Must be called when |record_state_| is + // kPending. + void SetResponse(mojom::blink::FetchAPIResponsePtr& response); + + bool IsRecordPending(); void Trace(blink::Visitor* visitor) override; private: @@ -34,12 +53,23 @@ ScriptPromiseProperty<Member<BackgroundFetchRecord>, Member<Response>, Member<DOMException>>; + + // Resolves a pending |response_read_property_| with |response_|, if it's not + // null. + // If |response_| is null, we do nothing if the record isn't final yet. If + // |record_final_| is true in this case, we reject the promise. + // This is because the record will not be updated with a valid |response_|. + void ResolveResponseReadyProperty(); + Member<Request> request_; Member<Response> response_; Member<ResponseReadyProperty> response_ready_property_; - // Whether this record belongs to a fetch that was aborted. - bool aborted_; + // Since BackgroundFetchRecord can only be accessed from the world that + // created it, there's no danger of ScriptState leaking across worlds. + Member<ScriptState> script_state_; + + State record_state_ = State::kPending; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc index ae18e06..bc1af00 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/modules/manifest/image_resource.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" namespace blink { @@ -87,6 +88,8 @@ result_ = result; failure_reason_ = failure_reason; + // TODO(crbug.com/875201): Update records in |records_|. + ExecutionContext* context = GetExecutionContext(); if (!context || context->IsContextDestroyed()) return; @@ -232,25 +235,30 @@ ScriptPromiseResolver* resolver, bool return_all, Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches) { + DCHECK(resolver); + ScriptState* script_state = resolver->GetScriptState(); // Do not remove this, |scope| is needed for calling ToV8() ScriptState::Scope scope(script_state); HeapVector<Member<BackgroundFetchRecord>> to_return; to_return.ReserveInitialCapacity(settled_fetches.size()); - for (const auto& fetch : settled_fetches) { - Request* request = Request::Create(script_state, *(fetch->request)); + for (auto& fetch : settled_fetches) { + // If there isn't a record for this fetch in records_ already, create one. + auto iter = records_.find(fetch->request->url); + BackgroundFetchRecord* record = nullptr; + if (iter == records_.end()) { + Request* request = Request::Create(script_state, *(fetch->request)); + auto* new_record = new BackgroundFetchRecord(request, script_state); + DCHECK(new_record); + records_.Set(request->url(), new_record); - Response* response = fetch->response - ? Response::Create(script_state, *fetch->response) - : nullptr; + record = new_record; + } else { + record = iter->value; + } - bool aborted = - failure_reason_ == - mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI || - failure_reason_ == - mojom::BackgroundFetchFailureReason::CANCELLED_BY_DEVELOPER; - - to_return.push_back(new BackgroundFetchRecord(request, response, aborted)); + UpdateRecord(record, fetch->response); + to_return.push_back(record); } if (!return_all) { @@ -267,6 +275,38 @@ resolver->Resolve(to_return); } +void BackgroundFetchRegistration::UpdateRecord( + BackgroundFetchRecord* record, + mojom::blink::FetchAPIResponsePtr& response) { + DCHECK(record); + + if (!record->IsRecordPending()) + return; + + // Per the spec, resolve with a valid response, if there is one available, + // even if the fetch has been aborted. + if (response) { + record->SetResponse(response); + record->UpdateState(BackgroundFetchRecord::State::kSettled); + return; + } + + if (IsAborted()) { + record->UpdateState(BackgroundFetchRecord::State::kAborted); + return; + } + + if (result_ != mojom::blink::BackgroundFetchResult::UNSET) + record->UpdateState(BackgroundFetchRecord::State::kSettled); +} + +bool BackgroundFetchRegistration::IsAborted() { + return failure_reason_ == + mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI || + failure_reason_ == + mojom::BackgroundFetchFailureReason::CANCELLED_BY_DEVELOPER; +} + void BackgroundFetchRegistration::DidAbort( ScriptPromiseResolver* resolver, mojom::blink::BackgroundFetchError error) { @@ -333,6 +373,7 @@ void BackgroundFetchRegistration::Trace(Visitor* visitor) { visitor->Trace(registration_); + visitor->Trace(records_); EventTargetWithInlineData::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h index dbfdbf4..715709c42 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -12,10 +12,12 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { +class BackgroundFetchRecord; class CacheQueryOptions; class ScriptPromiseResolver; class ScriptState; @@ -111,8 +113,18 @@ bool return_all, Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches); + // Updates the |record| with a |response|, if one is available, else marks + // the |record|'s request as aborted or failed. + void UpdateRecord(BackgroundFetchRecord* record, + mojom::blink::FetchAPIResponsePtr& response); + + bool IsAborted(); + Member<ServiceWorkerRegistration> registration_; + // TODO(crbug.com/774054): Update the key once we support duplicate requests. + HeapHashMap<KURL, Member<BackgroundFetchRecord>> records_; + // Corresponds to IDL 'id' attribute. Not unique - an active registration can // have the same |developer_id_| as one or more inactive registrations. String developer_id_;
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc b/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc index 553b6af..aaae8633 100644 --- a/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc +++ b/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
@@ -39,7 +39,7 @@ const Vector<AtomicString>& custom_invalidation_properties, const Vector<CSSSyntaxDescriptor>& input_argument_types, const PaintRenderingContext2DSettings* context_settings) { - return new CSSPaintDefinition( + return MakeGarbageCollected<CSSPaintDefinition>( script_state, constructor, paint, native_invalidation_properties, custom_invalidation_properties, input_argument_types, context_settings); }
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_definition.h b/third_party/blink/renderer/modules/csspaint/css_paint_definition.h index 0c43c786..c282c56 100644 --- a/third_party/blink/renderer/modules/csspaint/css_paint_definition.h +++ b/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
@@ -38,6 +38,15 @@ const Vector<AtomicString>& custom_invalidation_properties, const Vector<CSSSyntaxDescriptor>& input_argument_types, const PaintRenderingContext2DSettings*); + + CSSPaintDefinition( + ScriptState*, + v8::Local<v8::Function> constructor, + v8::Local<v8::Function> paint, + const Vector<CSSPropertyID>& native_invalidation_properties, + const Vector<AtomicString>& custom_invalidation_properties, + const Vector<CSSSyntaxDescriptor>& input_argument_types, + const PaintRenderingContext2DSettings*); virtual ~CSSPaintDefinition(); // Invokes the javascript 'paint' callback on an instance of the javascript @@ -80,15 +89,6 @@ } private: - CSSPaintDefinition( - ScriptState*, - v8::Local<v8::Function> constructor, - v8::Local<v8::Function> paint, - const Vector<CSSPropertyID>& native_invalidation_properties, - const Vector<AtomicString>& custom_invalidation_properties, - const Vector<CSSSyntaxDescriptor>& input_argument_types, - const PaintRenderingContext2DSettings*); - void MaybeCreatePaintInstance(); Member<ScriptState> script_state_;
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc index cd31dcc..b088fc6 100644 --- a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc +++ b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc
@@ -22,9 +22,11 @@ DCHECK(paint_worklet); CSSPaintImageGeneratorImpl* generator; if (paint_worklet->GetDocumentDefinitionMap().Contains(name)) { - generator = new CSSPaintImageGeneratorImpl(paint_worklet, name); + generator = + MakeGarbageCollected<CSSPaintImageGeneratorImpl>(paint_worklet, name); } else { - generator = new CSSPaintImageGeneratorImpl(observer, paint_worklet, name); + generator = MakeGarbageCollected<CSSPaintImageGeneratorImpl>( + observer, paint_worklet, name); paint_worklet->AddPendingGenerator(name, generator); }
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h index 42696148..6fa7f01c 100644 --- a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h +++ b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h
@@ -27,6 +27,9 @@ static CSSPaintImageGenerator* Create(const String& name, const Document&, Observer*); + + CSSPaintImageGeneratorImpl(Observer*, PaintWorklet*, const String&); + CSSPaintImageGeneratorImpl(PaintWorklet*, const String&); ~CSSPaintImageGeneratorImpl() override; // The |container_size| is without subpixel snapping. @@ -52,9 +55,6 @@ void Trace(blink::Visitor*) override; private: - CSSPaintImageGeneratorImpl(Observer*, PaintWorklet*, const String&); - CSSPaintImageGeneratorImpl(PaintWorklet*, const String&); - bool HasDocumentDefinition() const; // This function first checks whether the document definition with |name_| // exists or not. If it does exist, the function fetches the document
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl index 766714c6..d41c1b1c 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl
@@ -6,7 +6,7 @@ [Exposed=Window] interface MediaCapabilities { - [CallWith=ScriptState, Measure, OriginTrialEnabled=MediaCapabilities] Promise<MediaCapabilitiesInfo> decodingInfo(MediaDecodingConfiguration configuration); + [CallWith=ScriptState, Measure] Promise<MediaCapabilitiesInfo> decodingInfo(MediaDecodingConfiguration configuration); [CallWith=ScriptState, Measure, RuntimeEnabled=MediaCapabilitiesEncodingInfo] Promise<MediaCapabilitiesInfo> encodingInfo( MediaEncodingConfiguration configuration); };
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl index 35c1c06..06bf60f 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl
@@ -5,8 +5,7 @@ // https://wicg.github.io/media-capabilities/#mediacapabilitiesinfo [ - Exposed=Window, - OriginTrialEnabled=MediaCapabilities + Exposed=Window ] interface MediaCapabilitiesInfo { [Measure] readonly attribute boolean supported; [Measure] readonly attribute boolean smooth;
diff --git a/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl b/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl index 5f421af..6b00ca4 100644 --- a/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl +++ b/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl
@@ -6,8 +6,7 @@ [ Exposed=Window, - ImplementedAs=NavigatorMediaCapabilities, - OriginTrialEnabled=MediaCapabilities + ImplementedAs=NavigatorMediaCapabilities ] partial interface Navigator { [SameObject] readonly attribute MediaCapabilities mediaCapabilities; };
diff --git a/third_party/blink/renderer/modules/webdatabase/change_version_wrapper.cc b/third_party/blink/renderer/modules/webdatabase/change_version_wrapper.cc index 689a2e54..44d8ee42 100644 --- a/third_party/blink/renderer/modules/webdatabase/change_version_wrapper.cc +++ b/third_party/blink/renderer/modules/webdatabase/change_version_wrapper.cc
@@ -47,7 +47,7 @@ String actual_version; if (!database->GetVersionFromDatabase(actual_version)) { int sqlite_error = database->SqliteDatabase().LastError(); - database->ReportChangeVersionResult(1, SQLError::kUnknownErr, sqlite_error); + database->ReportSqliteError(sqlite_error); sql_error_ = SQLErrorData::Create( SQLError::kUnknownErr, "unable to read the current version", sqlite_error, database->SqliteDatabase().LastErrorMsg()); @@ -55,7 +55,6 @@ } if (actual_version != old_version_) { - database->ReportChangeVersionResult(2, SQLError::kVersionErr, 0); sql_error_ = SQLErrorData::Create(SQLError::kVersionErr, "current version of the database and " "`oldVersion` argument do not match"); @@ -74,7 +73,7 @@ if (!database->SetVersionInDatabase(new_version_)) { int sqlite_error = database->SqliteDatabase().LastError(); - database->ReportChangeVersionResult(3, SQLError::kUnknownErr, sqlite_error); + database->ReportSqliteError(sqlite_error); sql_error_ = SQLErrorData::Create( SQLError::kUnknownErr, "unable to set new version in database", sqlite_error, database->SqliteDatabase().LastErrorMsg()); @@ -83,7 +82,6 @@ database->SetExpectedVersion(new_version_); - database->ReportChangeVersionResult(0, -1, 0); // OK return true; }
diff --git a/third_party/blink/renderer/modules/webdatabase/database.cc b/third_party/blink/renderer/modules/webdatabase/database.cc index d3c597ee4..9ea1af8 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.cc +++ b/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -454,7 +454,6 @@ bool Database::PerformOpenAndVerify(bool should_set_version_in_new_database, DatabaseError& error, String& error_message) { - TimeTicks call_start_time = WTF::CurrentTimeTicks(); DoneCreatingDatabaseOnExitCaller on_exit_caller(this); DCHECK(error_message.IsEmpty()); DCHECK_EQ(error, @@ -465,10 +464,7 @@ const int kMaxSqliteBusyWaitTime = 30000; if (!sqlite_database_.Open(filename_)) { - ReportOpenDatabaseResult( - 1, static_cast<int>(DOMExceptionCode::kInvalidStateError), - sqlite_database_.LastError(), - WTF::CurrentTimeTicks() - call_start_time); + ReportSqliteError(sqlite_database_.LastError()); error_message = FormatErrorMessage("unable to open database", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -512,10 +508,7 @@ SQLiteTransaction transaction(sqlite_database_); transaction.begin(); if (!transaction.InProgress()) { - ReportOpenDatabaseResult( - 2, static_cast<int>(DOMExceptionCode::kInvalidStateError), - sqlite_database_.LastError(), - WTF::CurrentTimeTicks() - call_start_time); + ReportSqliteError(sqlite_database_.LastError()); error_message = FormatErrorMessage( "unable to open database, failed to start transaction", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -531,10 +524,7 @@ "CREATE TABLE " + table_name + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT " "REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { - ReportOpenDatabaseResult( - 3, static_cast<int>(DOMExceptionCode::kInvalidStateError), - sqlite_database_.LastError(), - WTF::CurrentTimeTicks() - call_start_time); + ReportSqliteError(sqlite_database_.LastError()); error_message = FormatErrorMessage( "unable to open database, failed to create 'info' table", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -543,10 +533,7 @@ return false; } } else if (!GetVersionFromDatabase(current_version, false)) { - ReportOpenDatabaseResult( - 4, static_cast<int>(DOMExceptionCode::kInvalidStateError), - sqlite_database_.LastError(), - WTF::CurrentTimeTicks() - call_start_time); + ReportSqliteError(sqlite_database_.LastError()); error_message = FormatErrorMessage( "unable to open database, failed to read current version", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -563,10 +550,7 @@ << " in database " << DatabaseDebugName() << " that was just created"; if (!SetVersionInDatabase(expected_version_, false)) { - ReportOpenDatabaseResult( - 5, static_cast<int>(DOMExceptionCode::kInvalidStateError), - sqlite_database_.LastError(), - WTF::CurrentTimeTicks() - call_start_time); + ReportSqliteError(sqlite_database_.LastError()); error_message = FormatErrorMessage( "unable to open database, failed to write current version", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -594,9 +578,6 @@ // whatever version of the database we have. if ((!new_ || should_set_version_in_new_database) && expected_version_.length() && expected_version_ != current_version) { - ReportOpenDatabaseResult( - 6, static_cast<int>(DOMExceptionCode::kInvalidStateError), 0, - WTF::CurrentTimeTicks() - call_start_time); error_message = "unable to open database, version mismatch, '" + expected_version_ + "' does not match the currentVersion of '" + current_version + "'"; @@ -621,9 +602,6 @@ expected_version_ = ""; } - ReportOpenDatabaseResult(0, -1, 0, - WTF::CurrentTimeTicks() - call_start_time); // OK - if (GetDatabaseContext()->GetDatabaseThread()) GetDatabaseContext()->GetDatabaseThread()->RecordDatabaseOpen(this); return true; @@ -766,69 +744,17 @@ int64_t total_size = sqlite_database_.TotalSize(); if (total_size <= 10 * free_space_size) { int result = sqlite_database_.RunIncrementalVacuumCommand(); - ReportVacuumDatabaseResult(result); - if (result != kSQLResultOk) + if (result != kSQLResultOk) { + ReportSqliteError(result); LogErrorMessage(FormatErrorMessage("error vacuuming database", result, sqlite_database_.LastErrorMsg())); + } } } -// These are used to generate histograms of errors seen with websql. -// See about:histograms in chromium. -void Database::ReportOpenDatabaseResult(int error_site, - int web_sql_error_code, - int sqlite_error_code, - TimeDelta duration) { +void Database::ReportSqliteError(int sqlite_error_code) { if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportOpenDatabaseResult( - WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site, - web_sql_error_code, sqlite_error_code, duration); - } -} - -void Database::ReportChangeVersionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code) { - if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportChangeVersionResult( - WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site, - web_sql_error_code, sqlite_error_code); - } -} - -void Database::ReportStartTransactionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code) { - if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportStartTransactionResult( - WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site, - web_sql_error_code, sqlite_error_code); - } -} - -void Database::ReportCommitTransactionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code) { - if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportCommitTransactionResult( - WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site, - web_sql_error_code, sqlite_error_code); - } -} - -void Database::ReportExecuteStatementResult(int error_site, - int web_sql_error_code, - int sqlite_error_code) { - if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportExecuteStatementResult( - WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site, - web_sql_error_code, sqlite_error_code); - } -} - -void Database::ReportVacuumDatabaseResult(int sqlite_error_code) { - if (Platform::Current()->DatabaseObserver()) { - Platform::Current()->DatabaseObserver()->ReportVacuumDatabaseResult( + Platform::Current()->DatabaseObserver()->ReportSqliteError( WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), sqlite_error_code); }
diff --git a/third_party/blink/renderer/modules/webdatabase/database.h b/third_party/blink/renderer/modules/webdatabase/database.h index 028fca47..7c42a47 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.h +++ b/third_party/blink/renderer/modules/webdatabase/database.h
@@ -158,23 +158,7 @@ const ChangeVersionData* = nullptr); Vector<String> PerformGetTableNames(); - void ReportOpenDatabaseResult(int error_site, - int web_sql_error_code, - int sqlite_error_code, - TimeDelta duration); - void ReportChangeVersionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code); - void ReportStartTransactionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code); - void ReportCommitTransactionResult(int error_site, - int web_sql_error_code, - int sqlite_error_code); - void ReportExecuteStatementResult(int error_site, - int web_sql_error_code, - int sqlite_error_code); - void ReportVacuumDatabaseResult(int sqlite_error_code); + void ReportSqliteError(int sqlite_error_code); void LogErrorMessage(const String&); static const char* DatabaseInfoTableName(); String DatabaseDebugName() const {
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc b/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc index e3a7b1b..ebbe92a 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc +++ b/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc
@@ -146,15 +146,16 @@ STORAGE_DVLOG(1) << "Unable to verify correctness of statement " << statement_ << " - error " << result << " (" << database->LastErrorMsg() << ")"; - if (result == kSQLResultInterrupt) + if (result == kSQLResultInterrupt) { error_ = SQLErrorData::Create(SQLError::kDatabaseErr, "could not prepare statement", result, "interrupted"); - else + } else { error_ = SQLErrorData::Create(SQLError::kSyntaxErr, "could not prepare statement", result, database->LastErrorMsg()); - db->ReportExecuteStatementResult(1, error_->Code(), result); + } + db->ReportSqliteError(result); return false; } @@ -167,7 +168,6 @@ error_ = SQLErrorData::Create( SQLError::kSyntaxErr, "number of '?'s in statement string does not match argument count"); - db->ReportExecuteStatementResult(2, error_->Code(), 0); return false; } @@ -181,7 +181,7 @@ if (result != kSQLResultOk) { STORAGE_DVLOG(1) << "Failed to bind value index " << (i + 1) << " to statement for query " << statement_; - db->ReportExecuteStatementResult(3, SQLError::kDatabaseErr, result); + db->ReportSqliteError(result); error_ = SQLErrorData::Create(SQLError::kDatabaseErr, "could not bind value", result, database->LastErrorMsg()); @@ -206,7 +206,7 @@ } while (result == kSQLResultRow); if (result != kSQLResultDone) { - db->ReportExecuteStatementResult(4, SQLError::kDatabaseErr, result); + db->ReportSqliteError(result); error_ = SQLErrorData::Create(SQLError::kDatabaseErr, "could not iterate results", result, database->LastErrorMsg()); @@ -222,14 +222,14 @@ SetFailureDueToQuota(db); return false; } else if (result == kSQLResultConstraint) { - db->ReportExecuteStatementResult(6, SQLError::kConstraintErr, result); + db->ReportSqliteError(result); error_ = SQLErrorData::Create( SQLError::kConstraintErr, "could not execute statement due to a constraint failure", result, database->LastErrorMsg()); return false; } else { - db->ReportExecuteStatementResult(5, SQLError::kDatabaseErr, result); + db->ReportSqliteError(result); error_ = SQLErrorData::Create(SQLError::kDatabaseErr, "could not execute statement", result, database->LastErrorMsg()); @@ -242,14 +242,12 @@ // For now, this seems sufficient. result_set_->SetRowsAffected(database->LastChanges()); - db->ReportExecuteStatementResult(0, -1, 0); // OK return true; } void SQLStatementBackend::SetVersionMismatchedError(Database* database) { DCHECK(!error_); DCHECK(!result_set_->IsValid()); - database->ReportExecuteStatementResult(7, SQLError::kVersionErr, 0); error_ = SQLErrorData::Create( SQLError::kVersionErr, "current version of the database and `oldVersion` argument do not match"); @@ -258,7 +256,6 @@ void SQLStatementBackend::SetFailureDueToQuota(Database* database) { DCHECK(!error_); DCHECK(!result_set_->IsValid()); - database->ReportExecuteStatementResult(8, SQLError::kQuotaErr, 0); error_ = SQLErrorData::Create(SQLError::kQuotaErr, "there was not enough remaining storage " "space, or the storage quota was reached and "
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc index 6c1024fc..cb048261 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc +++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
@@ -198,13 +198,11 @@ // jump to the error callback. SQLTransactionState next_state = SQLTransactionState::kRunStatements; if (should_deliver_error_callback) { - database_->ReportStartTransactionResult(5, SQLError::kUnknownErr, 0); transaction_error_ = SQLErrorData::Create( SQLError::kUnknownErr, "the SQLTransactionCallback was null or threw an exception"); next_state = SQLTransactionState::kDeliverTransactionErrorCallback; } - database_->ReportStartTransactionResult(0, -1, 0); // OK return next_state; } @@ -249,7 +247,6 @@ execute_sql_allowed_ = false; if (result) { - database_->ReportCommitTransactionResult(2, SQLError::kUnknownErr, 0); transaction_error_ = SQLErrorData::Create(SQLError::kUnknownErr, "the statement callback raised an exception or "
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc b/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc index 9376297..03fc119 100644 --- a/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc +++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc
@@ -616,8 +616,7 @@ // callback if that fails. if (!sqlite_transaction_->InProgress()) { DCHECK(!database_->SqliteDatabase().TransactionInProgress()); - database_->ReportStartTransactionResult( - 2, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError()); + database_->ReportSqliteError(database_->SqliteDatabase().LastError()); transaction_error_ = SQLErrorData::Create( SQLError::kDatabaseErr, "unable to begin transaction", database_->SqliteDatabase().LastError(), @@ -632,8 +631,7 @@ // this is just a map lookup. String actual_version; if (!database_->GetActualVersionForTransaction(actual_version)) { - database_->ReportStartTransactionResult( - 3, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError()); + database_->ReportSqliteError(database_->SqliteDatabase().LastError()); transaction_error_ = SQLErrorData::Create(SQLError::kDatabaseErr, "unable to read version", database_->SqliteDatabase().LastError(), @@ -655,7 +653,6 @@ if (wrapper_->SqlError()) { transaction_error_ = SQLErrorData::Create(*wrapper_->SqlError()); } else { - database_->ReportStartTransactionResult(4, SQLError::kUnknownErr, 0); transaction_error_ = SQLErrorData::Create( SQLError::kUnknownErr, "unknown error occurred during transaction preflight"); @@ -774,7 +771,6 @@ transaction_error_ = SQLErrorData::Create(*current_statement_backend_->SqlError()); } else { - database_->ReportCommitTransactionResult(1, SQLError::kDatabaseErr, 0); transaction_error_ = SQLErrorData::Create( SQLError::kDatabaseErr, "the statement failed to execute"); } @@ -790,7 +786,6 @@ if (wrapper_->SqlError()) { transaction_error_ = SQLErrorData::Create(*wrapper_->SqlError()); } else { - database_->ReportCommitTransactionResult(3, SQLError::kUnknownErr, 0); transaction_error_ = SQLErrorData::Create( SQLError::kUnknownErr, "unknown error occurred during transaction postflight"); @@ -810,8 +805,7 @@ if (sqlite_transaction_->InProgress()) { if (wrapper_) wrapper_->HandleCommitFailedAfterPostflight(this); - database_->ReportCommitTransactionResult( - 4, SQLError::kDatabaseErr, database_->SqliteDatabase().LastError()); + database_->ReportSqliteError(database_->SqliteDatabase().LastError()); transaction_error_ = SQLErrorData::Create( SQLError::kDatabaseErr, "unable to commit transaction", database_->SqliteDatabase().LastError(), @@ -819,8 +813,6 @@ return NextStateForTransactionError(); } - database_->ReportCommitTransactionResult(0, -1, 0); // OK - // Vacuum the database if anything was deleted. if (database_->HadDeletes()) database_->IncrementalVacuumIfNeeded();
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 1d6875e..8e6e055 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -552,6 +552,10 @@ RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable); } +void WebRuntimeFeatures::EnableScriptStreamingOnPreload(bool enable) { + RuntimeEnabledFeatures::SetScriptStreamingOnPreloadEnabled(enable); +} + void WebRuntimeFeatures::EnableExperimentalProductivityFeatures(bool enable) { RuntimeEnabledFeatures::SetExperimentalProductivityFeaturesEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc b/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc index ca71ff996..985601f7 100644 --- a/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc +++ b/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc
@@ -57,7 +57,10 @@ WTF::String* out) { ArrayDataView<uint16_t> view; data.GetDataDataView(&view); - *out = WTF::String(reinterpret_cast<const UChar*>(view.data()), view.size()); + if (view.size() > std::numeric_limits<uint32_t>::max()) + return false; + *out = WTF::String(reinterpret_cast<const UChar*>(view.data()), + static_cast<uint32_t>(view.size())); return true; } @@ -88,12 +91,16 @@ if (size % sizeof(UChar)) return false; + size /= sizeof(UChar); + if (size > std::numeric_limits<uint32_t>::max()) + return false; + // An empty |mojo_base::BigBuffer| may have a null |data()| if empty. if (!size) { *out = g_empty_string; } else { *out = WTF::String(reinterpret_cast<const UChar*>(buffer.data()), - size / sizeof(UChar)); + static_cast<uint32_t>(size)); } return true;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index e386090..98367a83 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -403,7 +403,7 @@ { // http://crbug.com/905922 name: "ElementInternals", - status: "test", + implied_by: ["FormAssociatedCustomElements"], }, { // https://crbug.com/879270 @@ -520,6 +520,10 @@ name: "ForceTallerSelectPopup", }, { + name: "FormAssociatedCustomElements", + status: "test", + }, + { name: "FormDataEvent", status: "experimental", }, @@ -713,11 +717,6 @@ status:"experimental", }, { - name: "MediaCapabilities", - origin_trial_feature_name: "MediaCapabilities", - status: "stable", - }, - { name: "MediaCapabilitiesEncodingInfo", status: "experimental", }, @@ -1098,6 +1097,9 @@ name: "ScriptedSpeechSynthesis", status: "stable", }, + { + name: "ScriptStreamingOnPreload", + }, // Serialize and restore scroll anchors. { name: "ScrollAnchorSerialization",
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc b/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc index 5ea9210..5914e48 100644 --- a/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc +++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc
@@ -168,10 +168,11 @@ } void WebURLLoaderMockFactoryImpl::RunUntilIdle() { - if (platform_) + if (platform_) { platform_->RunUntilIdle(); - else - base::RunLoop().RunUntilIdle(); + } else { + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); + } } void WebURLLoaderMockFactoryImpl::LoadRequest(
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 6d45925f..41216e7 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -233,6 +233,10 @@ 'event_handling_util::.+', 'event_util::.+', 'file_error::.+', + 'inspector_\\w+_event::.+', + 'inspector_async_task::.+', + 'inspector_set_layer_tree_id::.+', + 'inspector_tracing_started_in_frame::.+', 'layout_invalidation_reason::.+', 'media_constraints_impl::.+', 'media_element_parser_helpers::.+',
diff --git a/third_party/sqlite/BUILD.gn b/third_party/sqlite/BUILD.gn index 023c286..70853a8 100644 --- a/third_party/sqlite/BUILD.gn +++ b/third_party/sqlite/BUILD.gn
@@ -174,13 +174,22 @@ } } - if (use_fuzzing_engine && use_sanitizer_coverage && - (is_debug || dcheck_always_on)) { - # Enable SQLite's assert() macros. - defines += [ "SQLITE_DEBUG" ] + if (is_debug || dcheck_always_on) { + if (use_fuzzing_engine && use_sanitizer_coverage) { + # Enable SQLite's assert() macros. + # + # TODO(pwnall): Fix all the bugs preventing us from enabling this flag for + # all DCHECK builds. See https://crbug.com/907371 and + # https://crrev.com/c/1343529. + defines += [ "SQLITE_DEBUG" ] + } # Check preconditions when SQLite APIs are called. See # https://sqlite.org/compile.html#enable_api_armor + # + # fuzzing builds have this disabled because the fuzzers are guaranteed to + # use the API correctly, and removing the checks opens up the possibility + # that the fuzzers will get more code coverage. defines += [ "SQLITE_ENABLE_API_ARMOR" ] } } @@ -195,10 +204,11 @@ # sqlite3Fts3InitTok). cflags += [ "-Wno-unused-function" ] - if (use_fuzzing_engine && use_sanitizer_coverage && - (is_debug || dcheck_always_on)) { + if (is_debug || dcheck_always_on) { cflags += [ - "-Wno-implicit-function-declaration", + # SQLite uses assert(!"description") to express + # NOT_REACHED() << "description". This is considered an implicit + # conversion from char[] to bool, and triggers a warning. "-Wno-string-conversion", ] }
diff --git a/third_party/sqlite/sqlite3_shim.c b/third_party/sqlite/sqlite3_shim.c index 2c03175..c5a94a3 100644 --- a/third_party/sqlite/sqlite3_shim.c +++ b/third_party/sqlite/sqlite3_shim.c
@@ -36,4 +36,17 @@ #endif // defined(__linux__) +// For unfortunately complex reasons, Chrome has release builds where +// DCHECK_IS_ON() (so we want SQLITE_DEBUG to be on) but NDEBUG is also defined. +// This causes declarations for mutex-checking functions used by SQLITE_DEBUG +// code (sqlite3_mutex_held, sqlite3_mutex_notheld) to be omitted, resulting in +// warnings. +// +// The easiest solution for now is to undefine NDEBUG when SQLITE_DEBUG is +// defined. The #undef only takes effect for the SQLite implementation (included +// below), and does not impact any dependency. +#if defined(SQLITE_DEBUG) && defined(NDEBUG) +#undef NDEBUG +#endif // defined(SQLITE_DEBUG) && defined(NDEBUG) + #include "third_party/sqlite/amalgamation/sqlite3.c"
diff --git a/tools/grit/grit/grit_runner.py b/tools/grit/grit/grit_runner.py index e843c9a..09994da 100755 --- a/tools/grit/grit/grit_runner.py +++ b/tools/grit/grit/grit_runner.py
@@ -223,7 +223,7 @@ print ("Help for 'grit %s' (for general help, run 'grit help'):\n" % (tool)) - print _GetToolInfo(tool)[_FACTORY]().__doc__ + _GetToolInfo(tool)[_FACTORY]().ShowUsage() return 0 if not _GetToolInfo(tool): print "No such tool. Try running 'grit help' for a list of tools."
diff --git a/tools/grit/grit/tool/android2grd.py b/tools/grit/grit/tool/android2grd.py index 1c7f5d7..4326209 100644 --- a/tools/grit/grit/tool/android2grd.py +++ b/tools/grit/grit/tool/android2grd.py
@@ -8,6 +8,7 @@ import getopt import os.path import StringIO +import sys from xml.dom import Node import xml.dom.minidom @@ -124,7 +125,8 @@ Android2Grd._HEADER_DIR_FLAG, Android2Grd._XTB_DIR_FLAG, Android2Grd._XML_DIR_FLAG, ] - (opts, args) = getopt.getopt(args, None, ['%s=' % o for o in flags]) + (opts, args) = getopt.getopt( + args, None, ['%s=' % o for o in flags] + ['help']) for key, val in opts: # Get rid of the preceding hypens. @@ -143,6 +145,9 @@ self.xtb_dir = val elif k == Android2Grd._XML_DIR_FLAG: self.xml_res_dir = val + elif k == 'help': + self.ShowUsage() + sys.exit(0) return args def Run(self, opts, args):
diff --git a/tools/grit/grit/tool/build.py b/tools/grit/grit/tool/build.py index cbb9b3ba..43ebe8d 100644 --- a/tools/grit/grit/tool/build.py +++ b/tools/grit/grit/tool/build.py
@@ -163,6 +163,7 @@ replace_ellipsis = True (own_opts, args) = getopt.getopt(args, 'a:p:o:D:E:f:w:t:', ('depdir=','depfile=','assert-file-list=', + 'help', 'output-all-resource-defines', 'no-output-all-resource-defines', 'no-replace-ellipsis', @@ -209,6 +210,9 @@ js_minifier = val elif key == '--whitelist-support': whitelist_support = True + elif key == '--help': + self.ShowUsage() + sys.exit(0) if len(args): print 'This tool takes no tool-specific arguments.'
diff --git a/tools/grit/grit/tool/buildinfo.py b/tools/grit/grit/tool/buildinfo.py index 84075a7..5ef1a01 100644 --- a/tools/grit/grit/tool/buildinfo.py +++ b/tools/grit/grit/tool/buildinfo.py
@@ -7,6 +7,7 @@ import getopt import os +import sys from grit import grd_reader from grit.node import structure @@ -32,10 +33,13 @@ def Run(self, opts, args): """Main method for the buildinfo tool.""" self.output_directory = '.' - (own_opts, args) = getopt.getopt(args, 'o:') + (own_opts, args) = getopt.getopt(args, 'o:', ('help',)) for (key, val) in own_opts: if key == '-o': self.output_directory = val + elif key == '--help': + self.ShowUsage() + sys.exit(0) if len(args) > 0: print 'This tool takes exactly one argument: the output directory via -o' return 2
diff --git a/tools/grit/grit/tool/count.py b/tools/grit/grit/tool/count.py index 61225986..1a45d89 100644 --- a/tools/grit/grit/tool/count.py +++ b/tools/grit/grit/tool/count.py
@@ -5,6 +5,7 @@ '''Count number of occurrences of a given message ID.''' import getopt +import sys from grit import grd_reader from grit.tool import interface @@ -21,7 +22,11 @@ def ParseOptions(self, args): """Set this objects and return all non-option arguments.""" - own_opts, args = getopt.getopt(args, '') + own_opts, args = getopt.getopt(args, '', ('help',)) + for key, val in own_opts: + if key == '--help': + self.ShowUsage() + sys.exit(0) return args def Run(self, opts, args):
diff --git a/tools/grit/grit/tool/diff_structures.py b/tools/grit/grit/tool/diff_structures.py index 719abd27..681d01ec 100644 --- a/tools/grit/grit/tool/diff_structures.py +++ b/tools/grit/grit/tool/diff_structures.py
@@ -7,6 +7,7 @@ import os import getopt +import sys import tempfile from grit.node import structure @@ -48,7 +49,7 @@ def Run(self, global_opts, args): (opts, args) = getopt.getopt(args, 's:e:t:', - ['left_encoding=', 'right_encoding=']) + ('help', 'left_encoding=', 'right_encoding=')) for key, val in opts: if key == '-s': self.section = val @@ -61,6 +62,9 @@ self.left_encoding = val elif key == '--right_encoding': self.right_encoding == val + elif key == '--help': + self.ShowUsage() + sys.exit(0) if len(args) != 2: print "Incorrect usage - 'grit help sdiff' for usage details."
diff --git a/tools/grit/grit/tool/interface.py b/tools/grit/grit/tool/interface.py index 74e8aaa..27fbbb7 100644 --- a/tools/grit/grit/tool/interface.py +++ b/tools/grit/grit/tool/interface.py
@@ -38,6 +38,10 @@ def __init__(self): self.o = None + def ShowUsage(self): + '''Show usage text for this tool.''' + print self.__doc__ + def SetOptions(self, opts): self.o = opts
diff --git a/tools/grit/grit/tool/newgrd.py b/tools/grit/grit/tool/newgrd.py index e5169953..24c863f 100644 --- a/tools/grit/grit/tool/newgrd.py +++ b/tools/grit/grit/tool/newgrd.py
@@ -6,6 +6,7 @@ ''' import getopt +import sys from grit.tool import interface from grit import constants @@ -63,7 +64,11 @@ def ParseOptions(self, args): """Set this objects and return all non-option arguments.""" - own_opts, args = getopt.getopt(args, '') + own_opts, args = getopt.getopt(args, '', ('help',)) + for key, val in own_opts: + if key == '--help': + self.ShowUsage() + sys.exit(0) return args def Run(self, opts, args):
diff --git a/tools/grit/grit/tool/rc2grd.py b/tools/grit/grit/tool/rc2grd.py index c50a11e2..4850e824 100644 --- a/tools/grit/grit/tool/rc2grd.py +++ b/tools/grit/grit/tool/rc2grd.py
@@ -9,6 +9,7 @@ import getopt import re import StringIO +import sys import types import grit.node.empty @@ -156,11 +157,12 @@ self.pre_process = None self.post_process = None - def ParseOptions(self, args): + def ParseOptions(self, args, help_func=None): '''Given a list of arguments, set this object's options and return all non-option arguments. ''' - (own_opts, args) = getopt.getopt(args, 'e:h:u:n:r', ['pre=', 'post=']) + (own_opts, args) = getopt.getopt(args, 'e:h:u:n:r', + ('help', 'pre=', 'post=')) for (key, val) in own_opts: if key == '-e': self.input_encoding = val @@ -176,6 +178,12 @@ self.pre_process = val elif key == '--post': self.post_process = val + elif key == '--help': + if help_func is None: + self.ShowUsage() + else: + help_func() + sys.exit(0) return args def Run(self, opts, args):
diff --git a/tools/grit/grit/tool/resize.py b/tools/grit/grit/tool/resize.py index e5df4492..3891717 100644 --- a/tools/grit/grit/tool/resize.py +++ b/tools/grit/grit/tool/resize.py
@@ -7,6 +7,7 @@ import getopt import os +import sys from grit import grd_reader from grit import pseudo @@ -193,7 +194,7 @@ def Run(self, opts, args): self.SetOptions(opts) - own_opts, args = getopt.getopt(args, 'l:f:c:D:') + own_opts, args = getopt.getopt(args, 'l:f:c:D:', ('help',)) for key, val in own_opts: if key == '-l': self.SetLanguage(val) @@ -205,6 +206,9 @@ if key == '-D': name, val = util.ParseDefine(val) self.defines[name] = val + elif key == '--help': + self.ShowUsage() + sys.exit(0) res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose) res_tree.OnlyTheseTranslations([self.lang])
diff --git a/tools/grit/grit/tool/transl2tc.py b/tools/grit/grit/tool/transl2tc.py index 10a893f..d75e2b5c 100644 --- a/tools/grit/grit/tool/transl2tc.py +++ b/tools/grit/grit/tool/transl2tc.py
@@ -5,6 +5,7 @@ '''The 'grit transl2tc' tool. ''' +import sys from grit import grd_reader from grit import util @@ -59,7 +60,7 @@ if len(args) and args[0] == '-l': self.limits = util.ReadFile(args[1], util.RAW_TEXT).split('\n') args = args[2:] - return self.rc2grd.ParseOptions(args) + return self.rc2grd.ParseOptions(args, help_func=self.ShowUsage) def Run(self, globopt, args): args = self.Setup(globopt, args)
diff --git a/tools/grit/grit/tool/unit.py b/tools/grit/grit/tool/unit.py index 2dba2d93..c78ae0b9 100644 --- a/tools/grit/grit/tool/unit.py +++ b/tools/grit/grit/tool/unit.py
@@ -5,6 +5,7 @@ '''GRIT tool that runs the unit test suite for GRIT.''' import getopt +import sys import unittest import grit.test_suite_all @@ -20,7 +21,11 @@ def ParseOptions(self, args): """Set this objects and return all non-option arguments.""" - own_opts, args = getopt.getopt(args, '') + own_opts, args = getopt.getopt(args, '', ('help',)) + for key, val in own_opts: + if key == '--help': + self.ShowUsage() + sys.exit(0) return args def Run(self, opts, args):
diff --git a/tools/grit/grit/tool/xmb.py b/tools/grit/grit/tool/xmb.py index 3f6eb10..150652b4 100644 --- a/tools/grit/grit/tool/xmb.py +++ b/tools/grit/grit/tool/xmb.py
@@ -7,6 +7,7 @@ import getopt import os +import sys from xml.sax import saxutils @@ -171,7 +172,7 @@ limit_file = None limit_is_grd = False limit_file_dir = None - own_opts, args = getopt.getopt(args, 'l:D:ih') + own_opts, args = getopt.getopt(args, 'l:D:ih', ('help',)) for key, val in own_opts: if key == '-l': limit_file = open(val, 'r') @@ -187,6 +188,9 @@ elif key == '-E': (env_name, env_value) = val.split('=', 1) os.environ[env_name] = env_value + elif key == '--help': + self.ShowUsage() + sys.exit(0) if not len(args) == 1: print ('grit xmb takes exactly one argument, the path to the XMB file ' 'to output.')
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 726c47a6..d6b7111 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -14929,6 +14929,7 @@ <int value="502" label="DeviceDisplayResolution"/> <int value="503" label="PluginVmAllowed"/> <int value="504" label="PluginVmImage"/> + <int value="505" label="CloudManagementEnrollmentMandatory"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -23652,9 +23653,12 @@ <enum name="GetEncryptionKeyAction"> <int value="0" label="Key is successfully found - not first time"/> <int value="1" label="Key is successfully found for the first time"/> - <int value="2" label="Overwriting of the key is prevented"/> - <int value="3" label="Key is added to the Keychain"/> - <int value="4" label="Other error"/> + <int value="2" label="(Obsolete) Overwriting of the key is prevented"/> + <int value="3" label="New key is added to the Keychain"/> + <int value="4" label="Other error during lookup"/> + <int value="5" label="New key was created, old key potentially overwritten"/> + <int value="6" label="New key creation failed, old key not found"/> + <int value="7" label="Error adding a new key"/> </enum> <enum name="GetOutputDeviceInfoCacheHit">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b188f8a1..26ace6f 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3982,6 +3982,40 @@ </summary> </histogram> +<histogram name="Arc.EngagementTime.Background" units="seconds"> + <owner>maajid@google.com</owner> + <owner>shaochuan@google.com</owner> + <owner>shihuis@google.com</owner> + <summary> + Times when user is engaged and ARC++ apps are running in the background, but + the user isn't focusing on an ARC++ app window. See Arc.EngagementTime.Total + for definition of engagement and details. + </summary> +</histogram> + +<histogram name="Arc.EngagementTime.Foreground" units="seconds"> + <owner>maajid@google.com</owner> + <owner>shaochuan@google.com</owner> + <owner>shihuis@google.com</owner> + <summary> + Times when user is engaged and focuses on an ARC++ app window. See + Arc.EngagementTime.Total for definition of engagement and details. + </summary> +</histogram> + +<histogram name="Arc.EngagementTime.Total" units="seconds"> + <owner>maajid@google.com</owner> + <owner>shaochuan@google.com</owner> + <owner>shihuis@google.com</owner> + <summary> + Total user session time (from login to logout) excluding times when user + "disengages": screen is locked or dims down due to user idle. + Engagement time metrics, along with foreground and background time, are only + collected on users with ARC++ enabled. All three metrics are accumulated and + recorded to UMA once a day. + </summary> +</histogram> + <histogram name="Arc.FirstAppLaunchDelay.TimeDelta" units="ms"> <owner>yusukes@google.com</owner> <owner>khmel@google.com</owner> @@ -30589,7 +30623,10 @@ </histogram> <histogram name="Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate" - enum="HttpStatusCodeClass"> + enum="HttpStatusCodeClass" expires_after="2020-01-01"> + <obsolete> + Deprecated 11/2018 in favor of WebApp.Icon.HttpStatusCodeClassOnCreate. + </obsolete> <owner>alancutter@chromium.org</owner> <owner>mgiuca@chromium.org</owner> <summary> @@ -72558,6 +72595,9 @@ </histogram> <histogram name="OSCrypt.EncryptionKeyOverwritingPreventions"> + <obsolete> + Obsolete as of Chrome 72. + </obsolete> <owner>tsabolcec@google.com</owner> <owner>vasilii@chromium.com</owner> <summary> @@ -72567,7 +72607,7 @@ </histogram> <histogram name="OSCrypt.GetEncryptionKeyAction" enum="GetEncryptionKeyAction"> - <owner>tsabolcec@google.com</owner> + <owner>cfroussios@chromium.org</owner> <owner>vasilii@chromium.com</owner> <summary> Action taken when retrieving the encryption key from the Keychain. This @@ -102413,6 +102453,13 @@ </summary> </histogram> +<histogram name="Signin.AndroidGetAccountIdsTime" units="ms"> + <owner>bsazonov@chromium.org</owner> + <summary> + The time it takes to retrieve Gaia ids for all accounts from GoogleAuthUtil. + </summary> +</histogram> + <histogram name="Signin.AndroidGetAccountsTime" units="ms"> <owner>nyquist@chromium.org</owner> <summary> @@ -120148,6 +120195,19 @@ </summary> </histogram> +<histogram name="WebApp.Icon.HttpStatusCodeClassOnCreate" + enum="HttpStatusCodeClass" expires_after="2021-01-01"> + <owner>alancutter@chromium.org</owner> + <owner>mgiuca@chromium.org</owner> + <owner>loyso@chromium.org</owner> + <summary> + The HTTP status code class returned for each icon loaded during a WebApp's + creation. See corresponding + Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate histogram for legacy + extension-based system. + </summary> +</histogram> + <histogram name="Webapp.Install.DisplayMode" enum="WebAppDisplayMode"> <owner>piotrs@chromium.org</owner> <summary> @@ -125246,6 +125306,9 @@ </histogram> <histogram name="websql.Async.OpenTime.Error" units="ms"> + <obsolete> + Deprecated 12/2018. We're no longer monitoring WebSQL performance. + </obsolete> <owner>cmumford@chromium.org</owner> <summary> The time required to try (and fail) to open a Web SQL database. @@ -125253,6 +125316,9 @@ </histogram> <histogram name="websql.Async.OpenTime.Success" units="ms"> + <obsolete> + Deprecated 12/2018. We're no longer monitoring WebSQL performance. + </obsolete> <owner>cmumford@chromium.org</owner> <summary>The time required to successfully open a Web SQL database.</summary> </histogram>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index d047041..e95bdb7 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -5336,12 +5336,24 @@ Number of mouse events that were sent to the page. </summary> </metric> + <metric name="MRUIndex"> + <summary> + Index of the tab in most-recently-used order. A value of N means there are + N tabs more recently used than the one that is being foregrounded or + closed. + </summary> + </metric> <metric name="NavigationEntryCount"> <summary> Number of navigation entries in the tab's NavigationController. Corresponds to the size of the tab's back/forward list. </summary> </metric> + <metric name="NumReactivationBefore"> + <summary> + Number of reactivations that this tab had till now. + </summary> + </metric> <metric name="PageTransitionCoreType"> <summary> Type of the page transition for this navigation. Uses the core values from @@ -5373,6 +5385,18 @@ 10 to limit granularity. </summary> </metric> + <metric name="TimeFromBackgrounded"> + <summary> + Duration in MS from when the tab is backgrounded to when it is brought to + foreground or closed. + </summary> + </metric> + <metric name="TotalTabCount"> + <summary> + Total number of tabs open across all non-incognito browser windows. Helps + contextualize the MRUIndex value. + </summary> + </metric> <metric name="TouchEventCount"> <summary> Number of touch events that were sent to the page. @@ -5385,9 +5409,39 @@ </summary> </metric> <metric name="WindowId"> + <obsolete> + Deprecated 11/2018 in favor of putting window features directly in this + event. + </obsolete> <summary> WindowId of the WindowMetrics entry corresponding to the browser window - containing this tab. + containing this tab. This metrics is not populated from 11/2018 because we + don't need to join this event with other WindowMetrics any more. + </summary> + </metric> + <metric name="WindowIsActive"> + <summary> + Boolean value indicating whether the window is the active (frontmost) + window. + </summary> + </metric> + <metric name="WindowShowState"> + <summary> + Enumeration of the window show state, such as fullscreen or minimized. + Values are enumerated in metrics::WindowMetricsEvent::ShowState. + </summary> + </metric> + <metric name="WindowTabCount"> + <summary> + Number of tabs in the tab strip. Rounded down to the nearest exponential + bucket (with a bucket spacing factor of 1.5). Will be 1 for windows with + only one top-level WebContents, such as app windows. + </summary> + </metric> + <metric name="WindowType"> + <summary> + Enumeration for the type of the window. Values are enumerated in + metrics::WindowMetricsEvent::Type. </summary> </metric> </event>
diff --git a/ui/file_manager/audio_player/elements/BUILD.gn b/ui/file_manager/audio_player/elements/BUILD.gn index 3b3a504..cc51218f 100644 --- a/ui/file_manager/audio_player/elements/BUILD.gn +++ b/ui/file_manager/audio_player/elements/BUILD.gn
@@ -31,7 +31,7 @@ js_library("control_panel") { deps = [ ":repeat_button", - "//third_party/polymer/v1_0/components-chromium/paper-slider:paper-slider-extracted", + "//ui/webui/resources/cr_elements/cr_slider:cr_slider", "//ui/webui/resources/js:assert", ] }
diff --git a/ui/file_manager/audio_player/elements/audio_player.js b/ui/file_manager/audio_player/elements/audio_player.js index 38697f3..9587398b 100644 --- a/ui/file_manager/audio_player/elements/audio_player.js +++ b/ui/file_manager/audio_player/elements/audio_player.js
@@ -20,55 +20,88 @@ * Flag whether the audio is playing or paused. True if playing, or false * paused. */ - playing: - {type: Boolean, observer: 'playingChanged', reflectToAttribute: true}, + playing: { + type: Boolean, + observer: 'playingChanged', + reflectToAttribute: true, + }, /** * Current elapsed time in the current music in millisecond. */ - time: {type: Number, observer: 'timeChanged'}, + time: { + type: Number, + observer: 'onTimeChanged_', + }, /** * Whether the shuffle button is ON. */ - shuffle: {type: Boolean, notify: true}, + shuffle: { + type: Boolean, + notify: true, + }, /** * What mode the repeat button idicates. - * repeat-modes can be "no-repeat", "repeat-all", "repeat-one". + * |repeatMode| can be "no-repeat", "repeat-all", or "repeat-one". */ - repeatMode: {type: String, notify: true}, + repeatMode: { + type: String, + notify: true, + }, /** * The audio volume. 0 is silent, and 100 is maximum loud. */ - volume: {type: Number, notify: true}, + volume: { + type: Number, + notify: true, + }, /** * Whether the playlist is expanded or not. */ - playlistExpanded: {type: Boolean, notify: true}, + playlistExpanded: { + type: Boolean, + notify: true, + }, /** * Whether the artwork is expanded or not. */ - trackInfoExpanded: {type: Boolean, notify: true}, + trackInfoExpanded: { + type: Boolean, + notify: true, + }, /** * Track index of the current track. */ - currentTrackIndex: {type: Number, observer: 'currentTrackIndexChanged'}, + currentTrackIndex: { + type: Number, + observer: 'currentTrackIndexChanged', + }, /** * URL of the current track. (exposed publicly for tests) */ - currenttrackurl: {type: String, value: '', reflectToAttribute: true}, + currenttrackurl: { + type: String, + value: '', + reflectToAttribute: true, + }, /** * The number of played tracks. (exposed publicly for tests) */ - playcount: {type: Number, value: 0, reflectToAttribute: true}, + playcount: { + type: Number, + value: 0, + reflectToAttribute: true, + }, - ariaLabels: {type: Object} + /** @type {AriaLabels} */ + ariaLabels: Object, }, /** @@ -82,8 +115,8 @@ * element is ready. */ ready: function() { - this.$.audioController.addEventListener('dragging-changed', - this.onDraggingChanged_.bind(this)); + this.$.audioController.addEventListener( + 'seeking-changed', this.onSeekingChanged_.bind(this)); this.$.audio.addEventListener('ended', this.onAudioEnded.bind(this)); this.$.audio.addEventListener('error', this.onAudioError.bind(this)); @@ -159,21 +192,6 @@ this.cancelAutoAdvance_(); this.$.audio.pause(); this.currenttrackurl = ''; - this.lastAudioUpdateTime_ = null; - }, - - /** - * Invoked when time is changed. - * @param {number} newValue new time (in ms). - * @param {number} oldValue old time (in ms). - */ - timeChanged: function(newValue, oldValue) { - // Ignores updates from the audio element. - if (this.lastAudioUpdateTime_ === newValue) - return; - - if (this.$.audio.readyState !== 0) - this.$.audio.currentTime = this.time / 1000; }, /** @@ -198,7 +216,6 @@ */ onAudioEnded: function() { this.playcount++; - if(this.repeatMode === "repeat-one") { this.playing = true; this.$.audio.currentTime = 0; @@ -226,10 +243,12 @@ * @private */ onAudioStatusUpdate_: function() { - this.time = (this.lastAudioUpdateTime_ = this.$.audio.currentTime * 1000); + this.playing = !this.$.audio.paused; + // If we're paused due to drag, do not update time. + if (this.playing) + this.time = this.$.audio.currentTime * 1000; if (!Number.isNaN(this.$.audio.duration)) this.duration = this.$.audio.duration * 1000; - this.playing = !this.$.audio.paused; }, /** @@ -396,19 +415,26 @@ /** * Invoked when dragging state of seek bar on control panel is changed. * During the user is dragging it, audio playback is paused temporalily. + * @param {!{detail: {value: boolean}}} e */ - onDraggingChanged_: function() { - if (this.$.audioController.dragging) { - if (this.playing) { - this.wasPlayingOnDragStart_ = true; - this.$.audio.pause(); - } - } else { - if (this.wasPlayingOnDragStart_) { - this.$.audio.play(); - this.wasPlayingOnDragStart_ = false; - } + onSeekingChanged_: function(e) { + if (e.detail.value && this.playing) { + this.$.audio.pause(); + this.wasPlayingOnDragStart_ = true; + return; } + + if (!e.detail.value && this.wasPlayingOnDragStart_) { + this.wasPlayingOnDragStart_ = false; + this.$.audio.play(); + } + }, + + /** @private */ + onTimeChanged_: function() { + const newTime = this.time / 1000; + if (this.$.audio.currentTime != newTime) + this.$.audio.currentTime = newTime; }, /** @@ -424,7 +450,7 @@ * Toggle pause. * @private */ - onTogglePauseEvent_: function(event) { + onTogglePauseEvent_: function() { this.$.audioController.playClick(); }, @@ -432,7 +458,7 @@ * Small skip forward. * @private */ - onSmallForwardSkipEvent_: function(event) { + onSmallForwardSkipEvent_: function() { this.$.audioController.smallSkip(true); }, @@ -440,7 +466,7 @@ * Small skip backword. * @private */ - onSmallBackwordSkipEvent_: function(event) { + onSmallBackwordSkipEvent_: function() { this.$.audioController.smallSkip(false); }, @@ -448,7 +474,7 @@ * Big skip forward. * @private */ - onBigForwardSkipEvent_: function(event) { + onBigForwardSkipEvent_: function() { this.$.audioController.bigSkip(true); }, @@ -456,17 +482,17 @@ * Big skip backword. * @private */ - onBigBackwordSkipEvent_: function(event) { + onBigBackwordSkipEvent_: function() { this.$.audioController.bigSkip(false); }, /** @private */ - onNextTrackEvent_: function(event) { + onNextTrackEvent_: function() { this.onControllerNextClicked(); }, /** @private */ - onPreviousTrackEvent_: function(event) { + onPreviousTrackEvent_: function() { this.onControllerPreviousClicked(); }, });
diff --git a/ui/file_manager/audio_player/elements/control_panel.css b/ui/file_manager/audio_player/elements/control_panel.css index fc599a8..fb25ba7 100644 --- a/ui/file_manager/audio_player/elements/control_panel.css +++ b/ui/file_manager/audio_player/elements/control_panel.css
@@ -85,22 +85,17 @@ top: 8px; /* Should be same as time-container's top padding. */ } -.time-container > .time.disabled { - opacity: 0; -} - .time-container > .time-spacer { opacity: 0; /* This class is intended to be used as invisible spacer. */ } -paper-slider { - cursor: pointer; +.time-volume-controls > cr-slider { + --cr-slider-active-color: rgb(66, 133, 244); + --cr-slider-knob-color: rgb(64, 138, 241); } -.time-volume-controls > paper-slider { - --paper-slider-active-color: rgb(66, 133, 244); - --paper-slider-knob-color: rgb(64, 138, 241); - flex: auto; +cr-slider { + cursor: pointer; } #timeSlider { @@ -113,11 +108,6 @@ width: 82px; } -.media-button.disabled, -paper-slider.disabled { - pointer-events: none; -} - /* Media controls in order of appearance. */ .audio-controls {
diff --git a/ui/file_manager/audio_player/elements/control_panel.html b/ui/file_manager/audio_player/elements/control_panel.html index e93a8d4..ba5f31fb 100644 --- a/ui/file_manager/audio_player/elements/control_panel.html +++ b/ui/file_manager/audio_player/elements/control_panel.html
@@ -6,7 +6,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/font-roboto/roboto.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_slider/cr_slider.html"> <link rel="import" href="chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/foreground/elements/files_icon_button.html"> <link rel="import" href="repeat_button.html"> @@ -61,17 +61,17 @@ <!-- Play/pause button and seek slider in the bottom line. --> <div class="time-container"> <div class="time-spacer">[[computeTimeString_(duration, duration)]]</div> - <div class="time">[[computeDisplayTimeString_(dragging, time, seekingTime, duration)]]</div> + <div class="time">[[computeTimeString_(time, duration)]]</div> </div> - <paper-slider id="timeSlider" max="[[duration]]" value="{{time::change}}"></paper-slider> - + <cr-slider id="timeSlider" max="[[duration]]" value="[[time]]" + on-dragging-changed="onSeekingChanged_" no-keybindings></cr-slider> <!-- Volume button and slider in the bottom line. --> <files-icon-button id="volumeButton" class="volume media-button" on-click="volumeClick"> </files-icon-button> - <paper-slider id="volumeSlider"></paper-slider> + <cr-slider id="volumeSlider"></cr-slider> </div> </div> </template>
diff --git a/ui/file_manager/audio_player/elements/control_panel.js b/ui/file_manager/audio_player/elements/control_panel.js index 2de3266c..9a5dec9e 100644 --- a/ui/file_manager/audio_player/elements/control_panel.js +++ b/ui/file_manager/audio_player/elements/control_panel.js
@@ -14,7 +14,6 @@ * seekSlider: string, * shuffle: string, * unmute: string, - * volume: string, * volumeSlider: string, * }} */ @@ -65,16 +64,7 @@ time: { type: Number, value: 0, - notify: true - }, - - /** - * Current seeking position on the time slider in millisecond. - */ - seekingTime: { - type: Number, - value: 0, - readOnly: true + notify: true, }, /** @@ -82,7 +72,7 @@ */ duration: { type: Number, - value: 0 + value: 0, }, /** @@ -91,7 +81,7 @@ shuffle: { type: Boolean, value: false, - notify: true + notify: true, }, /** @@ -100,8 +90,8 @@ */ repeatMode: { type: String, - value: "no-repeat", - notify: true + value: 'no-repeat', + notify: true, }, /** @@ -112,7 +102,7 @@ value: 50, notify: true, reflectToAttribute: true, - observer: 'volumeChanged_' + observer: 'volumeChanged_', }, /** @@ -121,7 +111,7 @@ playlistExpanded: { type: Boolean, value: false, - notify: true + notify: true, }, /** @@ -130,7 +120,7 @@ dragging: { type: Boolean, value: false, - notify: true + notify: true, }, /** @@ -139,8 +129,8 @@ */ ariaLabels: { type: Object, - observer: 'ariaLabelsChanged_' - } + observer: 'ariaLabelsChanged_', + }, }, /** @@ -148,28 +138,15 @@ * element is ready. */ ready: function() { - var timeSlider = /** @type {PaperSliderElement} */ (this.$.timeSlider); - timeSlider.addEventListener('change', function() { - if (this.dragging) - this.dragging = false; - this._setSeekingTime(0); - }.bind(this)); - timeSlider.addEventListener('immediate-value-change', function() { - this._setSeekingTime(timeSlider.immediateValue); - if (!this.dragging) - this.dragging = true; + var timeSlider = /** @type {!CrSliderElement} */ (this.$.timeSlider); + timeSlider.addEventListener('value-changed', function() { + this.time = timeSlider.value; }.bind(this)); - // Update volume on user inputs for volume slider. - // During a drag operation, the volume should be updated immediately. - var volumeSlider = - /** @type {PaperSliderElement} */ (this.$.volumeSlider); - volumeSlider.addEventListener('change', function() { + var volumeSlider = /** @type {!CrSliderElement} */ (this.$.volumeSlider); + volumeSlider.addEventListener('value-changed', function() { this.volume = volumeSlider.value; }.bind(this)); - volumeSlider.addEventListener('immediate-value-change', function() { - this.volume = volumeSlider.immediateValue; - }.bind(this)); }, /** @@ -206,38 +183,32 @@ }, /** - * Skips min(5 seconds, 10% of duration). * @param {boolean} forward Whether to skip forward/backword. */ smallSkip: function(forward) { - var millisecondsToSkip = Math.min(5000, this.duration / 10); - if (!forward) { - millisecondsToSkip *= -1; - } - this.skip_(millisecondsToSkip); + this.skip_(true /* small */, forward); }, /** - * Skips min(10 seconds, 20% of duration). * @param {boolean} forward Whether to skip forward/backword. */ bigSkip: function(forward) { - var millisecondsToSkip = Math.min(10000, this.duration / 5); - if (!forward) { - millisecondsToSkip *= -1; - } - this.skip_(millisecondsToSkip); + this.skip_(false /* small */, forward); }, /** - * Skips forward/backword. - * @param {number} millis Milliseconds to skip. Set negative value to skip - * backword. + * Skips small min(5 seconds, 10% of duration) or large + * min(10 seconds, 20% of duration). + * @param {boolean} small Whether to skip small/large interval. + * @param {boolean} forward Whether to skip forward/backword. * @private */ - skip_: function(millis) { + skip_: function(small, forward) { + var maxSkip = small ? 5000 : 10000; + var percentOfDuration = (small ? .1 : .2) * this.duration; + var update = (forward ? 1 : -1) * Math.min(maxSkip, percentOfDuration); if (this.duration > 0) - this.time = Math.max(Math.min(this.time + millis, this.duration), 0); + this.time = Math.max(Math.min(this.time + update, this.duration), 0); }, /** @@ -260,23 +231,6 @@ }, /** - * Computes string representation of displayed time. If a user is dragging - * the knob of seek bar, seeking position should be shown. Otherwise, - * playing position should be shown. - * @param {boolean} dragging Whether the know of seek bar is being dragged. - * @param {number} time Time corresponding to the playing position. - * @param {number} seekingTime Time corresponding to the seeking position. - * @param {number} duration Duration of the audio file. - * @return {string} String representation to be displayed as current time. - */ - computeDisplayTimeString_: function(dragging, time, seekingTime, duration) { - if (dragging) - return this.computeTimeString_(seekingTime, duration); - else - return this.computeTimeString_(time, duration); - }, - - /** * Invoked when the playing property is changed. * @param {boolean} playing * @private @@ -304,6 +258,14 @@ }, /** + * @param {{detail: {value: boolean}}} e + * @private + */ + onSeekingChanged_: function(e) { + this.fire('seeking-changed', e.detail); + }, + + /** * Invoked when the ariaLabels property is changed. * @param {Object} ariaLabels * @private @@ -318,7 +280,6 @@ this.$.play.setAttribute('aria-label', this.playing ? ariaLabels.pause : ariaLabels.play); this.$.next.setAttribute('aria-label', ariaLabels.next); - this.$.volumeButton.setAttribute('aria-label', ariaLabels.volume); this.$.playList.setAttribute('aria-label', ariaLabels.playList); this.$.timeSlider.setAttribute('aria-label', ariaLabels.seekSlider); this.$.volumeButton.setAttribute('aria-label',
diff --git a/ui/file_manager/audio_player/js/audio_player.js b/ui/file_manager/audio_player/js/audio_player.js index 81b0804c..f163a52 100644 --- a/ui/file_manager/audio_player/js/audio_player.js +++ b/ui/file_manager/audio_player/js/audio_player.js
@@ -46,6 +46,7 @@ this.player_ = /** @type {AudioPlayerElement} */ (document.querySelector('audio-player')); this.player_.tracks = []; + this.isRtl_ = window.getComputedStyle(this.player_)['direction'] === 'rtl'; /** * Queue to throttle concurrent reading of audio file metadata. @@ -99,6 +100,7 @@ this.errorString_ = ''; this.offlineString_ = ''; chrome.fileManagerPrivate.getStrings(function(strings) { + strings = /** @type {!Object<string>} */ (strings); container.ownerDocument.title = strings['AUDIO_PLAYER_TITLE']; this.errorString_ = strings['AUDIO_ERROR']; this.offlineString_ = strings['AUDIO_OFFLINE']; @@ -389,14 +391,20 @@ this.player_.dispatchEvent(new Event('toggle-pause-event')); break; case 'ArrowUp': - case 'ArrowRight': - if (event.target.id !== 'volumeSlider') - this.player_.dispatchEvent(new Event('small-forward-skip-event')); + this.player_.dispatchEvent(new Event('small-forward-skip-event')); break; case 'ArrowDown': + this.player_.dispatchEvent(new Event('small-backword-skip-event')); + break; + case 'ArrowRight': + var eventName = this.isRtl_ ? 'small-backword-skip-event' : + 'small-forward-skip-event'; + this.player_.dispatchEvent(new Event(eventName)); + break; case 'ArrowLeft': - if (event.target.id !== 'volumeSlider') - this.player_.dispatchEvent(new Event('small-backword-skip-event')); + var eventName = this.isRtl_ ? 'small-forward-skip-event' : + 'small-backword-skip-event'; + this.player_.dispatchEvent(new Event(eventName)); break; case 'l': this.player_.dispatchEvent(new Event('big-forward-skip-event'));
diff --git a/ui/file_manager/externs/background/file_browser_background.js b/ui/file_manager/externs/background/file_browser_background.js index 7f20ef1..fe2395a7 100644 --- a/ui/file_manager/externs/background/file_browser_background.js +++ b/ui/file_manager/externs/background/file_browser_background.js
@@ -13,8 +13,5 @@ */ FileBrowserBackground.prototype.ready = function(callback) {}; -/** @type {!analytics.Tracker} */ -FileBrowserBackground.prototype.tracker; - /** @type {!Object<!Window>} */ FileBrowserBackground.prototype.dialogs;
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index caf75a6..2132981 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -350,7 +350,6 @@ deps = [ ":volume_info_impl", "../../common/js:metrics", - "../../common/js:metrics_events", "../../common/js:util", "//ui/file_manager/base/js:volume_manager_types", ]
diff --git a/ui/file_manager/file_manager/background/js/background.js b/ui/file_manager/file_manager/background/js/background.js index b437db1b..9cce9be 100644 --- a/ui/file_manager/file_manager/background/js/background.js +++ b/ui/file_manager/file_manager/background/js/background.js
@@ -12,9 +12,6 @@ function FileBrowserBackgroundImpl() { BackgroundBase.call(this); - /** @type {!analytics.Tracker} */ - this.tracker = metrics.getTracker(); - /** * Progress center of the background page. * @type {!ProgressCenter}
diff --git a/ui/file_manager/file_manager/background/js/background_scripts.js b/ui/file_manager/file_manager/background/js/background_scripts.js index 8008208..e7288c6 100644 --- a/ui/file_manager/file_manager/background/js/background_scripts.js +++ b/ui/file_manager/file_manager/background/js/background_scripts.js
@@ -5,7 +5,6 @@ // error_counter.js must be loaded before all other scripts of the Files app. // <include src="../../../base/js/error_counter.js"> -// <include src="../../common/js/metrics_events.js"> // <include src="../../common/js/metrics.js"> // <include src="metrics_start.js"> // <include src="../../common/js/lru_cache.js">
diff --git a/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html b/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html index c4fb84d7..1b93d12f 100644 --- a/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html +++ b/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html
@@ -15,7 +15,6 @@ <script src="../../common/js/async_util.js"></script> <script src="../../common/js/metrics_base.js"></script> - <script src="../../common/js/metrics_events.js"></script> <script src="../../common/js/mock_entry.js"></script> <script src="../../../base/js/test_error_reporting.js"></script> <script src="../../../base/js/mock_chrome.js"></script>
diff --git a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js index 79b3020..f425fa7 100644 --- a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js +++ b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js
@@ -171,14 +171,14 @@ test.util.sync.queryAllElements = function( contentWindow, targetQuery, opt_styleNames) { return test.util.sync.deepQueryAllElements( - contentWindow, [targetQuery], opt_styleNames); + contentWindow, targetQuery, opt_styleNames); }; /** * Queries elements inside shadow DOM. * * @param {!Window} contentWindow Window to be tested. - * @param {!Array<string>} targetQuery Query to specify the element. + * @param {string|!Array<string>} targetQuery Query to specify the element. * |targetQuery[0]| specifies the first element(s). |targetQuery[1]| specifies * elements inside the shadow DOM of the first element, and so on. * @param {Array<string>=} opt_styleNames List of CSS property name to be @@ -192,6 +192,8 @@ contentWindow, targetQuery, opt_styleNames) { if (!contentWindow.document) return []; + if (typeof targetQuery === 'string') + targetQuery = [targetQuery]; var elems = test.util.sync.deepQuerySelectorAll_(contentWindow.document, targetQuery);
diff --git a/ui/file_manager/file_manager/common/js/BUILD.gn b/ui/file_manager/file_manager/common/js/BUILD.gn index 1457e31..9d56ac9 100644 --- a/ui/file_manager/file_manager/common/js/BUILD.gn +++ b/ui/file_manager/file_manager/common/js/BUILD.gn
@@ -26,7 +26,6 @@ ":lru_cache", ":metrics", ":metrics_base", - ":metrics_events", ":mock_entry", ":progress_center_common", ":util", @@ -126,8 +125,6 @@ } js_library("metrics") { - # |metrics| and |metrics_events| are for analytics. Don't leak this dependency - # outside of the core files app. visibility = [] visibility = [ "//ui/file_manager/file_manager/*" ] deps = [ @@ -135,21 +132,12 @@ "../../../externs:file_manager_private", "//ui/webui/resources/js:assert", ] - externs_list = [ "//third_party/analytics/externs.js" ] } js_library("metrics_base") { externs_list = [ "$externs_path/metrics_private.js" ] } -js_library("metrics_events") { - visibility = [] - visibility = [ "//ui/file_manager/file_manager/*" ] - deps = [ - ":metrics_base", - ] -} - js_library("mock_entry") { deps = [ ":util", @@ -162,6 +150,7 @@ js_library("unittest_util") { testonly = true + # Only files app tests use this util file. visibility = [] visibility = [ "//ui/file_manager/file_manager/*" ]
diff --git a/ui/file_manager/file_manager/common/js/OWNERS b/ui/file_manager/file_manager/common/js/OWNERS index 9aa5bad..faae3ce8c 100644 --- a/ui/file_manager/file_manager/common/js/OWNERS +++ b/ui/file_manager/file_manager/common/js/OWNERS
@@ -1,8 +1 @@ per-file importer_common*=smckay@chromium.org - -# Changes to analytics reporting structures can have disruptive effects on the -# analytics history of the Files app (e.g. making it hard or impossible to detect trending). Such changes need to be reviewed by someone familiar with the analytics system. -per-file metrics_events.js=set noparent -per-file metrics_events.js=fukino@chromium.org -per-file metrics_events.js=kenobi@chromium.org -per-file metrics_events.js=smckay@chromium.org
diff --git a/ui/file_manager/file_manager/common/js/importer_common.js b/ui/file_manager/file_manager/common/js/importer_common.js index cf5384f..cbcbaa1 100644 --- a/ui/file_manager/file_manager/common/js/importer_common.js +++ b/ui/file_manager/file_manager/common/js/importer_common.js
@@ -772,35 +772,14 @@ * @final * * @param {!Promise<!FileEntry>} fileEntryPromise - * @param {!Promise<!analytics.Tracker>} trackerPromise */ -importer.RuntimeLogger = function(fileEntryPromise, trackerPromise) { - +importer.RuntimeLogger = function(fileEntryPromise) { /** @private {!Promise<!importer.PromisingFileEntry>} */ this.fileEntryPromise_ = fileEntryPromise.then( /** @param {!FileEntry} fileEntry */ function(fileEntry) { return new importer.PromisingFileEntry(fileEntry); }); - - /** @private {!Promise<!analytics.Tracker>} */ - this.trackerPromise_ = trackerPromise; -}; - -/** - * Reports an error to analytics. - * - * @param {string} context MUST NOT contain any dynamic error content, - * only statically defined string will dooooo. - */ -importer.RuntimeLogger.prototype.reportErrorContext_ = function(context) { - this.trackerPromise_.then( - /** @param {!analytics.Tracker} tracker */ - function(tracker) { - tracker.sendException( - context, - false /* fatal */ ); - }); }; /** @override */ @@ -820,7 +799,6 @@ var prefix = '(' + context + ') '; return function(error) { - this.reportErrorContext_(context); var message = prefix + 'Caught error in promise chain.'; // Append error info, if provided, then output the error. @@ -912,35 +890,13 @@ importer.logger_ = new importer.RuntimeLogger( importer.ChromeSyncFilesystem.getOrCreateFileEntry( /** @type {!Promise<string>} */ (rotator().then( - importer.getDebugLogFilename.bind(null, nextLogId)))), - importer.getTracker_()); + importer.getDebugLogFilename.bind(null, nextLogId))))); } return importer.logger_; }; /** - * Fetch analytics.Tracker from background page. - * @return {!Promise<!analytics.Tracker>} - * @private - */ -importer.getTracker_ = function() { - return new Promise( - function(resolve, reject) { - chrome.runtime.getBackgroundPage( - function(/** BackgroundWindow */ opt_background) { - if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError); - } - opt_background.background.ready( - function() { - resolve(opt_background.background.tracker); - }); - }); - }); -}; - -/** * Returns the log ID for the next debug log to use. * @private */
diff --git a/ui/file_manager/file_manager/common/js/metrics.js b/ui/file_manager/file_manager/common/js/metrics.js index f3df13f..09f1f570 100644 --- a/ui/file_manager/file_manager/common/js/metrics.js +++ b/ui/file_manager/file_manager/common/js/metrics.js
@@ -21,86 +21,3 @@ metrics.convertName_ = function(name) { return 'FileBrowser.' + name; }; - -/** @private {analytics.GoogleAnalytics} */ -metrics.analytics_ = null; - -/** @private {analytics.Tracker} */ -metrics.tracker_ = null; - -/** @private {boolean} */ -metrics.enabled_ = false; - -/** @return {!analytics.Tracker} */ -metrics.getTracker = function() { - if (!metrics.tracker_) { - metrics.createTracker_(); - } - return /** @type {!analytics.Tracker} */ (metrics.tracker_); -}; - -/** - * Creates a new analytics tracker. - * @private - */ -metrics.createTracker_ = function() { - var chromeVersion = /Chrome\/([0-9]*)\.[0-9.]*/.exec(navigator.userAgent); - if (chromeVersion && chromeVersion[1]) { - metrics.analytics_ = analytics.getService('Files app', chromeVersion[1]); - } else { - metrics.analytics_ = analytics.getService('Files app', '0.0'); - } - - // Create a tracker, add a filter that only enables analytics when UMA is - // enabled. - const kFilesAppTrackingId = 'UA-38248358-9'; - metrics.tracker_ = metrics.analytics_.getTracker(kFilesAppTrackingId); - metrics.tracker_.addFilter(metrics.umaEnabledFilter_); -}; - -/** - * Queries the chrome UMA enabled setting, and filters hits based on that. - * @param {!analytics.Tracker.Hit} hit - * @return {!goog.async.Deferred} A deferred indicating when the filter has - * completed running. - * @private - */ -metrics.umaEnabledFilter_ = function(hit) { - // TODO(kenobi): Change this to use Promises when analytics supports it. - var deferred = new goog.async.Deferred(); - - chrome.fileManagerPrivate.isUMAEnabled( - function(enabled) { - if (chrome.runtime.lastError) { - console.error(chrome.runtime.lastError.message); - return; - } - assert(enabled !== undefined); - if (!enabled) { - // If UMA was just toggled, reset the analytics ID. - if (metrics.enabled_) { - metrics.clearUserId_(); - } - hit.cancel(); - } - metrics.enabled_ = enabled; - // TODO(sashab): We should call deferred.callback(enabled) here, but - // this can cause strange issues when behind certain VPNs. In the - // meantime, don't call anything, so Analytics is never contacted, which - // prevents this issue. See https://crbug.com/842880 for details. - }); - - return deferred; -}; - -/** - * Clears the previously set analytics user id. - * @return {!Promise} Resolves when the analytics ID has been reset. - */ -metrics.clearUserId_ = function() { - return metrics.analytics_.getConfig().then( - /** @param {!analytics.Config} config */ - function(config) { - config.resetUserId(); - }); -};
diff --git a/ui/file_manager/file_manager/common/js/metrics_events.js b/ui/file_manager/file_manager/common/js/metrics_events.js deleted file mode 100644 index 39fdfa96..0000000 --- a/ui/file_manager/file_manager/common/js/metrics_events.js +++ /dev/null
@@ -1,146 +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. - -// Changes to analytics reporting structures can have disruptive effects on the -// analytics history of the Files app (e.g. making it hard or impossible to -// detect trending). -// -// In general, treat changes to analytics like histogram changes, i.e. make -// additive changes, don't remove or rename existing Dimensions, Events, Labels, -// etc. -// -// Changes to this file will need to be reviewed by someone familiar with the -// analytics system. - -// namespace -var metrics = metrics || metricsBase; - -/** @enum {string} */ -metrics.Categories = { - ACQUISITION: 'Acquisition', - MANAGEMENT: 'Management', - INTERNALS: 'Internals' -}; - -/** - * The values of these enums come from the analytics console. - * @private @enum {number} - */ -metrics.Dimension_ = { - CONSUMER_TYPE: 1, - SESSION_TYPE: 2, - MACHINE_USE: 3 -}; - -/** - * Enumeration of known FSPs used to qualify "providers" - * "screens" on analytics. All FSPs NOT present in this list - * will be reported to analytics as 'provided-unknown'. - * - * NOTE: When an unknown provider is encountered, a separate event will be - * sent to analytics with the id. Consulation of that event will provided - * an indication when a provider is popular enough to be added to the - * whitelist. - * - * These look like extension ids, but are actually provider ids which may - * but don't have to be extension ids. - * - * @enum {string} - */ -metrics.FileSystemProviders = { - oedeeodfidgoollimchfdnbmhcpnklnd: 'ZipUnpacker', - hlffpaajmfllggclnjppbblobdhokjhe: 'File System for Dropbox (YT)', - jbfdfcehgafdbfpniaimfbfomafoadgo: 'File System for OneDrive (YT)', - gbheifiifcfekkamhepkeogobihicgmn: 'SFTP File System (YT)', - dikonaebkejmpbpcnnmfaeopkaenicgf: 'Box for Chrome OS', - iibcngmpkgghccnakicfmgajlkhnohep: 'TED Talks (FB)', - hmckflbfniicjijmdoffagjkpnjgbieh: 'WebDAV File System (YT)', - ibfbhbegfkamboeglpnianlggahglbfi: 'Cloud Storage (FB)', - pmnllmkmjilbojkpgplbdmckghmaocjh: 'Scan (FB)', - mfhnnfciefdpolbelmfkpmhhmlkehbdf: 'File System for SMB/CIFS (YT)', - plmanjiaoflhcilcfdnjeffklbgejmje: 'Add MY Documents (KA)', - mljpablpddhocfbnokacjggdbmafjnon: 'Wicked Good Unarchiver (MF)', - ndjpildffkeodjdaeebdhnncfhopkajk: 'Network File Share for Chrome OS', - gmhmnhjihabohahcllfgjooaoecglhpi: 'LanFolder', - dmboannefpncccogfdikhmhpmdnddgoe: 'ZipArchiver', - - /** - * Native Providers. - */ - '@smb': 'Native Network File Share (SMB)', -}; - -/** - * Returns a new "screen" name for a provided file system type. Returns - * 'unknown' for unknown providers. - * @param {string|undefined} providerId The FSP provider ID. - * @return {string} Name or 'unknown' if extension is unrecognized. - */ -metrics.getFileSystemProviderName = function(providerId) { - return metrics.FileSystemProviders[providerId] || 'unknown'; -}; - -/** - * @enum {!analytics.EventBuilder.Dimension} - */ -metrics.Dimensions = { - CONSUMER_TYPE_MANAGER: { - index: metrics.Dimension_.CONSUMER_TYPE, - value: 'Manage' - }, - CONSUMER_TYPE_IMPORTER: { - index: metrics.Dimension_.CONSUMER_TYPE, - value: 'Import' - }, - SESSION_TYPE_MANAGE: { - index: metrics.Dimension_.SESSION_TYPE, - value: 'Manage' - }, - MACHINE_USE_SINGLE: { - index: metrics.Dimension_.MACHINE_USE, - value: 'Single' - }, - MACHINE_USE_MULTIPLE: { - index: metrics.Dimension_.MACHINE_USE, - value: 'Multiple' - } -}; - -// namespace -metrics.event = metrics.event || {}; - -/** - * Base event builders for files app. - * @private @enum {!analytics.EventBuilder} - */ -metrics.event.Builders_ = { - IMPORT: analytics.EventBuilder.builder() - .category(metrics.Categories.ACQUISITION), - INTERNALS: analytics.EventBuilder.builder() - .category(metrics.Categories.INTERNALS), - MANAGE: analytics.EventBuilder.builder() - .category(metrics.Categories.MANAGEMENT) -}; - -/** @enum {!analytics.EventBuilder} */ -metrics.Management = { - WINDOW_CREATED: metrics.event.Builders_.MANAGE - .action('Window Created') - .dimension(metrics.Dimensions.SESSION_TYPE_MANAGE) - .dimension(metrics.Dimensions.CONSUMER_TYPE_MANAGER) -}; - -/** @enum {!analytics.EventBuilder} */ -metrics.Internals = { - UNRECOGNIZED_FILE_SYSTEM_PROVIDER: metrics.event.Builders_.INTERNALS - .action('Unrecognized File System Provider') -}; - -// namespace -metrics.timing = metrics.timing || {}; - -/** @enum {string} */ -metrics.timing.Variables = { - EXTRACT_THUMBNAIL_FROM_RAW: 'Extract Thumbnail From RAW' -};
diff --git a/ui/file_manager/file_manager/common/js/test_tracker.js b/ui/file_manager/file_manager/common/js/test_tracker.js deleted file mode 100644 index 71006d4..0000000 --- a/ui/file_manager/file_manager/common/js/test_tracker.js +++ /dev/null
@@ -1,78 +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. - -/** - * A tracker to substitute for analytics.Tracker in tests. - * @construtor - * @implements {analytics.Tracker} - */ -TestTracker = function() {}; - -/** - * @param {!analytics.HitType|!analytics.EventBuilder} hitType - * @param {(!analytics.ParameterMap| - * !Object<!analytics.Value>)=} opt_extraParams - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.send = function(hitType, opt_extraParams) { -}; - -/** - * @param {string} description - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.sendAppView = function() {}; - -/** - * @param {string} category - * @param {string} action - * @param {string=} opt_label - * @param {number=} opt_value - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.sendEvent = function() {}; - -/** - * @param {string} network Specifies the social network, for example Facebook - * or Google Plus. - * @param {string} action Specifies the social interaction action. - * For example on Google Plus when a user clicks the +1 button, - * the social action is 'plus'. - * @param {string} target Specifies the target of a social interaction. - * This value is typically a URL but can be any text. - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.sendSocial = function() {}; - -/** - * @param {string=} opt_description Specifies the description of an exception. - * @param {boolean=} opt_fatal Was the exception fatal. - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.sendException = function() {}; - -/** - * @param {string} category Specifies the category of the timing. - * @param {string} variable Specifies the variable name of the timing. - * @param {number} value Specifies the value of the timing. - * @param {string=} opt_label Specifies the optional label of the timing. - * @param {number=} opt_sampleRate - * @return {!goog.async.Deferred} - */ -TestTracker.prototype.sendTiming = function() {}; - -TestTracker.prototype.forceSessionStart = function() {}; - -/** - * @param {string} category - * @param {string} variable - * @param {string=} opt_label - * @param {number=} opt_sampleRate - * @return {!TestTracker.Timing} - */ -TestTracker.prototype.startTiming = function() { - return /** @type {!TestTracker.Timing} */ ({ - send: function() {} - }); -};
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index b62e59b..fc223832 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -238,7 +238,6 @@ ":directory_contents", ":file_watcher", "../../common/js:importer_common", - "../../common/js:metrics_events", "ui:file_list_selection_model", ] externs_list = [
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 9a42ccb..5c66f67 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -21,15 +21,10 @@ * service. * @param {!VolumeManager} volumeManager The volume manager. * @param {!FileOperationManager} fileOperationManager File operation manager. - * @param {!analytics.Tracker} tracker */ function DirectoryModel( - singleSelection, - fileFilter, - metadataModel, - volumeManager, - fileOperationManager, - tracker) { + singleSelection, fileFilter, metadataModel, volumeManager, + fileOperationManager) { this.fileListSelection_ = singleSelection ? new FileListSingleSelectionModel() : new FileListSelectionModel(); @@ -82,9 +77,6 @@ 'entries-changed', this.onEntriesChanged_.bind(this)); - /** @private {!analytics.Tracker} */ - this.tracker_ = tracker; - /** @private {string} */ this.lastSearchQuery_ = ''; } @@ -762,6 +754,7 @@ // Restore leadIndex in case leadName no longer exists. var leadIndex = this.fileListSelection_.leadIndex; var leadEntry = this.getLeadEntry_(); + const isCheckSelectMode = this.fileListSelection_.getCheckSelectMode(); var previousDirContents = this.currentDirContents_; this.currentDirContents_ = dirContents; @@ -780,6 +773,10 @@ this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2, this.getFileList().length) - 1); forceChangeEvent = true; + } else if (isCheckSelectMode) { + // Otherwise, ensure check select mode is retained if it was previously + // active. + this.fileListSelection_.setCheckSelectMode(true); } return forceChangeEvent; }.bind(this)); @@ -1017,65 +1014,11 @@ event.newDirEntry = dirEntry; event.volumeChanged = previousVolumeInfo !== currentVolumeInfo; this.dispatchEvent(event); - - if (currentVolumeInfo && event.volumeChanged) { - this.onVolumeChanged_(assert(currentVolumeInfo)); - } }.bind(this)); }.bind(this, this.changeDirectorySequence_)); }; /** - * Handles volume changed by sending an analytics appView event. - * - * @param {!VolumeInfo} volumeInfo The new volume info. - * @return {!Promise} resolves once handling is done. - * @private - */ -DirectoryModel.prototype.onVolumeChanged_ = function(volumeInfo) { - // NOTE: That dynamic values, like volume name MUST NOT - // be sent to GA as that value can contain PII. - // VolumeType is an enum. - // ... - // But we can do stuff like figure out if this is a media device or vanilla - // removable device. - return Promise.resolve(undefined) - .then( - (/** @this {DirectoryModel} */ - function() { - switch (volumeInfo.volumeType) { - case VolumeManagerCommon.VolumeType.REMOVABLE: - return importer.hasMediaDirectory(volumeInfo.fileSystem.root) - .then( - /** - * @param {boolean} hasMedia - * @return {string} - */ - function(hasMedia) { - return hasMedia ? - volumeInfo.volumeType + ':with-media-dir' : - volumeInfo.volumeType; - }); - case VolumeManagerCommon.VolumeType.PROVIDED: - var providerId = volumeInfo.providerId; - var name = metrics.getFileSystemProviderName(providerId); - // Make note of an unrecognized provider id. When we see - // high counts for a particular id, we should add it to the - // whitelist in metrics_events.js. - if (providerId && name == 'unknown') { - this.tracker_.send( - metrics.Internals.UNRECOGNIZED_FILE_SYSTEM_PROVIDER.label( - providerId)); - } - return volumeInfo.volumeType + ':' + name; - default: - return volumeInfo.volumeType; - } - }).bind(this)) - .then(this.tracker_.sendAppView.bind(this.tracker_)); -}; - -/** * Activates the given directory. * This method: * - Changes the current directory, if the given directory is not the current
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index b69d158e..16b9b48 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -138,11 +138,6 @@ */ this.ui_ = null; - /** - * @private {analytics.Tracker} - */ - this.tracker_ = null; - // -------------------------------------------------------------------------- // Parameters determining the type of file manager. @@ -517,12 +512,6 @@ */ get ui() { return this.ui_; - }, - /** - * @return {analytics.Tracker} - */ - get tracker() { - return this.tracker_; } }; @@ -870,12 +859,6 @@ // Initialize the member variables that depend this.launchParams_. this.dialogType = this.launchParams_.type; - - // We used to share the tracker with background, but due to - // its use of instanceof checks for some functionality - // we really can't do this (as instanceof checks fail across - // different script contexts). - this.tracker_ = metrics.getTracker(); }; /** @@ -1100,12 +1083,8 @@ assert(this.fileOperationManager_); assert(this.metadataModel_); this.directoryModel_ = new DirectoryModel( - singleSelection, - this.fileFilter_, - this.metadataModel_, - this.volumeManager_, - this.fileOperationManager_, - assert(this.tracker_)); + singleSelection, this.fileFilter_, this.metadataModel_, + this.volumeManager_, this.fileOperationManager_); this.folderShortcutsModel_ = new FolderShortcutsDataModel( this.volumeManager_);
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html index d0558749..43337a5f7 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html
@@ -22,7 +22,6 @@ <script src="../../common/js/files_app_entry_types.js"></script> <script src="../../common/js/util.js"></script> <script src="../../common/js/metrics_base.js"></script> - <script src="../../common/js/metrics_events.js"></script> <script src="../../../base/js/volume_manager_types.js"></script> <script src="../../common/js/file_type.js"></script> <script src="../../common/js/importer_common.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/main.js b/ui/file_manager/file_manager/foreground/js/main.js index 9042b3b6..b132d601 100644 --- a/ui/file_manager/file_manager/foreground/js/main.js +++ b/ui/file_manager/file_manager/foreground/js/main.js
@@ -22,8 +22,6 @@ function initializeUI() { fileManager.initializeUI(document.body).then(() => { util.testSendMessage('ready'); - metrics.recordInterval('Load.Total'); - fileManager.tracker.send(metrics.Management.WINDOW_CREATED); }); } @@ -36,6 +34,3 @@ } else { initializeUI(); } - -/** Record script load metric: must be the last line. */ -metrics.recordInterval('Load.Script');
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index dd25735..224b199 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -72,10 +72,6 @@ // <include src="../../../../webui/resources/js/cr/ui/menu.js"> // <include src="../../../../webui/resources/js/cr/ui/menu_button.js"> // <include src="../../../../webui/resources/js/cr/ui/context_menu_handler.js"> -// -// <include src="../../../../webui/resources/js/analytics.js"> -// metrics_events.js must be loaded after the analytics package. -// <include src="../../common/js/metrics_events.js"> (function() { // 'strict mode' is invoked for this scope.
diff --git a/ui/file_manager/file_manager/foreground/js/selection_menu_controller.js b/ui/file_manager/file_manager/foreground/js/selection_menu_controller.js index 7a613c4..579b29d 100644 --- a/ui/file_manager/file_manager/foreground/js/selection_menu_controller.js +++ b/ui/file_manager/file_manager/foreground/js/selection_menu_controller.js
@@ -29,24 +29,20 @@ } /** - * Class name to indicate if the menu was opened by the toolbar button or not. - * @type {string} - * @const - */ -SelectionMenuController.TOOLBAR_MENU = 'toolbar-menu'; - -/** * @private */ SelectionMenuController.prototype.onShowMenu_ = function() { - this.menu_.classList.toggle(SelectionMenuController.TOOLBAR_MENU, true); + this.menu_.classList.toggle('toolbar-menu', true); this.toggleRipple_.activated = true; + // crbug.com 752035 focus still on button, get rid of the tooltip + document.querySelector('files-tooltip').hideTooltip(); }; /** * @private */ SelectionMenuController.prototype.onHideMenu_ = function() { - this.menu_.classList.toggle(SelectionMenuController.TOOLBAR_MENU, false); + // Do not remove 'toolbar-menu' yet, it will be removed at the end of + // FilesMenuItem.setMenuAsAnimating_ to avoid flicker. See crbug.com/862926. this.toggleRipple_.activated = false; };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_menu.js b/ui/file_manager/file_manager/foreground/js/ui/files_menu.js index b09ff9b..d12598d8 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_menu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_menu.js
@@ -107,6 +107,10 @@ if (menuItem instanceof cr.ui.FilesMenuItem) menuItem.setAnimating_(value); } + + if (!value) { + menu.classList.remove('toolbar-menu'); + } }, /**
diff --git a/ui/file_manager/file_manager/test/BUILD.gn b/ui/file_manager/file_manager/test/BUILD.gn index 5808d27..bc93c54 100644 --- a/ui/file_manager/file_manager/test/BUILD.gn +++ b/ui/file_manager/file_manager/test/BUILD.gn
@@ -25,7 +25,6 @@ "crostini_share.js", "crostini_tasks.js", "js/strings.js", - "quick_view.js", "uma.js", ] args = [ "--output=" + rebase_path(output, root_build_dir) ] @@ -41,7 +40,6 @@ ":crostini_mount", ":crostini_share", ":crostini_tasks", - ":quick_view", ":uma", ] } @@ -94,13 +92,6 @@ ] } -js_library("quick_view") { - deps = [ - "js:test_util", - "//ui/webui/resources/js:webui_resource_test", - ] -} - js_library("uma") { deps = [ "js:test_util",
diff --git a/ui/file_manager/file_manager/test/js/test_util.js b/ui/file_manager/file_manager/test/js/test_util.js index d72e773..5bc0099 100644 --- a/ui/file_manager/file_manager/test/js/test_util.js +++ b/ui/file_manager/file_manager/test/js/test_util.js
@@ -240,11 +240,6 @@ test.SharedOption.NONE, 'Sep 30, 2014, 3:30 PM', '.hiddenfile.txt', '51 bytes', 'Plain text'), - mhtml: new test.TestEntryInfo( - test.EntryType.FILE, 'text.txt', 'hello.mhtml', 'text/html', - test.SharedOption.NONE, 'Sep 4, 1998, 12:34 PM', 'hello.mhtml', - '51 bytes', 'HTML document'), - helloInA: new test.TestEntryInfo( test.EntryType.FILE, 'text.txt', 'hello.txt', 'text/plain', test.SharedOption.NONE, 'Sep 4, 1998, 12:34 PM', 'A/hello.txt',
diff --git a/ui/file_manager/file_manager/test/quick_view.js b/ui/file_manager/file_manager/test/quick_view.js deleted file mode 100644 index 62decfe..0000000 --- a/ui/file_manager/file_manager/test/quick_view.js +++ /dev/null
@@ -1,101 +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. - -const quickview = {}; - -/** - * Helper function to open and close Quick View. - * @param {string} file file to open and close. - * @param {function(!Element)=} opt_validate optional validation function that - * receives the QuickView element as argument. - */ -quickview.openCloseQuickView = (file, opt_validate) => { - // Using an image file for testing https://crbug.com/845830. - // If this test starts to take too long on the bots, the image could be - // changed to text file 'hello.txt'. - assertTrue(test.selectFile(file)); - // Press Space key. - assertTrue(test.fakeKeyDown('#file-list', ' ', false, false, false)); - // Wait until Quick View is displayed and files-safe-media.src is set. - return test - .repeatUntil(() => { - let element = document.querySelector('#quick-view'); - if (element && element.shadowRoot) { - element = element.shadowRoot.querySelector('#dialog'); - if (getComputedStyle(element).display === 'block' && - element.querySelector('files-safe-media').src) - return element; - } - return test.pending('Quick View is not opened yet.'); - }) - .then((result) => { - // Run optional validate. - if (opt_validate) - opt_validate(result); - - // Click panel and wait for close. - assertTrue(test.fakeMouseClick(['#quick-view', '#contentPanel'])); - return test.repeatUntil(() => { - if (getComputedStyle(result).display === 'none') - return result; - return test.pending('Quick View is not closed yet.'); - }); - }); -}; - -/** - * Tests opening Quick View for downloads. - */ -quickview.testOpenCloseQuickViewDownloads = (done) => { - test.setupAndWaitUntilReady() - .then(() => { - return quickview.openCloseQuickView('My Desktop Background.png'); - }) - .then(() => { - // Add hello.mhtml file and verify background is white. - const entriesWithMhtml = - test.BASIC_LOCAL_ENTRY_SET.concat([test.ENTRIES.mhtml]); - test.addEntries(entriesWithMhtml, [], []); - assertTrue(test.fakeMouseClick('#refresh-button'), 'click refresh'); - return test.waitForFiles( - test.TestEntryInfo.getExpectedRows(entriesWithMhtml)); - }) - .then(() => { - return quickview.openCloseQuickView('hello.mhtml', (qv) => { - const htmlPanel = qv.querySelector( - '#innerContentPanel files-safe-media[type="html"]'); - const style = window.getComputedStyle(htmlPanel); - // White background is 'rgb(255, 255, 255)'. - assertEquals('rgb(255, 255, 255)', style.backgroundColor, 'bg white'); - }); - }) - .then(() => { - done(); - }); -}; - -/** - * Tests opening Quick View for crostini. - */ -quickview.testOpenCloseQuickViewCrostini = (done) => { - test.setupAndWaitUntilReady() - .then(() => { - test.mountCrostini(); - return test.waitForElement( - '#directory-tree [volume-type-icon="crostini"]'); - }) - .then(() => { - assertTrue(test.fakeMouseClick( - '#directory-tree [volume-type-icon="crostini"]')); - return test.waitForFiles( - test.TestEntryInfo.getExpectedRows(test.BASIC_CROSTINI_ENTRY_SET)); - }) - .then(() => { - return quickview.openCloseQuickView('My Desktop Background.png'); - }) - .then(() => { - chrome.fileManagerPrivate.removeMount('crostini'); - done(); - }); -};
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index e351fffb..963ee19 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -907,3 +907,53 @@ }, ]); }; + +/** + * Tests close/open metadata info via Enter key. + */ +testcase.pressEnterOnInfoBoxToOpenClose = function() { + const infoButton = ['#quick-view', '#metadata-button']; + const key = [infoButton, 'Enter', false, false, false]; + const infoShown = ['#quick-view', '#contentPanel[metadata-box-active]']; + const infoHidden = + ['#quick-view', '#contentPanel:not([metadata-box-active])']; + + let appId; + + StepsRunner.run([ + // Open Files app on Downloads containing ENTRIES.hello. + function() { + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []); + }, + // Open the file in Quick View. + function(results) { + appId = results.windowId; + const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); + StepsRunner.run(openSteps).then(this.next); + }, + // Press Enter on info button to close metadata box. + function() { + remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); + }, + // Info should be hidden. + function() { + remoteCall.waitForElement(appId, infoHidden).then(this.next); + }, + // Press Enter on info button to open metadata box. + function() { + remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); + }, + // Info should be shown. + function() { + remoteCall.waitForElement(appId, infoShown).then(this.next); + }, + // Close Quick View. + function() { + StepsRunner.run(closeQuickViewSteps(appId)).then(this.next); + }, + function() { + checkIfNoErrorsOccured(this.next); + }, + ]); +};
diff --git a/ui/file_manager/integration_tests/file_manager/zip_files.js b/ui/file_manager/integration_tests/file_manager/zip_files.js index bcb19608..d7afec5 100644 --- a/ui/file_manager/integration_tests/file_manager/zip_files.js +++ b/ui/file_manager/integration_tests/file_manager/zip_files.js
@@ -159,6 +159,112 @@ }; /** + * Tests encrypted zip file open, and canceling the passphrase dialog. + */ +testcase.zipFileOpenDownloadsEncryptedCancelPassphrase = function() { + let appId; + + const zipArchiverAppId = 'dmboannefpncccogfdikhmhpmdnddgoe'; + const zipArchiverPassphraseDialogUrl = + 'chrome-extension://dmboannefpncccogfdikhmhpmdnddgoe/html/passphrase.html'; + + var cancelPassphraseDialog = function(windowId) { + return sendTestMessage({ + 'name': 'runJsInAppWindow', + 'windowId': windowId, + 'script': + 'document.addEventListener("DOMContentLoaded", function() {document.querySelector("passphrase-dialog").shadowRoot.querySelector("#cancelButton").click();});' + }); + }; + + var waitForAllPassphraseWindowsClosed = function() { + const caller = getCaller(); + + const passphraseWindowCountCommand = { + 'name': 'countAppWindows', + 'appId': zipArchiverAppId + }; + + const getPassphraseWindowIdCommand = { + 'name': 'getAppWindowId', + 'windowUrl': zipArchiverPassphraseDialogUrl + }; + + return repeatUntil(function() { + return sendTestMessage(passphraseWindowCountCommand).then((result) => { + if (result == 0) + return true; + return sendTestMessage(getPassphraseWindowIdCommand) + .then((result) => { + if (result == 'none') + return true; + return cancelPassphraseDialog(result); + }) + .then(function() { + return pending(caller, 'waitForAllPassphraseWindowsClosed'); + }); + }); + }); + }; + + StepsRunner.run([ + // Open Files app on Downloads containing a zip file. + function() { + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.zipArchiveEncrypted], + []); + }, + // Select the zip file. + function(result) { + appId = result.windowId; + remoteCall.callRemoteTestUtil('selectFile', appId, ['encrypted.zip']) + .then(this.next); + }, + // Press the Enter key. + function(result) { + chrome.test.assertTrue(!!result, 'selectFile failed'); + const key = ['#file-list', 'Enter', false, false, false]; + remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); + }, + // Check: the zip file content should be shown (unzip). + function(result) { + chrome.test.assertTrue(!!result, 'fakeKeyDown failed'); + const files = getUnzippedFileListRowEntries(); + remoteCall.waitForFiles(appId, files, {'ignoreLastModifiedTime': true}) + .then(this.next); + }, + // Select the text file in the ZIP file. + function(result) { + remoteCall.callRemoteTestUtil('selectFile', appId, ['text.txt']) + .then(this.next); + }, + // Press the Enter key. + function(result) { + chrome.test.assertTrue(!!result, 'selectFile failed'); + const key = ['#file-list', 'Enter', false, false, false]; + remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); + }, + // Wait for the external passphrase dialog window to appear. + function(result) { + chrome.test.assertTrue(!!result, 'fakeKeyDown failed'); + waitForAppWindow(zipArchiverPassphraseDialogUrl).then(this.next); + }, + // Close the dialog by pressing the 'Cancel' button. Repeat for any new + // dialogs that pop up. + function(result) { + waitForAllPassphraseWindowsClosed().then(this.next); + }, + // Check: the zip file content should still be shown. + function(result) { + chrome.test.assertTrue(!!result, 'fakeKeyDown failed'); + const files = getUnzippedFileListRowEntries(); + remoteCall.waitForFiles(appId, files, {'ignoreLastModifiedTime': true}) + .then(this.next); + }, + ]); +}; + +/** * Tests zip file open (aka unzip) from Google Drive. */ testcase.zipFileOpenDrive = function() {
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js index 626a83dc..1934587e 100644 --- a/ui/file_manager/integration_tests/remote_call.js +++ b/ui/file_manager/integration_tests/remote_call.js
@@ -184,7 +184,10 @@ /** * Waits for the specified element appearing in the DOM. * @param {string} windowId Target window ID. - * @param {string} query Query string for the element. + * @param {string|!Array<string>} query Query to specify the element. + * If query is an array, |query[0]| specifies the first + * element(s), |query[1]| specifies elements inside the shadow DOM of + * the first element, and so on. * @return {Promise} Promise to be fulfilled when the element appears. */ RemoteCall.prototype.waitForElement = function(windowId, query) { @@ -194,7 +197,10 @@ /** * Waits for the specified element appearing in the DOM. * @param {string} windowId Target window ID. - * @param {string} query Query string for the element. + * @param {string|!Array<string>} query Query to specify the element. + * If query is an array, |query[0]| specifies the first + * element(s), |query[1]| specifies elements inside the shadow DOM of + * the first element, and so on. * @param {!Array<string>} styleNames List of CSS property name to be * obtained. NOTE: Causes element style re-calculation. * @return {Promise} Promise to be fulfilled when the element appears. @@ -204,7 +210,8 @@ var caller = getCaller(); return repeatUntil(() => { return this - .callRemoteTestUtil('queryAllElements', windowId, [query, styleNames]) + .callRemoteTestUtil( + 'deepQueryAllElements', windowId, [query, styleNames]) .then(function(elements) { if (elements.length > 0) return elements[0]; @@ -248,13 +255,16 @@ /** * Waits for the specified element leaving from the DOM. * @param {string} windowId Target window ID. - * @param {string} query Query string for the element. + * @param {string|!Array<string>} query Query to specify the element. + * If query is an array, |query[0]| specifies the first + * element(s), |query[1]| specifies elements inside the shadow DOM of + * the first element, and so on. * @return {Promise} Promise to be fulfilled when the element is lost. */ RemoteCall.prototype.waitForElementLost = function(windowId, query) { var caller = getCaller(); return repeatUntil(function() { - return this.callRemoteTestUtil('queryAllElements', windowId, [query]) + return this.callRemoteTestUtil('deepQueryAllElements', windowId, [query]) .then(function(elements) { if (elements.length > 0) return pending(caller, 'Elements %j is still exists.', elements); @@ -266,7 +276,10 @@ /** * Sends a fake key down event. * @param {string} windowId Window ID. - * @param {string} query Query for the target element. + * @param {string|!Array<string>} query Query to specify the element. + * If query is an array, |query[0]| specifies the first + * element(s), |query[1]| specifies elements inside the shadow DOM of + * the first element, and so on. * @param {string} key DOM UI Events Key value. * @param {boolean} ctrlKey Control key flag. * @param {boolean} shiftKey Shift key flag. @@ -642,7 +655,10 @@ /** * Shorthand for clicking an element. * @param {AppWindow} appWindow Application window. - * @param {string} query Query for the element. + * @param {string|!Array<string>} query Query to specify the element. + * If query is an array, |query[0]| specifies the first + * element(s), |query[1]| specifies elements inside the shadow DOM of + * the first element, and so on. * @param {Promise} Promise to be fulfilled with the clicked element. */ RemoteCallGallery.prototype.waitAndClickElement = function(windowId, query) {
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js index 806bb8c6..28c69a5a 100644 --- a/ui/file_manager/integration_tests/test_util.js +++ b/ui/file_manager/integration_tests/test_util.js
@@ -193,6 +193,43 @@ } /** + * Waits for an app window with the URL |windowUrl|. + * @param {string} windowUrl URL of the app window to wait for. + * @return {Promise} Promise to be fulfilled with the window ID of the + * app window. + */ +function waitForAppWindow(windowUrl) { + const caller = getCaller(); + const command = {'name': 'getAppWindowId', 'windowUrl': windowUrl}; + return repeatUntil(function() { + return sendTestMessage(command).then((result) => { + if (result == 'none') + return pending(caller, 'getAppWindowId ' + windowUrl); + return result; + }); + }); +} + +/** + * Wait for the count of windows for app |appId| to equal |expectedCount|. + * @param{string} appId ID of the app to count windows for. + * @param{number} expectedCount Number of app windows to wait for. + * @return {Promise} Promise to be fulfilled when the number of app windows + * equals |expectedCount|. + */ +function waitForAppWindowCount(appId, expectedCount) { + const caller = getCaller(); + const command = {'name': 'countAppWindows', 'appId': appId}; + return repeatUntil(function() { + return sendTestMessage(command).then((result) => { + if (result != expectedCount) + return pending(caller, 'waitForAppWindowCount ' + appId + ' ' + result); + return true; + }); + }); +} + +/** * Adds the givin entries to the target volume(s). * @param {Array<string>} volumeNames Names of target volumes. * @param {Array<TestEntryInfo>} entries List of entries to be added. @@ -704,6 +741,17 @@ typeText: 'Zip archive' }), + zipArchiveEncrypted: new TestEntryInfo({ + type: EntryType.FILE, + sourceFileName: 'encrypted.zip', + targetPath: 'encrypted.zip', + mimeType: 'application/x-zip', + lastModifiedTime: 'Jan 1, 2014, 1:00 AM', + nameText: 'encrypted.zip', + sizeText: '589 bytes', + typeText: 'Zip archive' + }), + debPackage: new TestEntryInfo({ type: EntryType.FILE, sourceFileName: 'package.deb',
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 2b4458cf..46dd6934 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc
@@ -231,7 +231,7 @@ const uint16_t* glyphs, size_t glyph_count) { SkTextBlobBuilder builder; - const auto& run_buffer = builder.allocRunPos(flags_.ToSkPaint(), glyph_count); + const auto& run_buffer = builder.allocRunPos(flags_.ToSkFont(), glyph_count); static_assert(sizeof(*glyphs) == sizeof(*run_buffer.glyphs), ""); memcpy(run_buffer.glyphs, glyphs, glyph_count * sizeof(*glyphs));
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_generator.cc b/ui/ozone/common/gpu/ozone_gpu_message_generator.cc index d3032ed..d2f07ee 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_generator.cc +++ b/ui/ozone/common/gpu/ozone_gpu_message_generator.cc
@@ -10,10 +10,6 @@ #include "ipc/struct_constructor_macros.h" #include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" - // Generate param traits write methods. #include "ipc/param_traits_write_macros.h" namespace IPC {
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html index b7cf964..ca0c7e2a 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -44,7 +44,7 @@ } #bar { - border-top-color: var(--google-blue-600); + border-top-color: var(--cr-slider-active-color, --google-blue-600); height: 2px; left: 0; position: absolute; @@ -53,7 +53,7 @@ width: 0; } - :host-context([dir=rtl]) #bar { + :host([is-rtl_]) #bar { left: initial; right: 0; } @@ -66,7 +66,7 @@ } #knob { - background-color: var(--google-blue-600); + background-color: var(--cr-slider-knob-color, --google-blue-600); border: 0; border-radius: 50%; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4); @@ -88,7 +88,7 @@ width: 32px; } - :host-context([dir=rtl]) paper-ripple { + :host([is-rtl_]) paper-ripple { left: auto; right: -11px; }
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js index 7200f44..c2671d9 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -62,6 +62,7 @@ dragging: { type: Boolean, value: false, + notify: true, reflectToAttribute: true, }, @@ -80,6 +81,16 @@ value: 0, }, + /** + * When set to false, the keybindings are not handled by this component, + * for example when the owner of the component wants to set up its own + * keybindings. + */ + noKeybindings: { + type: Boolean, + value: false, + }, + snaps: { type: Boolean, value: false, @@ -135,6 +146,13 @@ type: String, value: '', }, + + /** @private */ + isRtl_: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, }, hostAttributes: { @@ -157,15 +175,13 @@ /** @private {Map<string, number>} */ deltaKeyMap_: null, - /** @private {boolean} */ - isRtl_: false, /** @private {EventTracker} */ draggingEventTracker_: null, /** @override */ attached: function() { - this.isRtl_ = this.matches(':host-context([dir=rtl]) cr-slider'); + this.isRtl_ = window.getComputedStyle(this)['direction'] === 'rtl'; this.deltaKeyMap_ = new Map([ ['ArrowDown', -1], ['ArrowUp', 1], @@ -234,15 +250,17 @@ * @private */ stopDragging_: function(pointerId) { - this.dragging = false; - this.draggingEventTracker_.removeAll(); + // Update |value| before updating |dragging| so dragging-changed event + // handlers will have access to the updated |value|. this.value = this.immediateValue_; + this.draggingEventTracker_.removeAll(); + this.releasePointerCapture(pointerId); + this.dragging = false; // If there is a ripple animation in progress, setTimeout will hold off // on updating |holdDown_|. setTimeout(() => { this.holdDown_ = false; }); - this.releasePointerCapture(pointerId); }, /** @private */ @@ -271,25 +289,28 @@ * @private */ onKeyDown_: function(event) { - if (this.disabled_) + if (this.disabled_ || this.noKeybindings) return; if (event.metaKey || event.shiftKey || event.altKey || event.ctrlKey) return; let handled = true; - if (event.key == 'Home') - this.value = this.min; - else if (event.key == 'End') - this.value = this.max; - else if (this.deltaKeyMap_.has(event.key)) { + if (event.key == 'Home') { + this.immediateValue_ = this.min; + } else if (event.key == 'End') { + this.immediateValue_ = this.max; + } else if (this.deltaKeyMap_.has(event.key)) { const newValue = this.value + this.deltaKeyMap_.get(event.key); - this.value = clamp(this.min, this.max, newValue); - } else + this.immediateValue_ = clamp(this.min, this.max, newValue); + } else { handled = false; + } if (handled) { + this.value = this.immediateValue_; event.preventDefault(); + event.stopPropagation(); setTimeout(() => { this.holdDown_ = true; }); @@ -307,13 +328,13 @@ return; this.dragging = true; + this.updateValueFromClientX_(event.clientX); // If there is a ripple animation in progress, setTimeout will hold off on // updating |holdDown_|. setTimeout(() => { this.$.knob.focus(); this.holdDown_ = true; }); - this.updateValueFromClientX_(event.clientX); this.setPointerCapture(event.pointerId); const stopDragging = this.stopDragging_.bind(this, event.pointerId);
diff --git a/ui/webui/resources/js/cr/ui/list_selection_model.js b/ui/webui/resources/js/cr/ui/list_selection_model.js index a51f2ac9..9f29304 100644 --- a/ui/webui/resources/js/cr/ui/list_selection_model.js +++ b/ui/webui/resources/js/cr/ui/list_selection_model.js
@@ -105,8 +105,14 @@ * @private */ getNearestSelectedIndex_: function(index) { - if (index == -1) + if (index == -1) { + // If no index is provided, pick the first selected index if there is + // one. + if (this.selectedIndexes.length) { + return this.selectedIndexes[0]; + } return -1; + } var result = Infinity; for (var i in this.selectedIndexes_) { @@ -348,8 +354,15 @@ if (oldSelectedItemsCount && !this.selectedIndexes.length && this.length_ && oldLeadIndex != -1) { // All selected items are deleted. We move selection to next item of - // last selected item. - this.selectedIndexes = [Math.min(oldLeadIndex, this.length_ - 1)]; + // last selected item, following it to its new position. + let newSelectedIndex = Math.min(oldLeadIndex, this.length_ - 1); + for (let i = oldLeadIndex + 1; i < permutation.length; ++i) { + if (permutation[i] != -1) { + newSelectedIndex = permutation[i]; + break; + } + } + this.selectedIndexes = [newSelectedIndex]; } this.endChange();
diff --git a/webrunner/browser/frame_impl_browsertest.cc b/webrunner/browser/frame_impl_browsertest.cc index dd120a5..3a3f359 100644 --- a/webrunner/browser/frame_impl_browsertest.cc +++ b/webrunner/browser/frame_impl_browsertest.cc
@@ -389,7 +389,8 @@ } // Test JS injection by using Javascript to trigger document navigation. -IN_PROC_BROWSER_TEST_F(FrameImplTest, ExecuteJavaScriptImmediate) { +// Flaky: https://crbug.com/907859 +IN_PROC_BROWSER_TEST_F(FrameImplTest, DISABLED_ExecuteJavaScriptImmediate) { chromium::web::FramePtr frame = CreateFrame(); ASSERT_TRUE(embedded_test_server()->Start());