diff --git a/DEPS b/DEPS index 82f1db1..85dd6ce 100644 --- a/DEPS +++ b/DEPS
@@ -121,7 +121,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': '88bfed46ab6e0e4aec5416092a349e394c72ba59', + 'skia_revision': '569dda7216cda3f096677df29ee787e44ddb0be0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -133,7 +133,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': '48d040e8c5241d22ba04746de1fb920268a25aeb', + 'angle_revision': 'cf9383ed325c2833f809377d29cafd0e735a1d4c', # 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. @@ -141,11 +141,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'ebe5f7fad06476b2828271977ee0d56ee45385ac', + 'swiftshader_revision': 'debaacab10b59cdd5a6e636be23e9ab560a7cec7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '7a629886aed968d8bfcabfe48cd898465e4ef469', + 'pdfium_revision': '0e08d591129048435706e2b7e7abd7164714233a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -185,7 +185,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': 'b6cc5a6baf93cfa6feeb240eea75c454506b0c3c', + 'catapult_revision': 'da7318dd0eeb291214442bd53cd71a13447b8fed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -694,7 +694,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2e5e7db63cd9aaa4d7052b10fe18f54f4acbfa26', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '387002d1535da658f3dc7a55ad7815c2256d36f5', 'condition': 'checkout_linux', }, @@ -719,7 +719,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '39b0b8e32a4ed0675a38d97799e8a219cc549910', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4f738c1fe58170ab1bc849381d62d28222920815', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1217,7 +1217,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'db52df17f0d012983dc281e4864c71485a86bd0e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '01f64e0eb22d855fc769b6976ba62dd0d94a071a', + Var('webrtc_git') + '/src.git' + '@' + '63470298753ad575ae21b00bf9da14c023709617', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1258,7 +1258,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2cde328881f0aaec7d59c81f2b861d4fbace3d10', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@87ab0aef9c54e1f465a400a87ed8324d64de8b98', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS index a8c7224..ad8baca 100644 --- a/android_webview/browser/DEPS +++ b/android_webview/browser/DEPS
@@ -35,6 +35,7 @@ "+components/visitedlink/browser", "+components/viz/common", "+components/viz/service/display", + "+components/viz/service/display_embedder", "+components/viz/service/frame_sinks", "+components/viz/test", "+components/webdata/common",
diff --git a/android_webview/browser/aw_gl_surface.cc b/android_webview/browser/aw_gl_surface.cc index 6ed2a73..073faa21 100644 --- a/android_webview/browser/aw_gl_surface.cc +++ b/android_webview/browser/aw_gl_surface.cc
@@ -8,7 +8,7 @@ namespace android_webview { -AwGLSurface::AwGLSurface() {} +AwGLSurface::AwGLSurface() : size_(1, 1) {} AwGLSurface::~AwGLSurface() {} @@ -29,7 +29,7 @@ } gfx::Size AwGLSurface::GetSize() { - return gfx::Size(1, 1); + return size_; } void* AwGLSurface::GetHandle() { @@ -44,4 +44,12 @@ return gl::GLSurfaceFormat(); } +bool AwGLSurface::Resize(const gfx::Size& size, + float scale_factor, + ColorSpace color_space, + bool has_alpha) { + size_ = size; + return true; +} + } // namespace android_webview
diff --git a/android_webview/browser/aw_gl_surface.h b/android_webview/browser/aw_gl_surface.h index 37ac0ae0..3640c8e 100644 --- a/android_webview/browser/aw_gl_surface.h +++ b/android_webview/browser/aw_gl_surface.h
@@ -26,11 +26,16 @@ void* GetHandle() override; void* GetDisplay() override; gl::GLSurfaceFormat GetFormat() override; + bool Resize(const gfx::Size& size, + float scale_factor, + ColorSpace color_space, + bool has_alpha) override; protected: ~AwGLSurface() override; private: + gfx::Size size_; DISALLOW_COPY_AND_ASSIGN(AwGLSurface); };
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc index cbd1f38..569c2f5 100644 --- a/android_webview/browser/surfaces_instance.cc +++ b/android_webview/browser/surfaces_instance.cc
@@ -14,17 +14,23 @@ #include "android_webview/browser/parent_output_surface.h" #include "base/stl_util.h" #include "components/viz/common/display/renderer_settings.h" +#include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/common/quads/surface_draw_quad.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" +#include "components/viz/service/display_embedder/skia_output_surface_impl.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "gpu/command_buffer/service/shared_context_state.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/transform.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_share_group.h" +#include "ui/gl/init/gl_factory.h" namespace android_webview { @@ -33,6 +39,11 @@ // from RenderWidgetHostImpl. constexpr uint32_t kDefaultClientId = 0u; SurfacesInstance* g_surfaces_instance = nullptr; + +void OnContextLost() { + NOTREACHED() << "Non owned context lost!"; +} + } // namespace // static @@ -54,12 +65,14 @@ // Webview does not own the surface so should not clear it. settings.should_clear_root_render_pass = false; + settings.use_skia_renderer = features::IsUsingSkiaRenderer(); + // The SharedBitmapManager is null as we do not support or use software // compositing on Android. frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>( /*shared_bitmap_manager=*/nullptr); - parent_local_surface_id_allocator_.reset( - new viz::ParentLocalSurfaceIdAllocator()); + parent_local_surface_id_allocator_ = + std::make_unique<viz::ParentLocalSurfaceIdAllocator>(); constexpr bool is_root = true; constexpr bool needs_sync_points = true; @@ -67,19 +80,47 @@ this, frame_sink_manager_.get(), frame_sink_id_, is_root, needs_sync_points); - begin_frame_source_.reset(new viz::StubBeginFrameSource); - std::unique_ptr<ParentOutputSurface> output_surface_holder( - new ParentOutputSurface(AwRenderThreadContextProvider::Create( - base::WrapRefCounted(new AwGLSurface), - DeferredGpuCommandService::GetInstance()))); - output_surface_ = output_surface_holder.get(); + std::unique_ptr<viz::OutputSurface> output_surface; + viz::SkiaOutputSurface* skia_output_surface = nullptr; + if (settings.use_skia_renderer) { + auto* task_executor = DeferredGpuCommandService::GetInstance(); + if (!shared_context_state_) { + auto surface = base::MakeRefCounted<AwGLSurface>(); + auto gl_context = + gl::init::CreateGLContext(task_executor->share_group().get(), + surface.get(), gl::GLContextAttribs()); + gl_context->MakeCurrent(surface.get()); + shared_context_state_ = base::MakeRefCounted<gpu::SharedContextState>( + task_executor->share_group(), std::move(surface), + std::move(gl_context), false /* use_virtualized_gl_contexts */, + base::BindOnce(&OnContextLost), + nullptr /* vulkan_context_provider */); + shared_context_state_->InitializeGrContext( + gpu::GpuDriverBugWorkarounds(task_executor->gpu_feature_info() + .enabled_gpu_driver_bug_workarounds), + nullptr /* gr_shader_cache */); + } + output_surface = std::make_unique<viz::SkiaOutputSurfaceImpl>( + task_executor, base::MakeRefCounted<AwGLSurface>(), + shared_context_state_); + skia_output_surface = + static_cast<viz::SkiaOutputSurface*>(output_surface.get()); + } else { + auto context_provider = AwRenderThreadContextProvider::Create( + base::MakeRefCounted<AwGLSurface>(), + DeferredGpuCommandService::GetInstance()); + output_surface = + std::make_unique<ParentOutputSurface>(std::move(context_provider)); + } + + begin_frame_source_ = std::make_unique<viz::StubBeginFrameSource>(); auto scheduler = std::make_unique<viz::DisplayScheduler>( begin_frame_source_.get(), nullptr /* current_task_runner */, - output_surface_holder->capabilities().max_frames_pending); + output_surface->capabilities().max_frames_pending); display_ = std::make_unique<viz::Display>( nullptr /* shared_bitmap_manager */, settings, frame_sink_id_, - std::move(output_surface_holder), std::move(scheduler), - nullptr /* current_task_runner */); + std::move(output_surface), std::move(scheduler), + nullptr /* current_task_runner */, skia_output_surface); display_->Initialize(this, frame_sink_manager_->surface_manager(), false /* enable_shared_images */); frame_sink_manager_->RegisterBeginFrameSource(begin_frame_source_.get(), @@ -95,6 +136,8 @@ DCHECK_EQ(g_surfaces_instance, this); frame_sink_manager_->UnregisterBeginFrameSource(begin_frame_source_.get()); g_surfaces_instance = nullptr; + display_ = nullptr; + DCHECK(!shared_context_state_ || shared_context_state_->HasOneRef()); DCHECK(child_ids_.empty()); } @@ -169,6 +212,10 @@ support_->SubmitCompositorFrame(root_id_allocation_.local_surface_id(), std::move(frame)); + if (shared_context_state_) { + // GL state could be changed across frames, so we need reset GrContext. + shared_context_state_->PessimisticallyResetGrContext(); + } display_->Resize(viewport); display_->DrawAndSwap(); display_->DidReceiveSwapBuffersAck();
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/surfaces_instance.h index b9dc83d..b2cc5cb 100644 --- a/android_webview/browser/surfaces_instance.h +++ b/android_webview/browser/surfaces_instance.h
@@ -23,18 +23,19 @@ class Transform; } +namespace gpu { +class SharedContextState; +} + namespace viz { class BeginFrameSource; class CompositorFrameSinkSupport; class Display; class FrameSinkManagerImpl; -class ParentLocalSurfaceIdAllocator; } // namespace viz namespace android_webview { -class ParentOutputSurface; - class SurfacesInstance : public base::RefCounted<SurfacesInstance>, public viz::DisplayClient, public viz::mojom::CompositorFrameSinkClient { @@ -102,11 +103,10 @@ std::vector<viz::SurfaceId> child_ids_; viz::FrameTokenGenerator next_frame_token_; - // This is owned by |display_|. - ParentOutputSurface* output_surface_; - gfx::Size surface_size_; + scoped_refptr<gpu::SharedContextState> shared_context_state_; + DISALLOW_COPY_AND_ASSIGN(SurfacesInstance); };
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc index f1a1bbd..6d97275 100644 --- a/ash/login/login_screen_controller.cc +++ b/ash/login/login_screen_controller.cc
@@ -505,11 +505,11 @@ ->SetShowGuestButtonInOobe(show); } -void LoginScreenController::SetShowParentAccess(bool show) { +void LoginScreenController::SetShowParentAccessButton(bool show) { Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) ->shelf_widget() ->login_shelf_view() - ->SetShowParentAccess(show); + ->SetShowParentAccessButton(show); } void LoginScreenController::FocusLoginShelf(bool reverse) {
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h index b78ca78..dacfefd 100644 --- a/ash/login/login_screen_controller.h +++ b/ash/login/login_screen_controller.h
@@ -157,7 +157,7 @@ void SetShutdownButtonEnabled(bool enable) override; void SetAllowLoginAsGuest(bool allow_guest) override; void SetShowGuestButtonInOobe(bool show) override; - void SetShowParentAccess(bool show) override; + void SetShowParentAccessButton(bool show) override; void FocusLoginShelf(bool reverse) override; // Flushes the mojo pipes - to be used in tests.
diff --git a/ash/login/login_screen_test_api.cc b/ash/login/login_screen_test_api.cc index 0bad2a1..41deee0 100644 --- a/ash/login/login_screen_test_api.cc +++ b/ash/login/login_screen_test_api.cc
@@ -21,6 +21,29 @@ namespace ash { +namespace { + +LoginShelfView* GetLoginShelfView() { + if (!Shell::HasInstance()) + return nullptr; + + return Shelf::ForWindow(Shell::GetPrimaryRootWindow()) + ->shelf_widget() + ->login_shelf_view(); +} + +bool IsLoginShelfViewButtonShown(int button_view_id) { + LoginShelfView* shelf_view = GetLoginShelfView(); + if (!shelf_view) + return false; + + views::View* button_view = shelf_view->GetViewByID(button_view_id); + + return button_view && button_view->visible(); +} + +} // anonymous namespace + // static void LoginScreenTestApi::BindRequest(mojom::LoginScreenTestApiRequest request) { mojo::MakeStrongBinding(std::make_unique<LoginScreenTestApi>(), @@ -38,11 +61,20 @@ } void LoginScreenTestApi::IsLoginShelfShown(IsLoginShelfShownCallback callback) { - std::move(callback).Run(Shell::HasInstance() && - Shelf::ForWindow(Shell::GetPrimaryRootWindow()) - ->shelf_widget() - ->login_shelf_view() - ->visible()); + LoginShelfView* view = GetLoginShelfView(); + std::move(callback).Run(view && view->visible()); +} + +void LoginScreenTestApi::IsRestartButtonShown( + IsRestartButtonShownCallback callback) { + std::move(callback).Run( + IsLoginShelfViewButtonShown(LoginShelfView::kRestart)); +} + +void LoginScreenTestApi::IsShutdownButtonShown( + IsShutdownButtonShownCallback callback) { + std::move(callback).Run( + IsLoginShelfViewButtonShown(LoginShelfView::kShutdown)); } void LoginScreenTestApi::SubmitPassword(const AccountId& account_id, @@ -70,4 +102,10 @@ std::move(callback).Run(); } +void LoginScreenTestApi::GetUiUpdateCount(GetUiUpdateCountCallback callback) { + LoginShelfView* view = GetLoginShelfView(); + + std::move(callback).Run(view ? view->ui_update_count() : 0); +} + } // namespace ash
diff --git a/ash/login/login_screen_test_api.h b/ash/login/login_screen_test_api.h index ed24dee..a61a35c 100644 --- a/ash/login/login_screen_test_api.h +++ b/ash/login/login_screen_test_api.h
@@ -23,9 +23,12 @@ // mojom::LoginScreen: void IsLockShown(IsLockShownCallback callback) override; void IsLoginShelfShown(IsLoginShelfShownCallback callback) override; + void IsRestartButtonShown(IsRestartButtonShownCallback callback) override; + void IsShutdownButtonShown(IsShutdownButtonShownCallback callback) override; void SubmitPassword(const AccountId& account_id, const std::string& password, SubmitPasswordCallback callback) override; + void GetUiUpdateCount(GetUiUpdateCountCallback callback) override; private: DISALLOW_COPY_AND_ASSIGN(LoginScreenTestApi);
diff --git a/ash/metrics/login_metrics_recorder.cc b/ash/metrics/login_metrics_recorder.cc index 48018f9..f447943b 100644 --- a/ash/metrics/login_metrics_recorder.cc +++ b/ash/metrics/login_metrics_recorder.cc
@@ -143,6 +143,10 @@ // Should not be called in LOCKED nor LOGIN_PRIMARY states. NOTREACHED(); break; + case ShelfButtonClickTarget::kParentAccessButton: + DCHECK(is_lock); + LogUserClickOnLock(LockScreenUserClickTarget::kParentAccessButton); + break; case ShelfButtonClickTarget::kTargetCount: NOTREACHED(); break;
diff --git a/ash/metrics/login_metrics_recorder.h b/ash/metrics/login_metrics_recorder.h index 2d0e4f9..7d348ad3 100644 --- a/ash/metrics/login_metrics_recorder.h +++ b/ash/metrics/login_metrics_recorder.h
@@ -28,6 +28,7 @@ kImeTray, kNotificationTray, kLockScreenNoteActionButton, + kParentAccessButton, kTargetCount, }; @@ -65,6 +66,7 @@ kAddUserButton, kCloseNoteButton, kCancelButton, + kParentAccessButton, kTargetCount, };
diff --git a/ash/public/interfaces/login_screen.mojom b/ash/public/interfaces/login_screen.mojom index 6e7f203..eaab8cf 100644 --- a/ash/public/interfaces/login_screen.mojom +++ b/ash/public/interfaces/login_screen.mojom
@@ -219,7 +219,7 @@ SetShowGuestButtonInOobe(bool show); // Sets whether parent access button can be shown on the login shelf. - SetShowParentAccess(bool show); + SetShowParentAccessButton(bool show); // Transitions focus to the shelf area. If |reverse|, focuses the status area. FocusLoginShelf(bool reverse);
diff --git a/ash/public/interfaces/login_screen_test_api.test-mojom b/ash/public/interfaces/login_screen_test_api.test-mojom index fde147c..1b1393dd 100644 --- a/ash/public/interfaces/login_screen_test_api.test-mojom +++ b/ash/public/interfaces/login_screen_test_api.test-mojom
@@ -14,6 +14,15 @@ // Returns true if the login shelf is currently being shown. IsLoginShelfShown() => (bool is_shown); + // Returns true if Restart button is currently being shown. + IsRestartButtonShown() => (bool is_shown); + + // Returns true if Shutdown button is currently being shown. + IsShutdownButtonShown() => (bool is_shown); + // Submit |password| for |account_id|. SubmitPassword(signin.mojom.AccountId account_id, string password) => (); + + // Fetches current UI update count. + GetUiUpdateCount() => (int64 count); };
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 41640ea3..c81cda8 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -93,6 +93,7 @@ "palette_tray_icon_laser_pointer.icon", "palette_tray_icon_magnify.icon", "palette_tray_icon_metalayer.icon", + "parent_access_lock.icon", "send.icon", "settings.icon", "shelf_add_person_button.icon", @@ -108,7 +109,6 @@ "shelf_overflow.icon", "shelf_overflow_horizontal_dots.icon", "shelf_overview.icon", - "shelf_parent_access_button.icon", "shelf_position.icon", "shelf_shutdown_button.icon", "shelf_sign_out_button.icon",
diff --git a/ash/resources/vector_icons/shelf_parent_access_button.icon b/ash/resources/vector_icons/parent_access_lock.icon similarity index 100% rename from ash/resources/vector_icons/shelf_parent_access_button.icon rename to ash/resources/vector_icons/parent_access_lock.icon
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index 12e6575..de11a30 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -79,6 +79,8 @@ return LoginMetricsRecorder::ShelfButtonClickTarget::kAddUserButton; case LoginShelfView::kCancel: return LoginMetricsRecorder::ShelfButtonClickTarget::kCancelButton; + case LoginShelfView::kParentAccess: + return LoginMetricsRecorder::ShelfButtonClickTarget::kParentAccessButton; } return LoginMetricsRecorder::ShelfButtonClickTarget::kTargetCount; } @@ -387,7 +389,7 @@ kShelfBrowseAsGuestButtonIcon); add_button(kAddUser, IDS_ASH_ADD_USER_BUTTON, kShelfAddPersonButtonIcon); add_button(kParentAccess, IDS_ASH_PARENT_ACCESS_BUTTON, - kShelfParentAccessButtonIcon); + kParentAccessLockIcon); // Adds observers for states that affect the visiblity of different buttons. tray_action_observer_.Add(Shell::Get()->tray_action()); @@ -508,7 +510,7 @@ UpdateUi(); } -void LoginShelfView::SetShowParentAccess(bool show) { +void LoginShelfView::SetShowParentAccessButton(bool show) { show_parent_access_ = show; UpdateUi(); } @@ -567,6 +569,7 @@ child_at(i)->SetVisible(false); return; } + ++ui_update_count_; bool show_reboot = Shell::Get()->shutdown_controller()->reboot_on_shutdown(); mojom::TrayActionState tray_action_state = Shell::Get()->tray_action()->GetLockScreenNoteState();
diff --git a/ash/shelf/login_shelf_view.h b/ash/shelf/login_shelf_view.h index 95e6cc32..47658fd79 100644 --- a/ash/shelf/login_shelf_view.h +++ b/ash/shelf/login_shelf_view.h
@@ -80,7 +80,7 @@ void SetAllowLoginAsGuest(bool allow_guest); // Sets whether parent access button can be shown on the login shelf. - void SetShowParentAccess(bool show); + void SetShowParentAccessButton(bool show); // Sets if the guest button on the login shelf can be shown during gaia // signin screen. @@ -101,6 +101,8 @@ // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override; + int ui_update_count() const { return ui_update_count_; } + protected: // TrayActionObserver: void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override; @@ -150,6 +152,9 @@ KioskAppsButton* kiosk_apps_button_ = nullptr; // Owned by view hierarchy + // This is used in tests to wait until UI is updated. + int ui_update_count_ = 0; + DISALLOW_COPY_AND_ASSIGN(LoginShelfView); };
diff --git a/ash/shelf/login_shelf_view_unittest.cc b/ash/shelf/login_shelf_view_unittest.cc index f03e9b6..669671f 100644 --- a/ash/shelf/login_shelf_view_unittest.cc +++ b/ash/shelf/login_shelf_view_unittest.cc
@@ -523,7 +523,7 @@ TEST_F(LoginShelfViewTest, ParentAccessButtonVisibility) { // Parent access button should only be visible on lock screen. - Shell::Get()->login_screen_controller()->SetShowParentAccess(true); + Shell::Get()->login_screen_controller()->SetShowParentAccessButton(true); NotifySessionStateChanged(SessionState::LOGIN_PRIMARY); EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown, @@ -554,12 +554,12 @@ EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut})); - Shell::Get()->login_screen_controller()->SetShowParentAccess(true); + Shell::Get()->login_screen_controller()->SetShowParentAccessButton(true); EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut, LoginShelfView::kParentAccess})); - Shell::Get()->login_screen_controller()->SetShowParentAccess(false); + Shell::Get()->login_screen_controller()->SetShowParentAccessButton(false); EXPECT_TRUE( ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut})); }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 38c0182..e4feba0 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -092aef2aaad3c9ceb2b9771170055371b987fe69 \ No newline at end of file +578a3808d2e72ead28a22a8b1d605680a59b9fcd \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 20d2e7f..d841760 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -793fd71e247d7f737d5466cd70c34f32773d5a9e \ No newline at end of file +a7f664353426d4c2fac93abfa9a187c309e15d9e \ No newline at end of file
diff --git a/chrome/VERSION b/chrome/VERSION index 7f4cf97..e143903 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=74 MINOR=0 -BUILD=3690 +BUILD=3691 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/MenuButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/MenuButton.java index 2a14c9a..42601766 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/MenuButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/MenuButton.java
@@ -27,7 +27,6 @@ import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper.MenuButtonState; import org.chromium.chrome.browser.widget.PulseDrawable; -import org.chromium.ui.UiUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator; /** @@ -108,6 +107,10 @@ ApiCompatibilityUtils.getDrawable(getResources(), drawable)); } + /** + * Show the update badge on the app menu button. + * @param animate Whether to animate the showing of the update badge. + */ public void showAppMenuUpdateBadge(boolean animate) { if (mUpdateBadgeView == null) return; mShowMenuBadge = true; @@ -116,6 +119,10 @@ setAppMenuUpdateBadgeToVisible(animate); } + /** + * Remove the update badge on the app menu button. + * @param animate Whether to animate the hiding of the update badge. + */ public void removeAppMenuUpdateBadge(boolean animate) { if (mUpdateBadgeView == null) return; boolean wasShowingMenuBadge = mShowMenuBadge; @@ -264,7 +271,6 @@ mThemeColorProvider.removeTintObserver(this); mThemeColorProvider = null; } - UiUtils.removeViewFromParent(this); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index 4fa4a3b..456f1161 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -136,6 +136,7 @@ private ImageButton mSecurityButton; private LinearLayout mCustomActionButtons; private ImageButton mCloseButton; + private ImageButton mMenuButton; // Whether dark tint should be applied to icons and text. private boolean mUseDarkColors = true; @@ -183,6 +184,7 @@ mCustomActionButtons = findViewById(R.id.action_buttons); mCloseButton = findViewById(R.id.close_button); mCloseButton.setOnLongClickListener(this); + mMenuButton = findViewById(R.id.menu_button); mAnimDelegate = new CustomTabToolbarAnimationDelegate(mSecurityButton, mTitleUrlContainer); } @@ -783,6 +785,9 @@ public void setAutocompleteProfile(Profile profile) {} @Override + void showAppMenuUpdateBadge(boolean animate) {} + + @Override boolean isShowingAppMenuUpdateBadge() { return false; } @@ -797,8 +802,14 @@ } @Override + ImageButton getMenuButton() { + return mMenuButton; + } + + @Override void disableMenuButton() { super.disableMenuButton(); + mMenuButton = null; // In addition to removing the menu button, we also need to remove the margin on the custom // action button. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 469013b..5c87dc8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -111,6 +111,12 @@ mToolbarTabController = tabController; if (mMenuButtonWrapper != null) { mMenuButtonWrapper.setAppMenuButtonHelper(appMenuButtonHelper); + } else { + final ImageButton menuButton = getMenuButton(); + if (menuButton != null) { + menuButton.setOnTouchListener(appMenuButtonHelper); + menuButton.setAccessibilityDelegate(appMenuButtonHelper); + } } } @@ -139,6 +145,8 @@ * instance vars. */ void disableMenuButton() { + UiUtils.removeViewFromParent(getMenuButtonWrapper()); + if (mMenuButtonWrapper != null) { mMenuButtonWrapper.destroy(); mMenuButtonWrapper = null;
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 721069a..4151efc 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-74.0.3687.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-74.0.3690.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 0216084..7796250 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1206,9 +1206,6 @@ <message name="IDS_KIOSK_APPS_BUTTON" desc="Text shown on a button that brings up the kiosk apps menu on login screen"> Apps </message> - <message name="IDS_LOCK_SCREEN_TASK_MANAGER_NAME" desc="The name of the lock screen as it appears in the task manager. This will be prefixed with another string, such as 'Extension: ' (see IDS_TASK_MANAGER_EXTENSION_PREFIX)"> - Lock Screen - </message> <message name="IDS_LOGIN_USER_ADDING_BANNER" desc="Text shown on a banner in user adding screen."> Add an account to multiple sign-in. All signed-in accounts can be accessed without a password, so this feature should only be used with trusted accounts. </message>
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_config.cc b/chrome/browser/android/oom_intervention/oom_intervention_config.cc index e63ffbe7..76f425d 100644 --- a/chrome/browser/android/oom_intervention/oom_intervention_config.cc +++ b/chrome/browser/android/oom_intervention/oom_intervention_config.cc
@@ -138,11 +138,11 @@ is_swap_monitor_enabled_ = false; status = OomInterventionBrowserMonitorStatus::kEnabledWithNoSwap; } - // If no threshold is specified, set blink_workload_threshold to 10 by - // default, meaning that 10% of the RAM size is set to blink memory usage - // threshold to trigger intervention. + // If no threshold is specified, set blink_workload_threshold to 10% of the + // RAM size. if (!GetRendererMemoryThresholds(&renderer_detection_args_)) { - renderer_detection_args_->blink_workload_threshold = 10; + renderer_detection_args_->blink_workload_threshold = + base::SysInfo::AmountOfPhysicalMemory() * 0.1; } }
diff --git a/chrome/browser/android/usage_stats/usage_stats_database.cc b/chrome/browser/android/usage_stats/usage_stats_database.cc index ebbdf8f..a94da91 100644 --- a/chrome/browser/android/usage_stats/usage_stats_database.cc +++ b/chrome/browser/android/usage_stats/usage_stats_database.cc
@@ -66,9 +66,9 @@ return domains.contains(key.substr(kFqdnPosition)); } -UsageStatsDatabase::Error ToError(bool success) { - return success ? UsageStatsDatabase::Error::kNoError - : UsageStatsDatabase::Error::kUnknownError; +UsageStatsDatabase::Error ToError(bool isSuccess) { + return isSuccess ? UsageStatsDatabase::Error::kNoError + : UsageStatsDatabase::Error::kUnknownError; } std::string CreateWebsiteEventKey(int64_t seconds, const std::string& fqdn) { @@ -95,6 +95,20 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +void UsageStatsDatabase::QueryEventsInRange(int64_t start, + int64_t end, + EventsCallback callback) { + // Load all UsageStats with the website events prefix, where the timestamp is + // in the specified range. Function accepts a half-open range [start, end) as + // input, but the database operates on fully-closed ranges. Because the + // timestamps are represented by integers, [start, end) is equivalent to + // [start, end - 1]. + proto_db_->LoadKeysAndEntriesInRange( + CreateWebsiteEventKey(start, ""), CreateWebsiteEventKey(end - 1, ""), + base::BindOnce(&UsageStatsDatabase::OnLoadEntriesForQueryEventsInRange, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + void UsageStatsDatabase::AddEvents(std::vector<WebsiteEvent> events, StatusCallback callback) { auto entries = std::make_unique< @@ -119,6 +133,34 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +void UsageStatsDatabase::DeleteAllEvents(StatusCallback callback) { + // Remove all entries with the website event prefix. + proto_db_->UpdateEntriesWithRemoveFilter( + std::make_unique< + leveldb_proto::ProtoDatabase<UsageStat>::KeyEntryVector>(), + base::BindRepeating([](const std::string& key) { return true; }), + kWebsiteEventPrefix, + base::BindOnce(&UsageStatsDatabase::OnUpdateEntries, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} +void UsageStatsDatabase::DeleteEventsInRange(int64_t start, + int64_t end, + StatusCallback callback) { + // TODO(crbug/927655): If/when leveldb_proto adds an UpdateEntriesInRange + // function, we should consolidate these two proto_db_ calls into a single + // call. + + // Load all keys with the website events prefix, where the timestamp is + // in the specified range, passing a callback to delete those entries. + // Function accepts a half-open range [start, end) as input, but the database + // operates on fully-closed ranges. Because the timestamps are represented by + // integers, [start, end) is equivalent to [start, end - 1]. + proto_db_->LoadKeysAndEntriesInRange( + CreateWebsiteEventKey(start, ""), CreateWebsiteEventKey(end - 1, ""), + base::BindOnce(&UsageStatsDatabase::OnLoadEntriesForDeleteEventsInRange, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + void UsageStatsDatabase::DeleteEventsWithMatchingDomains( base::flat_set<std::string> domains, StatusCallback callback) { @@ -212,13 +254,13 @@ } void UsageStatsDatabase::OnUpdateEntries(StatusCallback callback, - bool success) { - std::move(callback).Run(ToError(success)); + bool isSuccess) { + std::move(callback).Run(ToError(isSuccess)); } void UsageStatsDatabase::OnLoadEntriesForGetAllEvents( EventsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats) { std::vector<WebsiteEvent> results; @@ -229,12 +271,53 @@ } } - std::move(callback).Run(ToError(success), std::move(results)); + std::move(callback).Run(ToError(isSuccess), std::move(results)); +} + +void UsageStatsDatabase::OnLoadEntriesForQueryEventsInRange( + EventsCallback callback, + bool isSuccess, + std::unique_ptr<UsageStatMap> stat_map) { + std::vector<WebsiteEvent> results; + + if (stat_map) { + results.reserve(stat_map->size()); + for (const auto& key_stat : *stat_map) { + results.emplace_back(key_stat.second.website_event()); + } + } + + std::move(callback).Run(ToError(isSuccess), std::move(results)); +} + +void UsageStatsDatabase::OnLoadEntriesForDeleteEventsInRange( + StatusCallback callback, + bool isSuccess, + std::unique_ptr<UsageStatMap> stat_map) { + if (isSuccess && stat_map) { + // Collect keys found in range to be deleted. + auto keys_to_delete = std::make_unique<std::vector<std::string>>(); + keys_to_delete->reserve(stat_map->size()); + + for (const auto& key_stat : *stat_map) { + keys_to_delete->emplace_back(key_stat.first); + } + + // Remove all entries found in range. + proto_db_->UpdateEntries( + std::make_unique< + leveldb_proto::ProtoDatabase<UsageStat>::KeyEntryVector>(), + std::move(keys_to_delete), + base::BindOnce(&UsageStatsDatabase::OnUpdateEntries, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + } else { + std::move(callback).Run(ToError(isSuccess)); + } } void UsageStatsDatabase::OnLoadEntriesForGetAllSuspensions( SuspensionsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats) { std::vector<std::string> results; @@ -245,12 +328,12 @@ } } - std::move(callback).Run(ToError(success), std::move(results)); + std::move(callback).Run(ToError(isSuccess), std::move(results)); } void UsageStatsDatabase::OnLoadEntriesForGetAllTokenMappings( TokenMappingsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats) { TokenMap results; @@ -261,7 +344,7 @@ } } - std::move(callback).Run(ToError(success), std::move(results)); + std::move(callback).Run(ToError(isSuccess), std::move(results)); } } // namespace usage_stats
diff --git a/chrome/browser/android/usage_stats/usage_stats_database.h b/chrome/browser/android/usage_stats/usage_stats_database.h index 6e7dd11..767ebc2 100644 --- a/chrome/browser/android/usage_stats/usage_stats_database.h +++ b/chrome/browser/android/usage_stats/usage_stats_database.h
@@ -36,6 +36,8 @@ using StatusCallback = base::OnceCallback<void(Error)>; + using UsageStatMap = std::map<std::string, UsageStat>; + // Initializes the database with user |profile|. explicit UsageStatsDatabase(Profile* profile); @@ -47,16 +49,17 @@ void GetAllEvents(EventsCallback callback); - // |start| and |end| are timestamps representing milliseconds since the - // beginning of the Unix Epoch. + // Get all events in range between |start| (inclusive) and |end| (exclusive), + // where |start| and |end| are represented by milliseconds since Unix epoch. void QueryEventsInRange(int64_t start, int64_t end, EventsCallback callback); void AddEvents(std::vector<WebsiteEvent> events, StatusCallback callback); void DeleteAllEvents(StatusCallback callback); - // |start| and |end| are timestamps representing milliseconds since the - // beginning of the Unix Epoch. + // Delete all events in range between |start| (inclusive) and |end| + // (exclusive), where |start| and |end| are represented by milliseconds since + // Unix epoch. void DeleteEventsInRange(int64_t start, int64_t end, StatusCallback callback); void DeleteEventsWithMatchingDomains(base::flat_set<std::string> domains, @@ -76,21 +79,31 @@ void SetTokenMappings(TokenMap mappings, StatusCallback callback); private: - void OnUpdateEntries(StatusCallback callback, bool success); + void OnUpdateEntries(StatusCallback callback, bool isSuccess); void OnLoadEntriesForGetAllEvents( EventsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats); + void OnLoadEntriesForQueryEventsInRange( + EventsCallback callback, + bool isSuccess, + std::unique_ptr<UsageStatMap> stat_map); + + void OnLoadEntriesForDeleteEventsInRange( + StatusCallback callback, + bool isSuccess, + std::unique_ptr<UsageStatMap> stat_map); + void OnLoadEntriesForGetAllSuspensions( SuspensionsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats); void OnLoadEntriesForGetAllTokenMappings( TokenMappingsCallback callback, - bool success, + bool isSuccess, std::unique_ptr<std::vector<UsageStat>> stats); std::unique_ptr<leveldb_proto::ProtoDatabase<UsageStat>> proto_db_;
diff --git a/chrome/browser/android/usage_stats/usage_stats_database_unittest.cc b/chrome/browser/android/usage_stats/usage_stats_database_unittest.cc index 519ae33a9..10a4ace 100644 --- a/chrome/browser/android/usage_stats/usage_stats_database_unittest.cc +++ b/chrome/browser/android/usage_stats/usage_stats_database_unittest.cc
@@ -63,7 +63,7 @@ FakeDB<UsageStat>* fake_db() { return fake_db_unowned_; } MOCK_METHOD1(OnUpdateDone, void(UsageStatsDatabase::Error)); - MOCK_METHOD2(OnGetAllEventsDone, + MOCK_METHOD2(OnGetEventsDone, void(UsageStatsDatabase::Error, std::vector<WebsiteEvent>)); MOCK_METHOD2(OnGetAllSuspensionsDone, void(UsageStatsDatabase::Error, std::vector<std::string>)); @@ -85,22 +85,21 @@ // Website Event Tests TEST_F(UsageStatsDatabaseTest, GetAllEventsSuccess) { - EXPECT_CALL(*this, OnGetAllEventsDone(UsageStatsDatabase::Error::kNoError, - ElementsAre())); + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre())); usage_stats_database()->GetAllEvents(base::BindOnce( - &UsageStatsDatabaseTest::OnGetAllEventsDone, base::Unretained(this))); + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); fake_db()->LoadCallback(true); } TEST_F(UsageStatsDatabaseTest, GetAllEventsFailure) { - EXPECT_CALL(*this, - OnGetAllEventsDone(UsageStatsDatabase::Error::kUnknownError, - ElementsAre())); + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kUnknownError, + ElementsAre())); usage_stats_database()->GetAllEvents(base::BindOnce( - &UsageStatsDatabaseTest::OnGetAllEventsDone, base::Unretained(this))); + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); fake_db()->LoadCallback(false); } @@ -118,6 +117,7 @@ } TEST_F(UsageStatsDatabaseTest, AddAndGetOneEvent) { + // Add 1 event. WebsiteEvent event1 = CreateWebsiteEvent(kFqdn1, 1, WebsiteEvent::START_BROWSING); std::vector<WebsiteEvent> events({event1}); @@ -130,18 +130,119 @@ fake_db()->UpdateCallback(true); - EXPECT_CALL(*this, - OnGetAllEventsDone(UsageStatsDatabase::Error::kNoError, - ElementsAre(EqualsWebsiteEvent(event1)))); + // Get 1 event. + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre(EqualsWebsiteEvent(event1)))); usage_stats_database()->GetAllEvents(base::BindOnce( - &UsageStatsDatabaseTest::OnGetAllEventsDone, base::Unretained(this))); + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); + + fake_db()->LoadCallback(true); +} + +TEST_F(UsageStatsDatabaseTest, AddAndQueryEventsInRange) { + // Add 2 events at time 5 and 10. + WebsiteEvent event1 = + CreateWebsiteEvent(kFqdn1, 5, WebsiteEvent::START_BROWSING); + WebsiteEvent event2 = + CreateWebsiteEvent(kFqdn2, 10, WebsiteEvent::STOP_BROWSING); + std::vector<WebsiteEvent> events({event1, event2}); + + EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); + + usage_stats_database()->AddEvents( + events, base::BindOnce(&UsageStatsDatabaseTest::OnUpdateDone, + base::Unretained(this))); + + fake_db()->UpdateCallback(true); + + // Get events between time 0 (inclusive) and 9 (exclusive). + // This test validates the correct lexicographic ordering of timestamps such + // that key(0) <= key(5) < key(9) <= key(10). + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre(EqualsWebsiteEvent(event1)))); + + usage_stats_database()->QueryEventsInRange( + 0, 9, + base::BindOnce(&UsageStatsDatabaseTest::OnGetEventsDone, + base::Unretained(this))); + + fake_db()->LoadCallback(true); +} + +TEST_F(UsageStatsDatabaseTest, AddAndDeleteAllEvents) { + // Add 1 event. + WebsiteEvent event1 = + CreateWebsiteEvent(kFqdn1, 1, WebsiteEvent::START_BROWSING); + std::vector<WebsiteEvent> events({event1}); + + EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); + + usage_stats_database()->AddEvents( + events, base::BindOnce(&UsageStatsDatabaseTest::OnUpdateDone, + base::Unretained(this))); + + fake_db()->UpdateCallback(true); + + // Delete all events. + EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); + + usage_stats_database()->DeleteAllEvents(base::BindOnce( + &UsageStatsDatabaseTest::OnUpdateDone, base::Unretained(this))); + + fake_db()->UpdateCallback(true); + + // Get all events (expecting none). + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre())); + + usage_stats_database()->GetAllEvents(base::BindOnce( + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); + + fake_db()->LoadCallback(true); +} + +TEST_F(UsageStatsDatabaseTest, AddAndDeleteEventsInRange) { + // Add 3 events. + WebsiteEvent event1 = + CreateWebsiteEvent(kFqdn1, 1, WebsiteEvent::START_BROWSING); + WebsiteEvent event2 = + CreateWebsiteEvent(kFqdn1, 2, WebsiteEvent::START_BROWSING); + WebsiteEvent event3 = + CreateWebsiteEvent(kFqdn1, 10, WebsiteEvent::START_BROWSING); + std::vector<WebsiteEvent> events({event1, event2, event3}); + + EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); + + usage_stats_database()->AddEvents( + events, base::BindOnce(&UsageStatsDatabaseTest::OnUpdateDone, + base::Unretained(this))); + + fake_db()->UpdateCallback(true); + + // Delete events between time 1 (inclusive) and 10 (exclusive). + EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); + + usage_stats_database()->DeleteEventsInRange( + 1, 10, + base::BindOnce(&UsageStatsDatabaseTest::OnUpdateDone, + base::Unretained(this))); + + fake_db()->LoadCallback(true); + fake_db()->UpdateCallback(true); + + // Get 1 remaining event outside range (at time 10). + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre(EqualsWebsiteEvent(event3)))); + + usage_stats_database()->GetAllEvents(base::BindOnce( + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); fake_db()->LoadCallback(true); } TEST_F(UsageStatsDatabaseTest, AddAndDeleteEventsMatchingDomain) { - // Add 3 events + // Add 3 events. WebsiteEvent event1 = CreateWebsiteEvent(kFqdn1, 1, WebsiteEvent::START_BROWSING); WebsiteEvent event2 = @@ -158,7 +259,7 @@ fake_db()->UpdateCallback(true); - // Delete 2 events by FQDN + // Delete 2 events by FQDN. base::flat_set<std::string> domains({kFqdn1}); EXPECT_CALL(*this, OnUpdateDone(UsageStatsDatabase::Error::kNoError)); @@ -168,13 +269,12 @@ fake_db()->UpdateCallback(true); - // Get 1 remaining event with non-matching FQDN - EXPECT_CALL(*this, - OnGetAllEventsDone(UsageStatsDatabase::Error::kNoError, - ElementsAre(EqualsWebsiteEvent(event3)))); + // Get 1 remaining event with non-matching FQDN. + EXPECT_CALL(*this, OnGetEventsDone(UsageStatsDatabase::Error::kNoError, + ElementsAre(EqualsWebsiteEvent(event3)))); usage_stats_database()->GetAllEvents(base::BindOnce( - &UsageStatsDatabaseTest::OnGetAllEventsDone, base::Unretained(this))); + &UsageStatsDatabaseTest::OnGetEventsDone, base::Unretained(this))); fake_db()->LoadCallback(true); }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index ec6d3ed..1dfec9ea 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -17,10 +17,6 @@ <structure name="IDR_GUEST_TAB_HTML" file="resources\ntp4\guest_tab.html" flattenhtml="true" type="chrome_html" /> </if> <if expr="chromeos"> - <structure name="IDR_LOCK_HTML" file="resources\chromeos\login\lock.html" flattenhtml="true" type="chrome_html" variables="OOBE=lock" expand_variables="true"/> - <structure name="IDR_LOCK_JS" file="resources\chromeos\login\lock.js" flattenhtml="true" type="chrome_html" variables="OOBE=lock" expand_variables="true" /> - <structure name="IDR_MD_LOCK_HTML" file="resources\chromeos\login\md_lock.html" flattenhtml="true" type="chrome_html" variables="OOBE=md_lock" expand_variables="true"/> - <structure name="IDR_MD_LOCK_JS" file="resources\chromeos\login\md_lock.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_LOGIN_HTML" file="resources\chromeos\login\login.html" flattenhtml="true" type="chrome_html" variables="OOBE=login" expand_variables="true"/> <structure name="IDR_LOGIN_JS" file="resources\chromeos\login\login.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_MD_LOGIN_HTML" file="resources\chromeos\login\md_login.html" flattenhtml="true" type="chrome_html" variables="OOBE=md_login" expand_variables="true"/> @@ -43,8 +39,6 @@ <structure name="IDR_CHROMEOS_DISCOVER_MANIFEST" file="resources\chromeos\login\discover\manifest.json" flattenhtml="true" type="chrome_html"/> <structure name="IDR_CUSTOM_ELEMENTS_OOBE_HTML" file="resources\chromeos\login\custom_elements_oobe.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_OOBE_JS" file="resources\chromeos\login\custom_elements_oobe.js" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_CUSTOM_ELEMENTS_LOCK_HTML" file="resources\chromeos\login\custom_elements_lock.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_CUSTOM_ELEMENTS_LOCK_JS" file="resources\chromeos\login\custom_elements_lock.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_USER_POD_HTML" file="resources\chromeos\login\custom_elements_user_pod.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_LOGIN_HTML" file="resources\chromeos\login\custom_elements_login.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_CUSTOM_ELEMENTS_LOGIN_JS" file="resources\chromeos\login\custom_elements_login.js" flattenhtml="true" type="chrome_html" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index f109b8a8..e8f1beb 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1005,10 +1005,9 @@ } bool is_whitelisted = false; - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); PolicyBlacklistService* service = - PolicyBlacklistFactory::GetForBrowserContext(profile); + PolicyBlacklistFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); if (service) { const policy::URLBlacklist::URLBlacklistState url_state = service->GetURLBlacklistState(url);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 3beeed6..167a3868 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1145,8 +1145,6 @@ "login/lock/screen_locker.h", "login/lock/views_screen_locker.cc", "login/lock/views_screen_locker.h", - "login/lock/webui_screen_locker.cc", - "login/lock/webui_screen_locker.h", "login/lock_screen_utils.cc", "login/lock_screen_utils.h", "login/login_auth_recorder.cc", @@ -1358,10 +1356,6 @@ "login/ui/login_web_dialog.h", "login/ui/oobe_ui_dialog_delegate.cc", "login/ui/oobe_ui_dialog_delegate.h", - "login/ui/preloaded_web_view.cc", - "login/ui/preloaded_web_view.h", - "login/ui/preloaded_web_view_factory.cc", - "login/ui/preloaded_web_view_factory.h", "login/ui/simple_web_view_dialog.cc", "login/ui/simple_web_view_dialog.h", "login/ui/user_adding_screen.cc",
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc index 16009ad..925060f 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
@@ -173,8 +173,11 @@ // Avoid abrupt session restart that looks like a crash and happens when lock // screen is requested before sign in completion. It is safe, because time // limits will be reevaluated when session state changes to active. - if (session_manager::SessionManager::Get()->session_state() != - session_manager::SessionState::ACTIVE) + // TODO(agawronska): Remove the flag when it is confirmed that this does not + // cause a bug (https://crbug.com/924844). + if (base::FeatureList::IsEnabled(features::kDMServerOAuthForChildUser) && + session_manager::SessionManager::Get()->session_state() != + session_manager::SessionState::ACTIVE) return; chromeos::DBusThreadManager::Get() @@ -199,8 +202,10 @@ ScreenLocker::default_screen_locker()->SetAuthEnabledForUser( account_id, !visible, visible ? next_unlock_time : base::Optional<base::Time>()); - if (base::FeatureList::IsEnabled(features::kParentAccessCode)) - LoginScreenClient::Get()->login_screen()->SetShowParentAccess(visible); + if (base::FeatureList::IsEnabled(features::kParentAccessCode)) { + LoginScreenClient::Get()->login_screen()->SetShowParentAccessButton( + visible); + } } void ScreenTimeController::OnPolicyChanged() {
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc index c388ae0..8c8e913 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller_browsertest.cc
@@ -110,9 +110,7 @@ SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); MockClockForActiveUser(); - std::unique_ptr<chromeos::ScreenLockerTester> tester = - chromeos::ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester().Lock(); // Verify user is able to log in. EXPECT_TRUE(IsAuthEnabled()); @@ -142,9 +140,7 @@ SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); MockClockForActiveUser(); - std::unique_ptr<chromeos::ScreenLockerTester> tester = - chromeos::ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester().Lock(); system::TimezoneSettings::GetInstance()->SetTimezoneFromID( base::UTF8ToUTF16("GMT")); @@ -210,9 +206,7 @@ SkipToLoginScreen(); LogIn(kAccountId, kAccountPassword, test::kChildAccountServiceFlags); MockClockForActiveUser(); - std::unique_ptr<chromeos::ScreenLockerTester> tester = - chromeos::ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester().Lock(); system::TimezoneSettings::GetInstance()->SetTimezoneFromID( base::UTF8ToUTF16("GMT"));
diff --git a/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc b/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc index 3735521..c6369c8 100644 --- a/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc
@@ -236,7 +236,7 @@ // Screenlock - logged in, screen locked. IN_PROC_BROWSER_TEST_F(UsersPrivateApiLockStatusTest, ScreenLock) { - chromeos::ScreenLockerTester::Create()->Lock(); + chromeos::ScreenLockerTester().Lock(); EXPECT_TRUE(RunExtensionSubtest("users_private", "main.html?getLoginStatus", kFlagLoadAsComponent)) << message_;
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc index e296557..6c65a7a 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc
@@ -100,6 +100,8 @@ ADD_FAILURE() << "Should not be reached."; } + // TODO(crbug.com/927498): This tests is the only dependency on + // ScreenlockBridge::EnableInput. It should be removed. void EnableInput() override { ASSERT_EQ(STATE_ATTEMPTING_UNLOCK, state_); state_ = STATE_UNLOCK_CANCELED;
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index 63453c8..389d5db 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/lock/views_screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/login_auth_recorder.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" @@ -44,8 +43,6 @@ #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/ash/login_screen_client.h" #include "chrome/browser/ui/ash/session_controller_client.h" -#include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_provider.h" -#include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_source.h" #include "chrome/common/chrome_switches.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" @@ -198,37 +195,26 @@ authenticator_ = UserSessionManager::GetInstance()->CreateAuthenticator(this); extended_authenticator_ = ExtendedAuthenticator::Create(this); - if (!ash::switches::IsUsingViewsLock()) { - web_ui_.reset(new WebUIScreenLocker(this)); - delegate_ = web_ui_.get(); - web_ui_->LockScreen(); - // Ownership of |icon_image_source| is passed. - screenlock_icon_provider_ = std::make_unique<ScreenlockIconProvider>(); - content::URLDataSource::Add(web_ui_->web_contents()->GetBrowserContext(), - std::make_unique<ScreenlockIconSource>( - screenlock_icon_provider_->AsWeakPtr())); - } else { - // Create delegate that calls into the views-based lock screen via mojo. - views_screen_locker_ = std::make_unique<ViewsScreenLocker>(this); - delegate_ = views_screen_locker_.get(); + // Create delegate that calls into the views-based lock screen via mojo. + views_screen_locker_ = std::make_unique<ViewsScreenLocker>(this); + delegate_ = views_screen_locker_.get(); - // Create and display lock screen. - CHECK(LoginScreenClient::HasInstance()); - LoginScreenClient::Get()->login_screen()->ShowLockScreen(base::BindOnce( - [](ViewsScreenLocker* screen_locker, bool did_show) { - CHECK(did_show); - screen_locker->OnLockScreenReady(); + // Create and display lock screen. + CHECK(LoginScreenClient::HasInstance()); + LoginScreenClient::Get()->login_screen()->ShowLockScreen(base::BindOnce( + [](ViewsScreenLocker* screen_locker, bool did_show) { + CHECK(did_show); + screen_locker->OnLockScreenReady(); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); - }, - views_screen_locker_.get())); + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); + }, + views_screen_locker_.get())); - views_screen_locker_->Init(); - } + views_screen_locker_->Init(); // Start locking on ash side. SessionControllerClient::Get()->StartLock(base::BindOnce( @@ -369,7 +355,6 @@ unlock_attempt_type_ = AUTH_PASSWORD; authentication_start_time_ = base::Time::Now(); - delegate_->SetPasswordInputEnabled(false); if (user_context.IsUsingPin()) unlock_attempt_type_ = AUTH_PIN; @@ -488,13 +473,12 @@ } void ScreenLocker::EnableInput() { - delegate_->SetPasswordInputEnabled(true); + // TODO(crbug.com/927498): Remove this. } void ScreenLocker::ShowErrorMessage(int error_msg_id, HelpAppLauncher::HelpTopic help_topic_id, bool sign_out_only) { - delegate_->SetPasswordInputEnabled(!sign_out_only); delegate_->ShowErrorMessage(error_msg_id, help_topic_id); }
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.h b/chrome/browser/chromeos/login/lock/screen_locker.h index 0c2ac317..ae8df8f 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.h +++ b/chrome/browser/chromeos/login/lock/screen_locker.h
@@ -28,22 +28,16 @@ #include "ui/base/accelerators/accelerator.h" #include "ui/base/ime/chromeos/input_method_manager.h" -namespace content { -class WebContents; -} - namespace chromeos { class Authenticator; class ExtendedAuthenticator; class AuthFailure; -class ScreenlockIconProvider; -class WebUIScreenLocker; class ViewsScreenLocker; -// ScreenLocker creates a WebUIScreenLocker which will display the lock UI. -// As well, it takes care of authenticating the user and managing a global -// instance of itself which will be deleted when the system is unlocked. +// ScreenLocker displays the lock UI and takes care of authenticating the user +// and managing a global instance of itself which will be deleted when the +// system is unlocked. class ScreenLocker : public AuthStatusConsumer, public device::mojom::FingerprintObserver { public: @@ -53,9 +47,6 @@ Delegate(); virtual ~Delegate(); - // Enable/disable password input. - virtual void SetPasswordInputEnabled(bool enabled) = 0; - // Show the given error message. virtual void ShowErrorMessage(int error_msg_id, HelpAppLauncher::HelpTopic help_topic_id) = 0; @@ -63,16 +54,6 @@ // Close any displayed error messages. virtual void ClearErrors() = 0; - // Called when the webui lock screen is ready. This gets invoked by a - // chrome.send from the embedded webui. - virtual void OnLockWebUIReady() = 0; - - // Called when webui lock screen wallpaper is loaded and displayed. - virtual void OnLockBackgroundDisplayed() = 0; - - // Called when the webui header bar becomes visible. - virtual void OnHeaderBarVisible() = 0; - // Called by ScreenLocker to notify that ash lock animation finishes. virtual void OnAshLockAnimationFinished() = 0; @@ -83,11 +64,6 @@ // Called after a fingerprint authentication attempt. virtual void NotifyFingerprintAuthResult(const AccountId& account_id, bool success) = 0; - - // Returns the web contents used to back the lock screen. - // TODO(jdufault): Remove this function when we remove WebUIScreenLocker. - virtual content::WebContents* GetWebContents() = 0; - private: DISALLOW_COPY_AND_ASSIGN(Delegate); }; @@ -140,11 +116,6 @@ HelpAppLauncher::HelpTopic help_topic_id, bool sign_out_only); - // Returns the WebUIScreenLocker instance. This should only be used in tests. - // When using views-based lock this will be a nullptr. - // TODO(jdufault): Remove this function, make tests agnostic to ui impl. - WebUIScreenLocker* web_ui_for_testing() { return web_ui_.get(); } - // Returns delegate that can be used to talk to the view-layer. Delegate* delegate() { return delegate_; } @@ -198,7 +169,6 @@ private: friend class base::DeleteHelper<ScreenLocker>; - friend class WebUIScreenLocker; friend class ViewsScreenLocker; // Track whether the user used pin or password to unlock the lock screen. @@ -241,9 +211,6 @@ void OnPinCanAuthenticate(const AccountId& account_id, bool can_authenticate); - // WebUIScreenLocker instance in use. - std::unique_ptr<WebUIScreenLocker> web_ui_; - // Delegate used to talk to the view. Delegate* delegate_ = nullptr; @@ -287,9 +254,6 @@ // Callback to run, if any, when authentication is done. AuthenticateCallback on_auth_complete_; - // Provider for button icon set by the screenlockPrivate API. - std::unique_ptr<ScreenlockIconProvider> screenlock_icon_provider_; - scoped_refptr<input_method::InputMethodManager::State> saved_ime_state_; device::mojom::FingerprintPtr fp_service_;
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc index c26c23d4..1be438c 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -117,19 +117,19 @@ } // namespace IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBadThenGoodPassword) { - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester tester; + tester.Lock(); - tester->SetUnlockPassword(user_manager::StubAccountId(), "pass"); + tester.SetUnlockPassword(user_manager::StubAccountId(), "pass"); // Submit a bad password. - tester->UnlockWithPassword(user_manager::StubAccountId(), "fail"); - EXPECT_TRUE(tester->IsLocked()); + tester.UnlockWithPassword(user_manager::StubAccountId(), "fail"); + EXPECT_TRUE(tester.IsLocked()); // Submit the correct password. Successful authentication clears the lock // screen and tells the SessionManager to announce this over DBus. - tester->UnlockWithPassword(user_manager::StubAccountId(), "pass"); - EXPECT_FALSE(tester->IsLocked()); + tester.UnlockWithPassword(user_manager::StubAccountId(), "pass"); + EXPECT_FALSE(tester.IsLocked()); EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ(session_manager::SessionState::ACTIVE, session_manager::SessionManager::Get()->session_state()); @@ -156,7 +156,7 @@ // does not have all the pixels (e.g. the shelf is auto hidden instead of // hidden), locking the screen should not exit fullscreen. The shelf is // auto hidden when in immersive fullscreen. - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); + ScreenLockerTester tester; BrowserWindow* browser_window = browser()->window(); ash::wm::WindowState* window_state = ash::wm::GetWindowState(browser_window->GetNativeWindow()); @@ -169,19 +169,19 @@ fullscreen_waiter.WaitForState(true); EXPECT_TRUE(browser_window->IsFullscreen()); EXPECT_FALSE(window_state->GetHideShelfWhenFullscreen()); - EXPECT_FALSE(tester->IsLocked()); + EXPECT_FALSE(tester.IsLocked()); } { FullscreenWaiter fullscreen_waiter(browser()); - tester->Lock(); + tester.Lock(); fullscreen_waiter.WaitForState(true); EXPECT_TRUE(browser_window->IsFullscreen()); EXPECT_FALSE(window_state->GetHideShelfWhenFullscreen()); - EXPECT_TRUE(tester->IsLocked()); + EXPECT_TRUE(tester.IsLocked()); } - tester->SetUnlockPassword(user_manager::StubAccountId(), "pass"); - tester->UnlockWithPassword(user_manager::StubAccountId(), "pass"); - EXPECT_FALSE(tester->IsLocked()); + tester.SetUnlockPassword(user_manager::StubAccountId(), "pass"); + tester.UnlockWithPassword(user_manager::StubAccountId(), "pass"); + EXPECT_FALSE(tester.IsLocked()); { FullscreenWaiter fullscreen_waiter(browser()); browser() @@ -210,19 +210,19 @@ fullscreen_waiter.WaitForState(true); EXPECT_TRUE(browser_window->IsFullscreen()); EXPECT_TRUE(window_state->GetHideShelfWhenFullscreen()); - EXPECT_FALSE(tester->IsLocked()); + EXPECT_FALSE(tester.IsLocked()); } { FullscreenWaiter fullscreen_waiter(browser()); - tester->Lock(); + tester.Lock(); fullscreen_waiter.WaitForState(false); EXPECT_FALSE(browser_window->IsFullscreen()); - EXPECT_TRUE(tester->IsLocked()); + EXPECT_TRUE(tester.IsLocked()); } - tester->SetUnlockPassword(user_manager::StubAccountId(), "pass"); - tester->UnlockWithPassword(user_manager::StubAccountId(), "pass"); - EXPECT_FALSE(tester->IsLocked()); + tester.SetUnlockPassword(user_manager::StubAccountId(), "pass"); + tester.UnlockWithPassword(user_manager::StubAccountId(), "pass"); + EXPECT_FALSE(tester.IsLocked()); EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ( @@ -230,31 +230,31 @@ } IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestShowTwice) { - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester tester; + tester.Lock(); // Calling Show again simply send LockCompleted signal. ScreenLocker::Show(); - EXPECT_TRUE(tester->IsLocked()); + EXPECT_TRUE(tester.IsLocked()); EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count()); // Close the locker to match expectations. ScreenLocker::Hide(); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(tester->IsLocked()); + EXPECT_FALSE(tester.IsLocked()); EXPECT_EQ( 1, session_manager_client()->notify_lock_screen_dismissed_call_count()); } IN_PROC_BROWSER_TEST_F(ScreenLockerTest, PasswordAuthWhenAuthDisabled) { // Show lock screen and wait until it is shown. - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester tester; + tester.Lock(); // Inject fake authentication credentials. const std::string kPassword = "pass"; - tester->SetUnlockPassword(user_manager::StubAccountId(), kPassword); - EXPECT_TRUE(tester->IsLocked()); + tester.SetUnlockPassword(user_manager::StubAccountId(), kPassword); + EXPECT_TRUE(tester.IsLocked()); // Disable authentication for user. ScreenLocker::default_screen_locker()->SetAuthEnabledForUser( @@ -262,18 +262,18 @@ base::Time::Now() + base::TimeDelta::FromHours(1)); // Try to authenticate with password. - tester->UnlockWithPassword(user_manager::StubAccountId(), kPassword); + tester.UnlockWithPassword(user_manager::StubAccountId(), kPassword); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(tester->IsLocked()); + EXPECT_TRUE(tester.IsLocked()); // Re-enable authentication for user. ScreenLocker::default_screen_locker()->SetAuthEnabledForUser( user_manager::StubAccountId(), true /*is_enabled*/, base::nullopt); // Try to authenticate with password. - tester->UnlockWithPassword(user_manager::StubAccountId(), kPassword); + tester.UnlockWithPassword(user_manager::StubAccountId(), kPassword); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(tester->IsLocked()); + EXPECT_FALSE(tester.IsLocked()); EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ(session_manager::SessionState::ACTIVE, session_manager::SessionManager::Get()->session_state()); @@ -285,12 +285,12 @@ EnrollFingerprint(); // Show lock screen and wait until it is shown. - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - tester->Lock(); + ScreenLockerTester tester; + tester.Lock(); const std::string kPassword = "pass"; - tester->SetUnlockPassword(user_manager::StubAccountId(), kPassword); - EXPECT_TRUE(tester->IsLocked()); + tester.SetUnlockPassword(user_manager::StubAccountId(), kPassword); + EXPECT_TRUE(tester.IsLocked()); // Disable authentication for user. ScreenLocker::default_screen_locker()->SetAuthEnabledForUser( @@ -299,7 +299,7 @@ // Try to authenticate with fingerprint. AuthenticateWithFingerprint(); - EXPECT_TRUE(tester->IsLocked()); + EXPECT_TRUE(tester.IsLocked()); // Re-enable authentication for user. ScreenLocker::default_screen_locker()->SetAuthEnabledForUser( @@ -307,7 +307,7 @@ // Try to authenticate with fingerprint. AuthenticateWithFingerprint(); - EXPECT_FALSE(tester->IsLocked()); + EXPECT_FALSE(tester.IsLocked()); EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ(session_manager::SessionState::ACTIVE, session_manager::SessionManager::Get()->session_state());
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc index 75a8d23..6aca187 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc
@@ -9,7 +9,6 @@ #include "ash/public/cpp/ash_switches.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/login_screen_test_api.test-mojom-test-utils.h" -#include "ash/public/interfaces/login_screen_test_api.test-mojom.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" @@ -17,7 +16,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chromeos/login/auth/auth_status_consumer.h" #include "chromeos/login/auth/fake_extended_authenticator.h" #include "chromeos/login/auth/key.h" @@ -37,6 +35,16 @@ namespace chromeos { namespace { +// Helper to use inside a loop instead of using RunLoop::RunUntilIdle() to avoid +// the loop being a busy loop that prevents renderer from doing its job. Use +// only when there is no better way to synchronize. +void GiveItSomeTime(base::TimeDelta delta) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), delta); + run_loop.Run(); +} + bool IsScreenLockerLocked() { return ScreenLocker::default_screen_locker() && ScreenLocker::default_screen_locker()->locked(); @@ -83,121 +91,14 @@ DISALLOW_COPY_AND_ASSIGN(LoginAttemptObserver); }; -class WebUIScreenLockerTester : public ScreenLockerTester { - public: - WebUIScreenLockerTester() = default; - ~WebUIScreenLockerTester() override = default; - - // ScreenLockerTester: - bool IsLocked() override { return IsScreenLockerLocked(); } - void UnlockWithPassword(const AccountId& account_id, - const std::string& password) override { - bool result; - - SetPassword(password); - - // Verify password is set. - ASSERT_EQ(password, GetPassword()); - - // Verify that "reauth" warning is hidden. - std::unique_ptr<base::Value> v = content::ExecuteScriptAndGetValue( - GetMainFrame(), - "window.getComputedStyle(" - " $('pod-row').pods[0].querySelector('.reauth-hint-container'))" - " .display == 'none'"); - ASSERT_TRUE(v->GetAsBoolean(&result)); - ASSERT_TRUE(result); - - // Attempt to sign in. - LoginAttemptObserver login; - v = content::ExecuteScriptAndGetValue(GetMainFrame(), - "$('pod-row').pods[0].activate();"); - ASSERT_TRUE(v->GetAsBoolean(&result)); - ASSERT_TRUE(result); - - // Wait for login attempt. - login.WaitForAttempt(); - } - - private: - void SetPassword(const std::string& password) { - GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16( - base::StringPrintf("$('pod-row').pods[0].passwordElement.value = '%s';", - password.c_str()))); - } - - std::string GetPassword() { - std::string result; - std::unique_ptr<base::Value> v = content::ExecuteScriptAndGetValue( - GetMainFrame(), "$('pod-row').pods[0].passwordElement.value;"); - CHECK(v->GetAsString(&result)); - return result; - } - - content::RenderFrameHost* GetMainFrame() { - return webui()->GetWebContents()->GetMainFrame(); - } - - // Returns the ScreenLockerWebUI object. - WebUIScreenLocker* webui_screen_locker() { - DCHECK(ScreenLocker::default_screen_locker()); - return ScreenLocker::default_screen_locker()->web_ui_for_testing(); - } - - // Returns the WebUI object from the screen locker. - content::WebUI* webui() { - DCHECK(webui_screen_locker()->webui_ready_for_testing()); - content::WebUI* webui = webui_screen_locker()->GetWebUI(); - DCHECK(webui); - return webui; - } - - DISALLOW_COPY_AND_ASSIGN(WebUIScreenLockerTester); -}; - -class MojoScreenLockerTester : public ScreenLockerTester { - public: - MojoScreenLockerTester() { - content::ServiceManagerConnection::GetForProcess() - ->GetConnector() - ->BindInterface(ash::mojom::kServiceName, &test_api_); - } - ~MojoScreenLockerTester() override = default; - - // ScreenLockerTester: - bool IsLocked() override { - // Check from ash's perspective. - ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); - bool is_ui_shown; - login_screen.IsLockShown(&is_ui_shown); - return IsScreenLockerLocked() && is_ui_shown; - } - void UnlockWithPassword(const AccountId& account_id, - const std::string& password) override { - ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); - login_screen.SubmitPassword(account_id, password); - base::RunLoop().RunUntilIdle(); - } - - private: - ash::mojom::LoginScreenTestApiPtr test_api_; - - DISALLOW_COPY_AND_ASSIGN(MojoScreenLockerTester); -}; - } // namespace -// static -std::unique_ptr<ScreenLockerTester> ScreenLockerTester::Create() { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - ash::switches::kShowWebUiLock)) { - return std::make_unique<WebUIScreenLockerTester>(); - } - return std::make_unique<MojoScreenLockerTester>(); +ScreenLockerTester::ScreenLockerTester() { + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(ash::mojom::kServiceName, &test_api_); } -ScreenLockerTester::ScreenLockerTester() = default; - ScreenLockerTester::~ScreenLockerTester() = default; void ScreenLockerTester::Lock() { @@ -225,4 +126,56 @@ base::MakeRefCounted<FakeExtendedAuthenticator>(locker, user_context)); } +bool ScreenLockerTester::IsLocked() { + if (!IsScreenLockerLocked()) + return false; + + // Check from ash's perspective. + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + bool is_ui_shown; + login_screen.IsLockShown(&is_ui_shown); + return IsScreenLockerLocked() && is_ui_shown; +} + +bool ScreenLockerTester::IsRestartButtonShown() { + if (!IsScreenLockerLocked()) + return false; + + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + bool is_restart_button_shown; + login_screen.IsRestartButtonShown(&is_restart_button_shown); + return IsScreenLockerLocked() && is_restart_button_shown; +} + +bool ScreenLockerTester::IsShutdownButtonShown() { + if (!IsScreenLockerLocked()) + return false; + + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + bool is_shutdown_button_shown; + login_screen.IsShutdownButtonShown(&is_shutdown_button_shown); + return IsScreenLockerLocked() && is_shutdown_button_shown; +} + +void ScreenLockerTester::UnlockWithPassword(const AccountId& account_id, + const std::string& password) { + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + login_screen.SubmitPassword(account_id, password); + base::RunLoop().RunUntilIdle(); +} + +int64_t ScreenLockerTester::GetUiUpdateCount() { + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + int64_t ui_update_count = 0; + login_screen.GetUiUpdateCount(&ui_update_count); + return ui_update_count; +} + +// Blocks until LoginShelfView::ui_update_count() is greater then +// |previous_update_count|. +void ScreenLockerTester::WaitForUiUpdate(int64_t previous_update_count) { + while (GetUiUpdateCount() <= previous_update_count) { + GiveItSomeTime(base::TimeDelta::FromMilliseconds(100)); + } +} } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.h b/chrome/browser/chromeos/login/lock/screen_locker_tester.h index 4660a69c..179e653 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.h +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.h
@@ -8,19 +8,17 @@ #include <memory> #include <string> +#include "ash/public/interfaces/login_screen_test_api.test-mojom.h" + class AccountId; namespace chromeos { -// ScreenLockerTester provides a high-level API to test the lock screen. This -// API is meant to be representation independent. +// ScreenLockerTester provides a high-level API to test the lock screen. class ScreenLockerTester { public: - // Create a new tester. - static std::unique_ptr<ScreenLockerTester> Create(); - ScreenLockerTester(); - virtual ~ScreenLockerTester(); + ~ScreenLockerTester(); // Synchronously lock the device. void Lock(); @@ -30,11 +28,29 @@ const std::string& password); // Returns true if the screen is locked. - virtual bool IsLocked() = 0; + bool IsLocked(); + + // Returns true if Restart button is visible. + bool IsRestartButtonShown(); + + // Returns true if Shutdown button is visible. + bool IsShutdownButtonShown(); // Enters and submits the given password for the given account. - virtual void UnlockWithPassword(const AccountId& account_id, - const std::string& password) = 0; + void UnlockWithPassword(const AccountId& account_id, + const std::string& password); + + // Returns LoginShelfView update count. + int64_t GetUiUpdateCount(); + + // Blocks until LoginShelfView::ui_update_count() is creater then + // |previous_update_count|. + void WaitForUiUpdate(int64_t previous_update_count); + + private: + ash::mojom::LoginScreenTestApiPtr test_api_; + + DISALLOW_COPY_AND_ASSIGN(ScreenLockerTester); }; } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index 856ee48..d2063fa 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -136,10 +136,6 @@ OnAllowedInputMethodsChanged(); } -void ViewsScreenLocker::SetPasswordInputEnabled(bool enabled) { - NOTIMPLEMENTED(); -} - void ViewsScreenLocker::ShowErrorMessage( int error_msg_id, HelpAppLauncher::HelpTopic help_topic_id) { @@ -153,18 +149,6 @@ LoginScreenClient::Get()->login_screen()->ClearErrors(); } -void ViewsScreenLocker::OnLockWebUIReady() { - NOTIMPLEMENTED(); -} - -void ViewsScreenLocker::OnLockBackgroundDisplayed() { - NOTIMPLEMENTED(); -} - -void ViewsScreenLocker::OnHeaderBarVisible() { - NOTIMPLEMENTED(); -} - void ViewsScreenLocker::OnAshLockAnimationFinished() { SessionControllerClient::Get()->NotifyChromeLockAnimationsComplete(); } @@ -182,10 +166,6 @@ account_id, success); } -content::WebContents* ViewsScreenLocker::GetWebContents() { - return nullptr; -} - void ViewsScreenLocker::HandleAuthenticateUserWithPasswordOrPin( const AccountId& account_id, const std::string& password,
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.h b/chrome/browser/chromeos/login/lock/views_screen_locker.h index 099caf7..19c04ab 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.h +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.h
@@ -39,19 +39,14 @@ void OnLockScreenReady(); // ScreenLocker::Delegate: - void SetPasswordInputEnabled(bool enabled) override; void ShowErrorMessage(int error_msg_id, HelpAppLauncher::HelpTopic help_topic_id) override; void ClearErrors() override; - void OnLockWebUIReady() override; - void OnLockBackgroundDisplayed() override; - void OnHeaderBarVisible() override; void OnAshLockAnimationFinished() override; void SetFingerprintState(const AccountId& account_id, ash::mojom::FingerprintState state) override; void NotifyFingerprintAuthResult(const AccountId& account_id, bool success) override; - content::WebContents* GetWebContents() override; // LoginScreenClient::Delegate void HandleAuthenticateUserWithPasswordOrPin(
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc deleted file mode 100644 index 69220ef..0000000 --- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc +++ /dev/null
@@ -1,378 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" - -#include "ash/public/cpp/ash_pref_names.h" -#include "ash/public/cpp/ash_switches.h" -#include "ash/public/cpp/lock_screen_widget_factory.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/feature_list.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/helper.h" -#include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" -#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h" -#include "chrome/browser/chromeos/login/ui/login_display_webui.h" -#include "chrome/browser/chromeos/login/ui/preloaded_web_view.h" -#include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/lifetime/browser_shutdown.h" -#include "chrome/browser/ui/ash/session_controller_client.h" -#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" -#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "components/login/base_screen_handler_utils.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/user.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/ui_base_features.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" -#include "ui/views/controls/webview/webview.h" -#include "ui/views/widget/widget.h" - -namespace { - -// URL which corresponds to the login WebUI. -const char kLoginURL[] = "chrome://oobe/lock"; - -} // namespace - -namespace chromeos { - -// static -void WebUIScreenLocker::RequestPreload() { - if (!ShouldPreloadLockScreen()) - return; - - VLOG(1) << "Preloading lock screen"; - PreloadedWebView* preloaded_web_view = - PreloadedWebViewFactory::GetForProfile(ProfileHelper::GetSigninProfile()); - preloaded_web_view->PreloadOnIdle( - base::BindOnce(&WebUIScreenLocker::DoPreload)); -} - -// static -bool WebUIScreenLocker::ShouldPreloadLockScreen() { - // Only preload webui lock screen when it is used. - if (ash::switches::IsUsingViewsLock()) - return false; - - // Bail for mash because IdleDetector/UserActivityDetector does not work - // properly there. - // TODO(xiyuan): Revisit after http://crbug.com/626899. - if (features::IsMultiProcessMash()) - return false; - - Profile* profile = ProfileHelper::Get()->GetProfileByUser( - user_manager::UserManager::Get()->GetActiveUser()); - - // We only want to preload the lock screen if the user is likely to see the - // lock screen (since caching the lock screen uses memory). Without - // preloading, showing the lock screen can take so long we will timeout and - // crash the browser process (which currently takes down all of Chrome). See - // crbug.com/452599 for more context. - // - // prefs::kEnableAutoScreenLock controls if the lock screen is shown on - // suspend, so that is our primary hueristic. - - // Note that |profile| can be null in tests. - return base::FeatureList::IsEnabled(features::kPreloadLockScreen) && - profile && - profile->GetPrefs()->GetBoolean(ash::prefs::kEnableAutoScreenLock); -} - -// static -std::unique_ptr<views::WebView> WebUIScreenLocker::DoPreload(Profile* profile) { - auto web_view = std::make_unique<views::WebView>(profile); - web_view->set_owned_by_client(); - web_view->LoadInitialURL(GURL(kLoginURL)); - InitializeWebView(web_view.get(), l10n_util::GetStringUTF16( - IDS_LOCK_SCREEN_TASK_MANAGER_NAME)); - return web_view; -} - -//////////////////////////////////////////////////////////////////////////////// -// WebUIScreenLocker implementation. - -WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker) - : WebUILoginView(BuildConfigSettings()), - screen_locker_(screen_locker), - network_state_helper_(new login::NetworkStateHelper), - weak_factory_(this) { - // This class is a View, and contained in a view hierarchy, but also owned. - // Use set_owned_by_client() so it isn't deleted by Views. - set_owned_by_client(); - set_should_emit_login_prompt_visible(false); - display::Screen::GetScreen()->AddObserver(this); - DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); -} - -WebUIScreenLocker::~WebUIScreenLocker() { - DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); - // If LockScreen() was called, we need to clear the signin screen handler - // delegate set in ShowSigninScreen so that it no longer points to us. - if (login_display_.get() && GetOobeUI()) - GetOobeUI()->ResetSigninScreenHandlerDelegate(); - - ClearLockScreenAppFocusCyclerDelegate(); - - RequestPreload(); - - // This has to be after calls to GetOobeUI(). - lock_widget_.reset(); -} - -void WebUIScreenLocker::LockScreen() { - gfx::Rect bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); - - lock_time_ = base::TimeTicks::Now(); - lock_widget_ = ash::CreateLockScreenWidget(); - - Init(); - content::WebContentsObserver::Observe(web_view()->GetWebContents()); - - lock_widget_->SetContentsView(this); - lock_widget_->SetBounds(bounds); - lock_widget_->Show(); - LoadURL(GURL(kLoginURL)); - OnLockWindowReady(); - - signin_screen_controller_.reset(new SignInScreenController(GetOobeUI())); - - login_display_.reset(new LoginDisplayWebUI()); - login_display_->set_delegate(this); - login_display_->set_parent_window(GetNativeWindow()); - login_display_->Init(screen_locker_->users(), false, true, false); - - GetOobeUI()->ShowSigninScreen(LoginScreenContext(), login_display_.get(), - login_display_.get()); - - SetLockScreenAppFocusCyclerDelegate(); -} - -void WebUIScreenLocker::SetPasswordInputEnabled(bool enabled) { - login_display_->SetUIEnabled(enabled); -} - -void WebUIScreenLocker::ShowErrorMessage( - int error_msg_id, - HelpAppLauncher::HelpTopic help_topic_id) { - login_display_->ShowError(error_msg_id, 0 /* login_attempts */, - help_topic_id); -} - -void WebUIScreenLocker::ClearErrors() { - GetWebUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.clearErrors"); -} - -void WebUIScreenLocker::ScreenLockReady() { - UMA_HISTOGRAM_TIMES("LockScreen.LockReady", - base::TimeTicks::Now() - lock_time_); - screen_locker_->ScreenLockReady(); - SetPasswordInputEnabled(true); -} - -void WebUIScreenLocker::OnLockWindowReady() { - VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not"); - lock_ready_ = true; - if (webui_ready_) - ScreenLockReady(); -} - -gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const { - return lock_widget_->GetNativeWindow(); -} - -void WebUIScreenLocker::FocusUserPod() { - if (!webui_ready_) - return; - web_view()->RequestFocus(); - GetWebUI()->CallJavascriptFunctionUnsafe( - "cr.ui.Oobe.forceLockedUserPodFocus"); -} - -void WebUIScreenLocker::ResetAndFocusUserPod() { - if (!webui_ready_) - return; - GetWebUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.clearUserPodPassword"); - FocusUserPod(); -} - -WebUILoginView::WebViewSettings WebUIScreenLocker::BuildConfigSettings() { - chromeos::WebUILoginView::WebViewSettings settings; - if (chromeos::WebUIScreenLocker::ShouldPreloadLockScreen()) { - settings.check_for_preload = true; - settings.web_view_title = - l10n_util::GetStringUTF16(IDS_LOCK_SCREEN_TASK_MANAGER_NAME); - } - return settings; -} - -void WebUIScreenLocker::OnLockWebUIReady() { - VLOG(1) << "WebUI ready; lock window is " << (lock_ready_ ? "too" : "not"); - webui_ready_ = true; - if (lock_ready_) - ScreenLockReady(); -} - -void WebUIScreenLocker::OnLockBackgroundDisplayed() { - UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady", - base::TimeTicks::Now() - lock_time_); -} - -void WebUIScreenLocker::OnHeaderBarVisible() { - SessionControllerClient::Get()->NotifyChromeLockAnimationsComplete(); -} - -void WebUIScreenLocker::OnAshLockAnimationFinished() { - // Release capture if any. - aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow()) - ->SetCapture(nullptr); - GetWebUI()->CallJavascriptFunctionUnsafe( - "cr.ui.Oobe.animateOnceFullyDisplayed"); -} - -void WebUIScreenLocker::SetFingerprintState( - const AccountId& account_id, - ash::mojom::FingerprintState state) { - NOTREACHED(); -} - -void WebUIScreenLocker::NotifyFingerprintAuthResult(const AccountId& account_id, - bool success) { - NOTREACHED(); -} - -content::WebContents* WebUIScreenLocker::GetWebContents() { - return WebUILoginView::GetWebContents(); -} - -//////////////////////////////////////////////////////////////////////////////// -// WebUIScreenLocker, LoginDisplay::Delegate: -base::string16 WebUIScreenLocker::GetConnectedNetworkName() { - return network_state_helper_->GetCurrentNetworkName(); -} - -bool WebUIScreenLocker::IsSigninInProgress() const { - // The way how screen locker is implemented right now there's no - // GAIA sign in in progress in any case. - return false; -} - -void WebUIScreenLocker::Login(const UserContext& user_context, - const SigninSpecifics& specifics) { - chromeos::ScreenLocker::default_screen_locker()->Authenticate( - user_context, ScreenLocker::AuthenticateCallback()); -} - -void WebUIScreenLocker::OnSigninScreenReady() { - VLOG(2) << "Lock screen signin screen is ready"; -} - -void WebUIScreenLocker::OnStartEnterpriseEnrollment() { - NOTREACHED(); -} - -void WebUIScreenLocker::OnStartEnableDebuggingScreen() { - NOTREACHED(); -} - -void WebUIScreenLocker::OnStartKioskEnableScreen() { - NOTREACHED(); -} - -void WebUIScreenLocker::OnStartKioskAutolaunchScreen() { - NOTREACHED(); -} - -void WebUIScreenLocker::ShowWrongHWIDScreen() { - NOTREACHED(); -} - -void WebUIScreenLocker::ShowUpdateRequiredScreen() { - NOTREACHED(); -} - -void WebUIScreenLocker::ResetAutoLoginTimer() {} - -void WebUIScreenLocker::Signout() { - chromeos::ScreenLocker::default_screen_locker()->Signout(); -} - -//////////////////////////////////////////////////////////////////////////////// -// PowerManagerClient::Observer: - -void WebUIScreenLocker::LidEventReceived(PowerManagerClient::LidState state, - const base::TimeTicks& time) { - if (state == PowerManagerClient::LidState::OPEN) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&WebUIScreenLocker::FocusUserPod, - weak_factory_.GetWeakPtr())); - } -} - -void WebUIScreenLocker::SuspendImminent( - power_manager::SuspendImminent::Reason reason) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&WebUIScreenLocker::ResetAndFocusUserPod, - weak_factory_.GetWeakPtr())); -} - -void WebUIScreenLocker::SuspendDone(const base::TimeDelta& sleep_duration) { - base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&WebUIScreenLocker::FocusUserPod, - weak_factory_.GetWeakPtr())); - screen_locker_->RefreshPinAndFingerprintTimeout(); -} - -void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) { - if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID && - status != base::TERMINATION_STATUS_NORMAL_TERMINATION) { - LOG(ERROR) << "Renderer crash on lock screen; signing out"; - Signout(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// display::DisplayObserver: - -void WebUIScreenLocker::OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) { - display::Display primary_display = - display::Screen::GetScreen()->GetPrimaryDisplay(); - if (display.id() != primary_display.id() || - !(changed_metrics & DISPLAY_METRIC_BOUNDS)) { - return; - } - - if (GetOobeUI()) { - const gfx::Size& size = primary_display.size(); - GetOobeUI()->GetCoreOobeView()->SetClientAreaSize(size.width(), - size.height()); - } -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.h b/chrome/browser/chromeos/login/lock/webui_screen_locker.h deleted file mode 100644 index ba0c3b87..0000000 --- a/chrome/browser/chromeos/login/lock/webui_screen_locker.h +++ /dev/null
@@ -1,161 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_LOCK_WEBUI_SCREEN_LOCKER_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_LOCK_WEBUI_SCREEN_LOCKER_H_ - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/signin_screen_controller.h" -#include "chrome/browser/chromeos/login/signin_specifics.h" -#include "chrome/browser/chromeos/login/ui/login_display.h" -#include "chrome/browser/chromeos/login/ui/webui_login_view.h" -#include "chromeos/dbus/power_manager_client.h" -#include "content/public/browser/web_contents_observer.h" -#include "ui/display/display_observer.h" - -namespace content { -class WebUI; -} - -namespace views { -class Widget; -} - -namespace chromeos { - -class ScreenLocker; -class LoginDisplayWebUI; - -namespace login { -class NetworkStateHelper; -} - -// Displays a WebUI lock screen based on the Oobe account picker screen. -class WebUIScreenLocker : public WebUILoginView, - public ScreenLocker::Delegate, - public LoginDisplay::Delegate, - public PowerManagerClient::Observer, - public display::DisplayObserver, - public content::WebContentsObserver { - public: - // Request lock screen preload when the user is idle. Does nothing if - // preloading is disabled or if the preload hueristics return false. - static void RequestPreload(); - - explicit WebUIScreenLocker(ScreenLocker* screen_locker); - ~WebUIScreenLocker() override; - - // Begin initializing the widget and views::WebView that show the lock screen. - // ScreenLockReady is called when all initialization has finished. - void LockScreen(); - - bool webui_ready_for_testing() const { return webui_ready_; } - - private: - - // Returns true if the lock screen should be preloaded. - static bool ShouldPreloadLockScreen(); - // Helper function that creates and preloads a views::WebView. - static std::unique_ptr<views::WebView> DoPreload(Profile* profile); - - // ScreenLocker::Delegate: - void SetPasswordInputEnabled(bool enabled) override; - void ShowErrorMessage(int error_msg_id, - HelpAppLauncher::HelpTopic help_topic_id) override; - void ClearErrors() override; - void OnLockWebUIReady() override; - void OnLockBackgroundDisplayed() override; - void OnHeaderBarVisible() override; - void OnAshLockAnimationFinished() override; - void SetFingerprintState(const AccountId& account_id, - ash::mojom::FingerprintState state) override; - void NotifyFingerprintAuthResult(const AccountId& account_id, - bool success) override; - content::WebContents* GetWebContents() override; - - // LoginDisplay::Delegate: - base::string16 GetConnectedNetworkName() override; - bool IsSigninInProgress() const override; - void Login(const UserContext& user_context, - const SigninSpecifics& specifics) override; - void OnSigninScreenReady() override; - void OnStartEnterpriseEnrollment() override; - void OnStartEnableDebuggingScreen() override; - void OnStartKioskEnableScreen() override; - void OnStartKioskAutolaunchScreen() override; - void ShowWrongHWIDScreen() override; - void ShowUpdateRequiredScreen() override; - void ResetAutoLoginTimer() override; - void Signout() override; - - // PowerManagerClient::Observer: - void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; - void SuspendDone(const base::TimeDelta& sleep_duration) override; - void LidEventReceived(PowerManagerClient::LidState state, - const base::TimeTicks& time) override; - - // content::WebContentsObserver: - void RenderProcessGone(base::TerminationStatus status) override; - - // display::DisplayObserver: - void OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) override; - - // Inform the screen locker that the screen has been locked - void ScreenLockReady(); - - // Called when the lock window is ready. - void OnLockWindowReady(); - - // Returns the native window displaying the lock screen. - gfx::NativeWindow GetNativeWindow() const; - - // Ensures that user pod is focused. - void FocusUserPod(); - - // Reset user pod and ensures that user pod is focused. - void ResetAndFocusUserPod(); - - // Configuration settings. - WebViewSettings BuildConfigSettings(); - - // The ScreenLocker that owns this instance. - ScreenLocker* screen_locker_ = nullptr; - - // The screen locker widget. - std::unique_ptr<views::Widget> lock_widget_; - - // Sign-in Screen controller instance (owns login screens). - std::unique_ptr<SignInScreenController> signin_screen_controller_; - - // Login UI implementation instance. - std::unique_ptr<LoginDisplayWebUI> login_display_; - - // Tracks when the lock window is displayed and ready. - bool lock_ready_ = false; - - // Tracks when the WebUI finishes loading. - bool webui_ready_ = false; - - // Time when lock was initiated, required for metrics. - base::TimeTicks lock_time_; - - std::unique_ptr<login::NetworkStateHelper> network_state_helper_; - - base::WeakPtrFactory<WebUIScreenLocker> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(WebUIScreenLocker); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_LOCK_WEBUI_SCREEN_LOCKER_H_
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index 2d86b141..327900b 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" #include "chrome/browser/chromeos/login/demo_mode/demo_resources.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/screens/arc_terms_of_service_screen.h" #include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" @@ -279,8 +278,6 @@ content::Source<session_manager::SessionManager>(this), content::Details<const user_manager::User>( user_manager->GetActiveUser())); - - chromeos::WebUIScreenLocker::RequestPreload(); } void ChromeSessionManager::NotifyUserLoggedIn(const AccountId& user_account_id,
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 13af0b3..b53096d 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -92,7 +92,6 @@ #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/supervised_user/child_accounts/child_account_service.h" @@ -135,7 +134,6 @@ #include "components/prefs/pref_service.h" #include "components/quirks/quirks_manager.h" #include "components/session_manager/core/session_manager.h" -#include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_error_controller.h" #include "components/user_manager/known_user.h" #include "components/user_manager/user.h" @@ -149,6 +147,7 @@ #include "content/public/common/content_switches.h" #include "extensions/common/features/feature_session_type.h" #include "rlz/buildflags/buildflags.h" +#include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/identity_manager.h" #include "third_party/cros_system_api/switches/chrome_switches.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" @@ -1306,13 +1305,18 @@ // not be available when unlocking a previously opened profile, or when // creating a supervised users. However, in these cases the gaia_id should // be already available in the account tracker. + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); std::string gaia_id = user_context.GetGaiaID(); if (gaia_id.empty()) { - AccountTrackerService* account_tracker = - AccountTrackerServiceFactory::GetForProfile(profile); - const AccountInfo info = account_tracker->FindAccountInfoByEmail( - user_context.GetAccountId().GetUserEmail()); - gaia_id = info.gaia; + base::Optional<AccountInfo> maybe_account_info = + identity_manager + ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress( + user_context.GetAccountId().GetUserEmail()); + + DCHECK(maybe_account_info.has_value() || IsRunningTest()); + if (maybe_account_info.has_value()) + gaia_id = maybe_account_info.value().gaia; // Use a fake gaia id for tests that do not have it. if (IsRunningTest() && gaia_id.empty()) @@ -1328,30 +1332,28 @@ // mainstream Identity Service API once that API exists. Note that this // might require supplying a valid refresh token here as opposed to an // empty string. - identity::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); identity_manager->SetPrimaryAccountSynchronously( gaia_id, user_context.GetAccountId().GetUserEmail(), /*refresh_token=*/std::string()); std::string account_id = identity_manager->GetPrimaryAccountId(); + VLOG(1) << "Seed IdentityManager with the authenticated account info, " + << "success=" << !account_id.empty(); + const user_manager::User* user = user_manager->FindUser(user_context.GetAccountId()); bool is_child = user->GetType() == user_manager::USER_TYPE_CHILD; DCHECK(is_child == (user_context.GetUserType() == user_manager::USER_TYPE_CHILD)); - AccountTrackerService* account_tracker = - AccountTrackerServiceFactory::GetForProfile(profile); - account_tracker->SetIsChildAccount(account_id, is_child); - VLOG(1) - << "Seed IdentityManager and SigninManagerBase with the " - << "authenticated account info, success=" - << IdentityManagerFactory::GetForProfile(profile)->HasPrimaryAccount(); + base::Optional<bool> is_under_advanced_protection; if (IsOnlineSignin(user_context)) { - account_tracker->SetIsAdvancedProtectionAccount( - account_id, user_context.IsUnderAdvancedProtection()); + is_under_advanced_protection = user_context.IsUnderAdvancedProtection(); } + identity_manager->GetAccountsMutator()->UpdateAccountInfo( + account_id, /*is_child_account=*/is_child, + is_under_advanced_protection); + if (is_child && base::FeatureList::IsEnabled(::features::kDMServerOAuthForChildUser)) { child_policy_observer_ = std::make_unique<ChildPolicyObserver>(profile);
diff --git a/chrome/browser/chromeos/login/signin_screen_controller.cc b/chrome/browser/chromeos/login/signin_screen_controller.cc index 4aaa1c2..8381ca00 100644 --- a/chrome/browser/chromeos/login/signin_screen_controller.cc +++ b/chrome/browser/chromeos/login/signin_screen_controller.cc
@@ -6,7 +6,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h" #include "chrome/browser/chromeos/login/ui/views/user_board_view.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" @@ -55,8 +54,6 @@ void SignInScreenController::OnSigninScreenReady() { gaia_screen_->MaybePreloadAuthExtension(); user_selection_screen_->InitEasyUnlock(); - if (ScreenLocker::default_screen_locker()) - ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady(); } void SignInScreenController::RemoveUser(const AccountId& account_id) {
diff --git a/chrome/browser/chromeos/login/ui/preloaded_web_view.cc b/chrome/browser/chromeos/login/ui/preloaded_web_view.cc deleted file mode 100644 index 9802bad..0000000 --- a/chrome/browser/chromeos/login/ui/preloaded_web_view.cc +++ /dev/null
@@ -1,90 +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 "chrome/browser/chromeos/login/ui/preloaded_web_view.h" - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/time/default_tick_clock.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/idle_detector.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/web_contents.h" -#include "ui/views/controls/webview/webview.h" - -namespace chromeos { - -namespace { -// Duration of user inactivity before running the preload function. -constexpr int kIdleSecondsBeforePreloadingLockScreen = 8; -} // namespace - -PreloadedWebView::PreloadedWebView(Profile* profile) - : profile_(profile), weak_factory_(this) { - registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, - content::NotificationService::AllSources()); - memory_pressure_listener_ = - std::make_unique<base::MemoryPressureListener>(base::Bind( - &PreloadedWebView::OnMemoryPressure, weak_factory_.GetWeakPtr())); -} - -PreloadedWebView::~PreloadedWebView() {} - -void PreloadedWebView::PreloadOnIdle(PreloadCallback preload) { - preload_function_ = std::move(preload); - idle_detector_ = std::make_unique<chromeos::IdleDetector>( - base::BindRepeating(&PreloadedWebView::RunPreloader, - weak_factory_.GetWeakPtr()), - base::DefaultTickClock::GetInstance()); - idle_detector_->Start( - base::TimeDelta::FromSeconds(kIdleSecondsBeforePreloadingLockScreen)); -} - -std::unique_ptr<views::WebView> PreloadedWebView::TryTake() { - idle_detector_.reset(); - - // Clear cached reference if it is no longer valid (ie, destroyed in task - // manager). - if (preloaded_instance_ && !preloaded_instance_->GetWebContents() - ->GetRenderViewHost() - ->GetWidget() - ->GetView()) { - preloaded_instance_.reset(); - } - - return std::move(preloaded_instance_); -} - -void PreloadedWebView::Shutdown() { - preloaded_instance_.reset(); -} - -void PreloadedWebView::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type); - preloaded_instance_.reset(); -} - -void PreloadedWebView::OnMemoryPressure( - base::MemoryPressureListener::MemoryPressureLevel level) { - switch (level) { - case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: - break; - case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: - case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: - preloaded_instance_.reset(); - break; - } -} - -void PreloadedWebView::RunPreloader() { - idle_detector_.reset(); - preloaded_instance_ = std::move(preload_function_).Run(profile_); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/preloaded_web_view.h b/chrome/browser/chromeos/login/ui/preloaded_web_view.h deleted file mode 100644 index cfcc38b..0000000 --- a/chrome/browser/chromeos/login/ui/preloaded_web_view.h +++ /dev/null
@@ -1,84 +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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_H_ - -#include <memory> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/memory_pressure_listener.h" -#include "base/memory/weak_ptr.h" -#include "components/keyed_service/core/keyed_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -class Profile; - -namespace views { -class WebView; -} - -namespace chromeos { - -class IdleDetector; - -// Stores and fetches a views::WebView instance that is ulimately owned by the -// signin profile. This allows for a WebView to be reused over time or -// preloaded. Use PreloadedWebViewFactory to get an instance of this class. -class PreloadedWebView : public KeyedService, - public content::NotificationObserver { - public: - using PreloadCallback = - base::OnceCallback<std::unique_ptr<views::WebView>(Profile*)>; - - explicit PreloadedWebView(Profile* profile); - ~PreloadedWebView() override; - - // Executes the given |preload| function when the device is idle. - void PreloadOnIdle(PreloadCallback preload); - - // Try to fetch a preloaded instance. Returns nullptr if no instance has been - // preloaded. Calling this function will cancel any pending preload. - std::unique_ptr<views::WebView> TryTake(); - - private: - // KeyedSerivce: - void Shutdown() override; - - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // Called when there is a memory pressure event. - void OnMemoryPressure( - base::MemoryPressureListener::MemoryPressureLevel level); - - // Runs the preload function. Called only by |idle_detector_|. - void RunPreloader(); - - // Used to execute the preload function when the user is idle. - std::unique_ptr<IdleDetector> idle_detector_; - // The preload function. Can only be called once. - PreloadCallback preload_function_; - // The result of the preload function. - std::unique_ptr<views::WebView> preloaded_instance_; - // Profile passed into the preload function. - Profile* profile_; - - // Used to destroy a preloaded but not used WebView on shutdown. - content::NotificationRegistrar registrar_; - // Used to destroy a preloaded but not used WebView on low-memory. - std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; - - base::WeakPtrFactory<PreloadedWebView> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PreloadedWebView); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_H_
diff --git a/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.cc b/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.cc deleted file mode 100644 index cd1322bf..0000000 --- a/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.cc +++ /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. - -#include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h" - -#include "chrome/browser/chromeos/login/ui/preloaded_web_view.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/incognito_helpers.h" -#include "chrome/browser/profiles/profile.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" - -namespace chromeos { - -// static -PreloadedWebView* PreloadedWebViewFactory::GetForProfile(Profile* profile) { - auto* result = static_cast<PreloadedWebView*>( - GetInstance()->GetServiceForBrowserContext(profile, true)); - return result; -} - -// static -PreloadedWebViewFactory* PreloadedWebViewFactory::GetInstance() { - return base::Singleton<PreloadedWebViewFactory>::get(); -} - -PreloadedWebViewFactory::PreloadedWebViewFactory() - : BrowserContextKeyedServiceFactory( - "PreloadedWebViewFactory", - BrowserContextDependencyManager::GetInstance()) {} - -PreloadedWebViewFactory::~PreloadedWebViewFactory() {} - -content::BrowserContext* PreloadedWebViewFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - // Make sure that only the SigninProfile is using a preloaded webview. - if (Profile::FromBrowserContext(context) != ProfileHelper::GetSigninProfile()) - return nullptr; - - return context; -} - -KeyedService* PreloadedWebViewFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new PreloadedWebView(Profile::FromBrowserContext(context)); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h b/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h deleted file mode 100644 index 91b05af..0000000 --- a/chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h +++ /dev/null
@@ -1,42 +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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class Profile; - -namespace chromeos { - -class PreloadedWebView; - -// Fetches a PreloadedWebView instance for the signin profile. -class PreloadedWebViewFactory : public BrowserContextKeyedServiceFactory { - public: - static PreloadedWebView* GetForProfile(Profile* profile); - - static PreloadedWebViewFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<PreloadedWebViewFactory>; - - PreloadedWebViewFactory(); - ~PreloadedWebViewFactory() override; - - // BrowserContextKeyedServiceFactory: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* profile) const override; - - DISALLOW_COPY_AND_ASSIGN(PreloadedWebViewFactory); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_UI_PRELOADED_WEB_VIEW_FACTORY_H_
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc index 8a96376..3cbeae8 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -21,8 +21,6 @@ #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h" #include "chrome/browser/chromeos/login/ui/login_display_webui.h" -#include "chrome/browser/chromeos/login/ui/preloaded_web_view.h" -#include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h" #include "chrome/browser/chromeos/login/ui/web_contents_forced_title.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" @@ -227,25 +225,13 @@ void WebUILoginView::Init() { Profile* signin_profile = ProfileHelper::GetSigninProfile(); - - if (settings_.check_for_preload) { - PreloadedWebView* preloaded_web_view = - PreloadedWebViewFactory::GetForProfile(signin_profile); - // webui_login_ may still be null after this call if there is no preloaded - // instance. - webui_login_ = preloaded_web_view->TryTake(); - is_reusing_webview_ = true; - } - if (!webui_login_) { webui_login_ = std::make_unique<views::WebView>(signin_profile); webui_login_->set_owned_by_client(); - is_reusing_webview_ = false; } WebContents* web_contents = web_view()->GetWebContents(); - if (!is_reusing_webview_) - InitializeWebView(web_view(), settings_.web_view_title); + InitializeWebView(web_view(), settings_.web_view_title); web_view()->set_allow_accelerators(true); AddChildView(web_view()); @@ -316,8 +302,7 @@ } void WebUILoginView::LoadURL(const GURL& url) { - if (!is_reusing_webview_) - web_view()->LoadInitialURL(url); + web_view()->LoadInitialURL(url); web_view()->RequestFocus(); }
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.h b/chrome/browser/chromeos/login/ui/webui_login_view.h index 69875083..cc29db4 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.h +++ b/chrome/browser/chromeos/login/ui/webui_login_view.h
@@ -191,9 +191,6 @@ // WebView for rendering a webpage as a webui login. std::unique_ptr<views::WebView> webui_login_; - // True if the current webview instance (ie, GetWebUI()) has been reused. - bool is_reusing_webview_ = false; - // Converts keyboard events on the WebContents to accelerators. views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
diff --git a/chrome/browser/chromeos/power/renderer_freezer.cc b/chrome/browser/chromeos/power/renderer_freezer.cc index 882c758c..17f7d23 100644 --- a/chrome/browser/chromeos/power/renderer_freezer.cc +++ b/chrome/browser/chromeos/power/renderer_freezer.cc
@@ -11,8 +11,6 @@ #include "base/logging.h" #include "base/process/process_handle.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" @@ -65,12 +63,6 @@ const content::NotificationSource& source, const content::NotificationDetails& details) { switch (type) { - case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { - OnScreenLockStateChanged( - content::Source<chromeos::ScreenLocker>(source).ptr(), - *(content::Details<bool>(details).ptr())); - break; - } case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { content::RenderProcessHost* process = content::Source<content::RenderProcessHost>(source).ptr(); @@ -121,8 +113,6 @@ ->GetPowerManagerClient() ->SetRenderProcessManagerDelegate(weak_factory_.GetWeakPtr()); - registrar_.Add(this, chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, - content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add( this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, @@ -139,27 +129,6 @@ LOG(FATAL) << "Unable to thaw renderers."; } -void RendererFreezer::OnScreenLockStateChanged(chromeos::ScreenLocker* locker, - bool is_locked) { - // The ScreenLocker class sends NOTIFICATION_SCREEN_LOCK_STATE_CHANGED when - // the lock screen becomes ready, resulting in this code running synchronously - // to mark the screen locker renderer to remain unfrozen during a suspend - // request. Since this happens before the PowerManagerClient calls - // RendererFreezer::SuspendImminent(), it is guaranteed that the screen locker - // renderer will not be frozen at any point. - if (is_locked) { - // |web_contents| is null when using views-based login/lock screen. - // TODO(jdufault): Remove this code after webui login/lock is gone. See - // crbug.com/719015. - content::WebContents* web_contents = locker->delegate()->GetWebContents(); - if (web_contents) { - delegate_->SetShouldFreezeRenderer( - web_contents->GetMainFrame()->GetProcess()->GetProcess().Handle(), - false); - } - } -} - void RendererFreezer::OnRenderProcessCreated(content::RenderProcessHost* rph) { const int rph_id = rph->GetID();
diff --git a/chrome/browser/chromeos/power/renderer_freezer.h b/chrome/browser/chromeos/power/renderer_freezer.h index 89dbcd2b..0d1cf16 100644 --- a/chrome/browser/chromeos/power/renderer_freezer.h +++ b/chrome/browser/chromeos/power/renderer_freezer.h
@@ -25,8 +25,6 @@ namespace chromeos { -class ScreenLocker; - // Freezes the chrome renderers when the system is about to suspend and thaws // them after the system fully resumes. This class registers itself as a // PowerManagerClient::Observer on creation and unregisters itself on @@ -86,9 +84,6 @@ // Called after thawing the renderers has completed. void OnThawRenderersComplete(bool success); - // Called whenever the screen locker is shown or hidden. - void OnScreenLockStateChanged(chromeos::ScreenLocker* locker, bool is_locked); - // Called whenever a new renderer process is created. void OnRenderProcessCreated(content::RenderProcessHost* rph);
diff --git a/chrome/browser/chromeos/shutdown_policy_browsertest.cc b/chrome/browser/chromeos/shutdown_policy_browsertest.cc index 41f080c..132a46c 100644 --- a/chrome/browser/chromeos/shutdown_policy_browsertest.cc +++ b/chrome/browser/chromeos/shutdown_policy_browsertest.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/login/lock/screen_locker_tester.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/webui_login_view.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" @@ -74,7 +73,7 @@ : public policy::DevicePolicyCrosBrowserTest, public DeviceSettingsService::Observer { protected: - ShutdownPolicyBaseTest() : contents_(nullptr) {} + ShutdownPolicyBaseTest() {} ~ShutdownPolicyBaseTest() override {} // DeviceSettingsService::Observer: @@ -105,14 +104,6 @@ expectation ? "true" : "false"); } - // Checks whether the element identified by |element_id| is hidden and only - // returns if the expectation is fulfilled. - void PrepareAndRunScript(const std::string& element_id, bool expectation) { - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents_, PrepareScript(element_id, expectation), - &result_)); - } - // Updates the device shutdown policy and sets it to |reboot_on_shutdown|. void UpdateRebootOnShutdownPolicy(bool reboot_on_shutdown) { policy::DevicePolicyBuilder* builder = device_policy(); @@ -142,7 +133,6 @@ run_loop.Run(); } - content::WebContents* contents_; bool result_; std::unique_ptr<base::RunLoop> run_loop_; ash::mojom::SystemTrayTestApiPtr tray_test_api_; @@ -214,14 +204,8 @@ class ShutdownPolicyLockerTest : public ShutdownPolicyBaseTest { protected: - ShutdownPolicyLockerTest() : fake_session_manager_client_(nullptr) {} - ~ShutdownPolicyLockerTest() override {} - - void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ash::switches::kShowWebUiLock); - ShutdownPolicyBaseTest::SetUp(); - } + ShutdownPolicyLockerTest() = default; + ~ShutdownPolicyLockerTest() override = default; void SetUpInProcessBrowserTestFixture() override { fake_session_manager_client_ = new FakeSessionManagerClient; @@ -239,20 +223,7 @@ ShutdownPolicyBaseTest::SetUpOnMainThread(); // Bring up the locker screen. - std::unique_ptr<chromeos::ScreenLockerTester> tester = - chromeos::ScreenLockerTester::Create(); - tester->Lock(); - ScreenLocker* screen_locker = ScreenLocker::default_screen_locker(); - WebUIScreenLocker* web_ui_screen_locker = - screen_locker->web_ui_for_testing(); - ASSERT_TRUE(web_ui_screen_locker); - content::WebUI* web_ui = web_ui_screen_locker->GetWebUI(); - ASSERT_TRUE(web_ui); - contents_ = web_ui->GetWebContents(); - ASSERT_TRUE(contents_); - - // Wait for the login UI to be ready. - WaitUntilOobeUIIsReady(web_ui_screen_locker->GetOobeUI()); + chromeos::ScreenLockerTester().Lock(); } void TearDownOnMainThread() override { @@ -262,32 +233,38 @@ private: std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; - FakeSessionManagerClient* fake_session_manager_client_; + FakeSessionManagerClient* fake_session_manager_client_ = nullptr; DISALLOW_COPY_AND_ASSIGN(ShutdownPolicyLockerTest); }; IN_PROC_BROWSER_TEST_F(ShutdownPolicyLockerTest, TestBasic) { - PrepareAndRunScript("restart-header-bar-item", true); - PrepareAndRunScript("shutdown-header-bar-item", false); + ScreenLockerTester tester; + EXPECT_FALSE(tester.IsRestartButtonShown()); + EXPECT_TRUE(tester.IsShutdownButtonShown()); } IN_PROC_BROWSER_TEST_F(ShutdownPolicyLockerTest, PolicyChange) { + ScreenLockerTester tester; + int ui_update_count = tester.GetUiUpdateCount(); UpdateRebootOnShutdownPolicy(true); RefreshDevicePolicy(); - PrepareAndRunScript("restart-header-bar-item", false); - PrepareAndRunScript("shutdown-header-bar-item", true); + tester.WaitForUiUpdate(ui_update_count); + EXPECT_TRUE(tester.IsRestartButtonShown()); + EXPECT_FALSE(tester.IsShutdownButtonShown()); + ui_update_count = tester.GetUiUpdateCount(); UpdateRebootOnShutdownPolicy(false); RefreshDevicePolicy(); - PrepareAndRunScript("restart-header-bar-item", true); - PrepareAndRunScript("shutdown-header-bar-item", false); + tester.WaitForUiUpdate(ui_update_count); + EXPECT_FALSE(tester.IsRestartButtonShown()); + EXPECT_TRUE(tester.IsShutdownButtonShown()); } class ShutdownPolicyLoginTest : public ShutdownPolicyBaseTest { protected: - ShutdownPolicyLoginTest() {} - ~ShutdownPolicyLoginTest() override {} + ShutdownPolicyLoginTest() = default; + ~ShutdownPolicyLoginTest() override = default; // ShutdownPolicyBaseTest: void SetUpCommandLine(base::CommandLine* command_line) override { @@ -325,7 +302,16 @@ } } + // Checks whether the element identified by |element_id| is hidden and only + // returns if the expectation is fulfilled. + void PrepareAndRunScript(const std::string& element_id, bool expectation) { + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + contents_, PrepareScript(element_id, expectation), &result_)); + } + private: + content::WebContents* contents_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(ShutdownPolicyLoginTest); };
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc index 18459e2..e9efd7d 100644 --- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc +++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
@@ -317,8 +317,7 @@ }; IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateAPIUserTest, KeyEventOnLockScreen) { - std::unique_ptr<chromeos::ScreenLockerTester> tester = - chromeos::ScreenLockerTester::Create(); + chromeos::ScreenLockerTester tester; // Make sure the signin profile and active profile are different. Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile(); @@ -344,15 +343,15 @@ EXPECT_EQ(1, user_delegate->GetEventCount()); // Lock screen, and make sure that the key event goes to the signin profile. - tester->Lock(); + tester.Lock(); signin_api.OnBrailleKeyEvent(key_event); user_api.OnBrailleKeyEvent(key_event); EXPECT_EQ(0, signin_delegate->GetEventCount()); EXPECT_EQ(2, user_delegate->GetEventCount()); // Unlock screen, making sure key events go to the user profile again. - tester->SetUnlockPassword(AccountId::FromUserEmail(kTestUserEmail), "pass"); - tester->UnlockWithPassword(AccountId::FromUserEmail(kTestUserEmail), "pass"); + tester.SetUnlockPassword(AccountId::FromUserEmail(kTestUserEmail), "pass"); + tester.UnlockWithPassword(AccountId::FromUserEmail(kTestUserEmail), "pass"); signin_api.OnBrailleKeyEvent(key_event); user_api.OnBrailleKeyEvent(key_event); EXPECT_EQ(0, signin_delegate->GetEventCount());
diff --git a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc index 475cef5..accd732 100644 --- a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc +++ b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
@@ -128,17 +128,21 @@ #endif // defined(OS_ANDROID) #if defined(OS_MACOSX) - // Fail if access is denied in system permission. Note that if permission is - // not yet determined, we don't fail. If all other permissions are OK, we'll - // allow access. The reason for doing this is that if the permission is not - // yet determined, the user will get an async alert dialog and we don't want - // to wait on that before resolving getUserMedia. getUserMedia will succeed, - // but audio will be silent until user allows permission in the dialog. If the - // user denies permission audio will continue being silent but they will - // likely understand why since they denied it. + // Fail if access is denied in system permissions. Note that if permissions + // have not yet been determined, we don't fail. If all other permissions are + // OK, we'll allow access. The reason for doing this is that if the permission + // is not yet determined, the user will get an async system dialog and we + // don't wait on that response before resolving getUserMedia. getUserMedia + // will succeed, but audio/video will be silent/black until user allows + // permission in the dialog. If the user denies permission audio/video will + // continue to be silent/black but they will likely understand why since they + // denied access. We trigger the system dialog explicitly in + // OnAccessRequestResponse(). // TODO(https://crbug.com/885184): Handle the not determined case better. - if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE && - SystemAudioCapturePermissionIsDisallowed()) { + if ((request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE && + SystemAudioCapturePermissionIsDisallowed()) || + (request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE && + SystemVideoCapturePermissionIsDisallowed())) { std::move(callback).Run(blink::MediaStreamDevices(), blink::MEDIA_DEVICE_SYSTEM_PERMISSION_DENIED, nullptr); @@ -231,13 +235,15 @@ return; #if defined(OS_MACOSX) - // If the request was approved, trigger system user dialog if needed. We need - // to do this explicitly so that the system gives the correct information - // about the permission state in future requests - // (see PermissionBubbleMediaAccessHandler::HandleRequest). - if (queue.front().request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE && - result == blink::MEDIA_DEVICE_OK) { - EnsureSystemAudioCapturePermission(); + // If the request was approved, trigger system user dialogs if needed. We must + // do this explicitly so that the system gives the correct information about + // the permission states in future requests, see HandleRequest(). + if (result == blink::MEDIA_DEVICE_OK) { + const content::MediaStreamRequest& request = queue.front().request; + if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE) + EnsureSystemAudioCapturePermissionIsOrGetsDetermined(); + if (request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE) + EnsureSystemVideoCapturePermissionIsOrGetsDetermined(); } #endif // defined(OS_MACOSX)
diff --git a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.h b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.h index 4e460fc..ae201c47 100644 --- a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.h +++ b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.h
@@ -10,18 +10,20 @@ // On 10.13 and below: returns false, since there are no system media capture // permissions. bool SystemAudioCapturePermissionIsDisallowed(); +bool SystemVideoCapturePermissionIsDisallowed(); // On 10.14 and above: if system permission is not determined, requests // permission. Otherwise, does nothing. When requesting permission, the OS will // show a user dialog and respond asynchronously. This function does not wait // for the response and nothing is done at the response. The reason // for explicitly requesting permission is that if only implicitly requesting -// permission (when media::AUAudioInputStream::Start() calls +// permission (e.g. for audio when media::AUAudioInputStream::Start() calls // AudioOutputUnitStart()), the OS returns not determined when we ask what the // permission state is, even though it's actually set to something else, until // browser restart. // On 10.13 and below: does nothing, since there are no system media capture // permissions. -void EnsureSystemAudioCapturePermission(); +void EnsureSystemAudioCapturePermissionIsOrGetsDetermined(); +void EnsureSystemVideoCapturePermissionIsOrGetsDetermined(); #endif // CHROME_BROWSER_MEDIA_WEBRTC_SYSTEM_MEDIA_CAPTURE_PERMISSIONS_MAC_H_
diff --git a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm index a6942b9..a152da6 100644 --- a/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm +++ b/chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm
@@ -4,7 +4,8 @@ // // Authorization functions and types are available on 10.14+. // To avoid availability compile errors, use performSelector invocation of -// functions and NSInteger instead of AVAuthorizationStatus. +// functions, NSInteger instead of AVAuthorizationStatus, and NSString* instead +// of AVMediaType. // The AVAuthorizationStatus enum is defined as follows (10.14 SDK): // AVAuthorizationStatusNotDetermined = 0, // AVAuthorizationStatusRestricted = 1, @@ -21,14 +22,14 @@ namespace { -NSInteger AudioAuthorizationStatus() { +NSInteger MediaAuthorizationStatus(NSString* media_type) { if (@available(macOS 10.14, *)) { AVCaptureDevice* target = [AVCaptureDevice class]; SEL selector = @selector(authorizationStatusForMediaType:); NSInteger auth_status = 0; if ([target respondsToSelector:selector]) { - auth_status = (NSInteger)[target performSelector:selector - withObject:AVMediaTypeAudio]; + auth_status = + (NSInteger)[target performSelector:selector withObject:media_type]; } else { DLOG(WARNING) << "authorizationStatusForMediaType could not be executed"; } @@ -39,24 +40,23 @@ return 0; } -} // namespace - -bool SystemAudioCapturePermissionIsDisallowed() { +bool SystemMediaCapturePermissionIsDisallowed(NSString* media_type) { if (@available(macOS 10.14, *)) { - NSInteger auth_status = AudioAuthorizationStatus(); + NSInteger auth_status = MediaAuthorizationStatus(media_type); return auth_status == 1 || auth_status == 2; } return false; } -void EnsureSystemAudioCapturePermission() { +void EnsureSystemMediaCapturePermissionIsOrGetsDetermined( + NSString* media_type) { if (@available(macOS 10.14, *)) { - if (AudioAuthorizationStatus() == 0) { + if (MediaAuthorizationStatus(media_type) == 0) { AVCaptureDevice* target = [AVCaptureDevice class]; SEL selector = @selector(requestAccessForMediaType:completionHandler:); if ([target respondsToSelector:selector]) { [target performSelector:selector - withObject:AVMediaTypeAudio + withObject:media_type withObject:^(BOOL granted){ }]; } else { @@ -65,3 +65,21 @@ } } } + +} // namespace + +bool SystemAudioCapturePermissionIsDisallowed() { + return SystemMediaCapturePermissionIsDisallowed(AVMediaTypeAudio); +} + +bool SystemVideoCapturePermissionIsDisallowed() { + return SystemMediaCapturePermissionIsDisallowed(AVMediaTypeVideo); +} + +void EnsureSystemAudioCapturePermissionIsOrGetsDetermined() { + EnsureSystemMediaCapturePermissionIsOrGetsDetermined(AVMediaTypeAudio); +} + +void EnsureSystemVideoCapturePermissionIsOrGetsDetermined() { + EnsureSystemMediaCapturePermissionIsOrGetsDetermined(AVMediaTypeVideo); +}
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_lock.html b/chrome/browser/resources/chromeos/login/custom_elements_lock.html deleted file mode 100644 index b87074a..0000000 --- a/chrome/browser/resources/chromeos/login/custom_elements_lock.html +++ /dev/null
@@ -1,3 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<script src="chrome://oobe/custom_elements.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_lock.js b/chrome/browser/resources/chromeos/login/custom_elements_lock.js deleted file mode 100644 index 6853db7..0000000 --- a/chrome/browser/resources/chromeos/login/custom_elements_lock.js +++ /dev/null
@@ -1,3 +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.
diff --git a/chrome/browser/resources/chromeos/login/lock.html b/chrome/browser/resources/chromeos/login/lock.html deleted file mode 100644 index 87b5f986..0000000 --- a/chrome/browser/resources/chromeos/login/lock.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!doctype html> -<html i18n-values="dir:textdirection; - build:buildType; - highlight:highlightStrength; - lang:language"> -<head> -<meta charset="utf-8"> -<meta name="google" value="notranslate"> -<title i18n-content="title"></title> - -<include src="login_shared.html"> - -<!-- custom_elements.html (polymer) gets lazily-loaded in lock.js --> - -<script src="chrome://oobe/lock.js"></script> - -</head> -<body i18n-values=".style.fontFamily:fontfamily;" class="chromeos"> - <include src="screen_container.html"> - <script src="chrome://resources/js/i18n_template.js"></script> -</body> -</html>
diff --git a/chrome/browser/resources/chromeos/login/lock.js b/chrome/browser/resources/chromeos/login/lock.js deleted file mode 100644 index afb37f2..0000000 --- a/chrome/browser/resources/chromeos/login/lock.js +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright (c) 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. - -/** - * @fileoverview Login UI based on a stripped down OOBE controller. - */ - -// <include src="login_shared.js"> - -/** - * Ensures that the pin keyboard is loaded. - * @param {function()} onLoaded Callback run when the pin keyboard is loaded. - */ -function ensurePinKeyboardLoaded(onLoaded) { - 'use strict'; - - // The element we want to see if loaded. - var getPinKeyboard = function() { - return $('pod-row').querySelectorAll('pin-keyboard')[0]; - }; - - // Do not reload assets if they are already loaded. Run |onLoaded| once assets - // are done loading, though. - if (cr.ui.login.ResourceLoader.hasDeferredAssets('custom-elements')) { - cr.ui.login.ResourceLoader.waitUntilLayoutComplete( - getPinKeyboard, onLoaded); - return; - } - - // Register loader for custom elements. - cr.ui.login.ResourceLoader.registerAssets({ - id: 'custom-elements', - html: [{url: 'chrome://oobe/custom_elements.html'}] - }); - - // We only load the PIN element when it is actually shown so that lock screen - // load times remain low when the user is not using a PIN. - // - // Loading the PIN element blocks the DOM, which will interrupt any running - // animations. We load the PIN after an idle notification to allow the pod - // fly-in animation to complete without interruption. - cr.ui.login.ResourceLoader.loadAssetsOnIdle('custom-elements', function() { - cr.ui.login.ResourceLoader.waitUntilLayoutComplete( - getPinKeyboard, onLoaded); - }); -} - -cr.define('cr.ui.Oobe', function() { - return { - /** - * Initializes the OOBE flow. This will cause all C++ handlers to - * be invoked to do final setup. - */ - initialize: function() { - cr.ui.login.DisplayManager.initialize(); - login.AccountPickerScreen.register(); - - cr.ui.Bubble.decorate($('bubble')); - login.HeaderBar.decorate($('login-header-bar')); - - chrome.send('screenStateInitialize'); - }, - - /** - * Notification from the host that the PIN keyboard will be used in the - * lock session so it should also get preloaded. - */ - preloadPinKeyboard: function() { - ensurePinKeyboardLoaded(function() {}); - }, - - // Dummy Oobe functions not present with stripped login UI. - initializeA11yMenu: function(e) {}, - handleAccessibilityLinkClick: function(e) {}, - handleSpokenFeedbackClick: function(e) {}, - handleHighContrastClick: function(e) {}, - handleScreenMagnifierClick: function(e) {}, - setUsageStats: function(checked) {}, - setTpmPassword: function(password) {}, - refreshA11yInfo: function(data) {}, - reloadEulaContent: function(data) {}, - - /** - * Reloads content of the page. - * @param {!Object} data New dictionary with i18n values. - */ - reloadContent: function(data) { - loadTimeData.overrideValues(data); - i18nTemplate.process(document, loadTimeData); - Oobe.getInstance().updateLocalizedContent_(); - }, - - /** - * Updates "device in tablet mode" state when tablet mode is changed. - * @param {Boolean} isInTabletMode True when in tablet mode. - */ - setTabletModeState: function(isInTabletMode) { - Oobe.getInstance().setTabletModeState_(isInTabletMode); - }, - - /** - * Updates OOBE configuration when it is loaded. - * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration. - */ - updateOobeConfiguration: function(configuration) { - // Do nothing in lock mode. - }, - }; -});
diff --git a/chrome/browser/resources/chromeos/login/lock_screens.html b/chrome/browser/resources/chromeos/login/lock_screens.html deleted file mode 100644 index 7f8ed7a..0000000 --- a/chrome/browser/resources/chromeos/login/lock_screens.html +++ /dev/null
@@ -1 +0,0 @@ -<include src="../../../../../ui/login/account_picker/screen_account_picker.html"> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/login/login_shared.js b/chrome/browser/resources/chromeos/login/login_shared.js index ed46ec1..b60ae27 100644 --- a/chrome/browser/resources/chromeos/login/login_shared.js +++ b/chrome/browser/resources/chromeos/login/login_shared.js
@@ -217,15 +217,6 @@ }; /** - * Displays animations that have to happen once login UI is fully displayed. - */ - Oobe.animateOnceFullyDisplayed = function() { - login.HeaderBar.animateIn(true, function() { - chrome.send('headerBarVisible'); - }); - }; - - /** * Sets text content for a div with |labelId|. * @param {string} labelId Id of the label div. * @param {string} labelText Text for the label. @@ -260,13 +251,6 @@ }; /** - * Enforces focus on user pod of locked user. - */ - Oobe.forceLockedUserPodFocus = function() { - login.AccountPickerScreen.forceLockedUserPodFocus(); - }; - - /** * Clears password field in user-pod. */ Oobe.clearUserPodPassword = function() {
diff --git a/chrome/browser/resources/chromeos/login/md_lock.html b/chrome/browser/resources/chromeos/login/md_lock.html deleted file mode 100644 index eee6efef..0000000 --- a/chrome/browser/resources/chromeos/login/md_lock.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!doctype html> -<html i18n-values="dir:textdirection; - build:buildType; - highlight:highlightStrength; - lang:language"> -<head> -<meta charset="utf-8"> -<meta name="google" value="notranslate"> -<title i18n-content="title"></title> - -<include src="md_login_shared.html"> - -<!-- custom_elements.html (polymer) gets lazily-loaded in lock.js --> - -<script src="chrome://oobe/lock.js"></script> - -</head> -<body i18n-values=".style.fontFamily:fontfamily;" class="chromeos"> - <include src="md_screen_container.html"> - <script src="chrome://resources/js/i18n_template.js"></script> -</body> -</html>
diff --git a/chrome/browser/resources/chromeos/login/md_lock.js b/chrome/browser/resources/chromeos/login/md_lock.js deleted file mode 100644 index af120de..0000000 --- a/chrome/browser/resources/chromeos/login/md_lock.js +++ /dev/null
@@ -1,115 +0,0 @@ -// Copyright (c) 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. - -/** - * @fileoverview Login UI based on a stripped down OOBE controller. - */ - -// <include src="md_login_shared.js"> - -/** - * Ensures that the pin keyboard is loaded. - * @param {function()} onLoaded Callback run when the pin keyboard is loaded. - */ -function ensurePinKeyboardLoaded(onLoaded) { - 'use strict'; - - // The element we want to see if loaded. - var getPinKeyboard = function() { - return $('pod-row').querySelectorAll('pin-keyboard')[0]; - }; - - // Do not reload assets if they are already loaded. Run |onLoaded| once assets - // are done loading, though. - if (cr.ui.login.ResourceLoader.hasDeferredAssets('custom-elements')) { - cr.ui.login.ResourceLoader.waitUntilLayoutComplete( - getPinKeyboard, onLoaded); - return; - } - - // Register loader for custom elements. - cr.ui.login.ResourceLoader.registerAssets({ - id: 'custom-elements', - html: [{url: 'chrome://oobe/custom_elements.html'}] - }); - - // We only load the PIN element when it is actually shown so that lock screen - // load times remain low when the user is not using a PIN. - // - // Loading the PIN element blocks the DOM, which will interrupt any running - // animations. We load the PIN after an idle notification to allow the pod - // fly-in animation to complete without interruption. - cr.ui.login.ResourceLoader.loadAssetsOnIdle('custom-elements', function() { - cr.ui.login.ResourceLoader.waitUntilLayoutComplete( - getPinKeyboard, onLoaded); - }); -} - -cr.define('cr.ui.Oobe', function() { - return { - /** - * Initializes the OOBE flow. This will cause all C++ handlers to - * be invoked to do final setup. - */ - initialize: function() { - cr.ui.login.DisplayManager.initialize(); - login.AccountPickerScreen.register(); - - cr.ui.Bubble.decorate($('bubble-persistent')); - $('bubble-persistent').persistent = true; - $('bubble-persistent').hideOnKeyPress = false; - - cr.ui.Bubble.decorate($('bubble')); - login.HeaderBar.decorate($('login-header-bar')); - login.TopHeaderBar.decorate($('top-header-bar')); - - chrome.send('screenStateInitialize'); - }, - - /** - * Notification from the host that the PIN keyboard will be used in the - * lock session so it should also get preloaded. - */ - preloadPinKeyboard: function() { - ensurePinKeyboardLoaded(function() {}); - }, - - // Dummy Oobe functions not present with stripped login UI. - initializeA11yMenu: function(e) {}, - handleAccessibilityLinkClick: function(e) {}, - handleSpokenFeedbackClick: function(e) {}, - handleHighContrastClick: function(e) {}, - handleScreenMagnifierClick: function(e) {}, - setUsageStats: function(checked) {}, - setTpmPassword: function(password) {}, - refreshA11yInfo: function(data) {}, - reloadEulaContent: function(data) {}, - - /** - * Reloads content of the page. - * @param {!Object} data New dictionary with i18n values. - */ - reloadContent: function(data) { - loadTimeData.overrideValues(data); - i18nTemplate.process(document, loadTimeData); - Oobe.getInstance().updateLocalizedContent_(); - }, - - /** - * Updates "device in tablet mode" state when tablet mode is changed. - * @param {Boolean} isInTabletMode True when in tablet mode. - */ - setTabletModeState: function(isInTabletMode) { - Oobe.getInstance().setTabletModeState_(isInTabletMode); - }, - - /** - * Updates OOBE configuration when it is loaded. - * @param {!OobeTypes.OobeConfiguration} configuration OOBE configuration. - */ - updateOobeConfiguration: function(configuration) { - // Do nothing in lock mode. - }, - }; -});
diff --git a/chrome/browser/resources/chromeos/login/md_lock_screens.html b/chrome/browser/resources/chromeos/login/md_lock_screens.html deleted file mode 100644 index c25e88e..0000000 --- a/chrome/browser/resources/chromeos/login/md_lock_screens.html +++ /dev/null
@@ -1 +0,0 @@ -<include src="../../../../../ui/login/account_picker/md_screen_account_picker.html">
diff --git a/chrome/browser/resources/chromeos/login/md_login_shared.js b/chrome/browser/resources/chromeos/login/md_login_shared.js index 7e721b79..f8f1f0b1 100644 --- a/chrome/browser/resources/chromeos/login/md_login_shared.js +++ b/chrome/browser/resources/chromeos/login/md_login_shared.js
@@ -219,15 +219,6 @@ }; /** - * Displays animations that have to happen once login UI is fully displayed. - */ - Oobe.animateOnceFullyDisplayed = function() { - login.HeaderBar.animateIn(true, function() { - chrome.send('headerBarVisible'); - }); - }; - - /** * Sets text content for a div with |labelId|. * @param {string} labelId Id of the label div. * @param {string} labelText Text for the label. @@ -262,13 +253,6 @@ }; /** - * Enforces focus on user pod of locked user. - */ - Oobe.forceLockedUserPodFocus = function() { - login.AccountPickerScreen.forceLockedUserPodFocus(); - }; - - /** * Clears password field in user-pod. */ Oobe.clearUserPodPassword = function() {
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js b/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js index 707e610b..d4468ab 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js
@@ -12,7 +12,7 @@ /** @polymerBehavior */ const MultiDeviceFeatureBehaviorImpl = { properties: { - /** @type {MultiDevicePageContentData} */ + /** @type {!MultiDevicePageContentData} */ pageContentData: Object, /** @@ -31,7 +31,8 @@ * @return {boolean} */ isSuiteOn: function() { - return this.pageContentData.betterTogetherState === + return !!this.pageContentData && + this.pageContentData.betterTogetherState === settings.MultiDeviceFeatureState.ENABLED_BY_USER; }, @@ -41,7 +42,8 @@ * @return {boolean} */ isSuiteAllowedByPolicy: function() { - return this.pageContentData.betterTogetherState !== + return !!this.pageContentData && + this.pageContentData.betterTogetherState !== settings.MultiDeviceFeatureState.PROHIBITED_BY_POLICY; }, @@ -151,6 +153,10 @@ * @return {?settings.MultiDeviceFeatureState} */ getFeatureState: function(feature) { + if (!this.pageContentData) { + return null; + } + switch (feature) { case settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE: return this.pageContentData.betterTogetherState;
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html b/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html index 0db389f7..18864c6 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html
@@ -56,7 +56,8 @@ </div> </iron-collapse> <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> - <settings-password-prompt-dialog></settings-password-prompt-dialog> + <settings-password-prompt-dialog on-close="onDialogClose_"> + </settings-password-prompt-dialog> </template> </template> <script src="multidevice_smartlock_subpage.js"></script>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js b/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js index 3cc273c..93c44e5 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js
@@ -80,7 +80,6 @@ listeners: { 'auth-token-changed': 'onAuthTokenChanged_', - 'close': 'onDialogClose_', }, /** @private {?settings.MultiDeviceBrowserProxy} */
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index a0264f5..797df9d5 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -2,9 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/jumbo.gni") import("//extensions/buildflags/buildflags.gni") -static_library("safe_browsing") { +jumbo_static_library("safe_browsing") { sources = [ "safe_browsing_controller_client.cc", "safe_browsing_controller_client.h",
diff --git a/chrome/browser/safe_browsing/advanced_protection_status_manager_factory.cc b/chrome/browser/safe_browsing/advanced_protection_status_manager_factory.cc index e12b955..927b0ea 100644 --- a/chrome/browser/safe_browsing/advanced_protection_status_manager_factory.cc +++ b/chrome/browser/safe_browsing/advanced_protection_status_manager_factory.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" -#include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" @@ -30,7 +29,6 @@ : BrowserContextKeyedServiceFactory( "AdvancedProtectionStatusManager", BrowserContextDependencyManager::GetInstance()) { - DependsOn(AccountTrackerServiceFactory::GetInstance()); DependsOn(IdentityManagerFactory::GetInstance()); }
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index c348d5d..b8763a3 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -24,8 +24,7 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/chrome_device_id_helper.h" #include "chrome/browser/signin/force_signin_verifier.h" -#include "chrome/browser/signin/profile_oauth2_token_service_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_list.h" #include "chrome/common/buildflags.h" @@ -36,16 +35,17 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/cookie_settings_util.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_buildflags.h" #include "components/signin/core/browser/signin_header_helper.h" -#include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_urls.h" +#include "services/identity/public/cpp/access_token_info.h" +#include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/scope_set.h" #include "url/gurl.h" #if BUILDFLAG(ENABLE_SUPERVISED_USERS) @@ -95,9 +95,7 @@ } // namespace ChromeSigninClient::ChromeSigninClient(Profile* profile) - : OAuth2TokenService::Consumer("chrome_signin_client"), - profile_(profile), - weak_ptr_factory_(this) { + : profile_(profile), weak_ptr_factory_(this) { #if !defined(OS_CHROMEOS) content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver(this); #endif @@ -234,37 +232,31 @@ entry->SetPasswordChangeDetectionToken(handle); } } - oauth_request_.reset(); + access_token_fetcher_.reset(); } void ChromeSigninClient::OnOAuthError() { // Ignore the failure. It's not essential and we'll try again next time. - oauth_request_.reset(); + access_token_fetcher_.reset(); } void ChromeSigninClient::OnNetworkError(int response_code) { // Ignore the failure. It's not essential and we'll try again next time. - oauth_request_.reset(); + access_token_fetcher_.reset(); } -void ChromeSigninClient::OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const OAuth2AccessTokenConsumer::TokenResponse& token_response) { +void ChromeSigninClient::OnAccessTokenAvailable( + GoogleServiceAuthError error, + identity::AccessTokenInfo access_token_info) { + access_token_fetcher_.reset(); + // Exchange the access token for a handle that can be used for later // verification that the token is still valid (i.e. the password has not // been changed). - if (!oauth_client_) { - oauth_client_.reset(new gaia::GaiaOAuthClient(GetURLLoaderFactory())); - } - oauth_client_->GetTokenInfo(token_response.access_token, 3 /* retries */, - this); -} - -void ChromeSigninClient::OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) { - // Ignore the failure. It's not essential and we'll try again next time. - oauth_request_.reset(); + if (!oauth_client_) { + oauth_client_.reset(new gaia::GaiaOAuthClient(GetURLLoaderFactory())); + } + oauth_client_->GetTokenInfo(access_token_info.token, 3 /* retries */, this); } #if !defined(OS_CHROMEOS) @@ -329,15 +321,17 @@ ProfileAttributesEntry* entry; // If we don't have a token for detecting a password change, create one. if (storage.GetProfileAttributesWithPath(profile_->GetPath(), &entry) && - entry->GetPasswordChangeDetectionToken().empty() && !oauth_request_) { - std::string account_id = SigninManagerFactory::GetForProfile(profile_) - ->GetAuthenticatedAccountId(); - if (!account_id.empty()) { - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); - OAuth2TokenService::ScopeSet scopes; - scopes.insert(GaiaConstants::kGoogleUserInfoEmail); - oauth_request_ = token_service->StartRequest(account_id, scopes, this); + entry->GetPasswordChangeDetectionToken().empty() && + !access_token_fetcher_) { + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); + if (identity_manager->HasPrimaryAccount()) { + const identity::ScopeSet scopes{GaiaConstants::kGoogleUserInfoEmail}; + access_token_fetcher_ = + std::make_unique<identity::PrimaryAccountAccessTokenFetcher>( + "chrome_signin_client", identity_manager, scopes, + base::BindOnce(&ChromeSigninClient::OnAccessTokenAvailable, + base::Unretained(this)), + identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate); } } }
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h index a397f89..4080fb0a 100644 --- a/chrome/browser/signin/chrome_signin_client.h +++ b/chrome/browser/signin/chrome_signin_client.h
@@ -6,6 +6,8 @@ #define CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_CLIENT_H_ #include <list> +#include <memory> +#include <string> #include "base/compiler_specific.h" #include "base/macros.h" @@ -14,7 +16,7 @@ #include "build/build_config.h" #include "components/signin/core/browser/signin_client.h" #include "google_apis/gaia/gaia_oauth_client.h" -#include "google_apis/gaia/oauth2_token_service.h" +#include "services/identity/public/cpp/primary_account_access_token_fetcher.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/mojom/network_change_manager.mojom.h" @@ -32,8 +34,7 @@ #if !defined(OS_CHROMEOS) public network::NetworkConnectionTracker::NetworkConnectionObserver, #endif - public gaia::GaiaOAuthClient::Delegate, - public OAuth2TokenService::Consumer { + public gaia::GaiaOAuthClient::Delegate { public: explicit ChromeSigninClient(Profile* profile); ~ChromeSigninClient() override; @@ -75,13 +76,6 @@ void OnOAuthError() override; void OnNetworkError(int response_code) override; - // OAuth2TokenService::Consumer implementation - void OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const OAuth2AccessTokenConsumer::TokenResponse& token_response) override; - void OnGetTokenFailure(const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) override; - #if !defined(OS_CHROMEOS) // network::NetworkConnectionTracker::NetworkConnectionObserver // implementation. @@ -108,6 +102,10 @@ const base::FilePath& profile_path); void OnCloseBrowsersAborted(const base::FilePath& profile_path); + // identity::PrimaryAccountAccessTokenFetcher callback + void OnAccessTokenAvailable(GoogleServiceAuthError error, + identity::AccessTokenInfo access_token_info); + Profile* profile_; // Stored callback from PreSignOut(); @@ -123,7 +121,8 @@ #endif std::unique_ptr<gaia::GaiaOAuthClient> oauth_client_; - std::unique_ptr<OAuth2TokenService::Request> oauth_request_; + std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> + access_token_fetcher_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_for_testing_;
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index 5dd0c16..50b899a 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -123,7 +123,30 @@ return identity_manager; } +void IdentityManagerFactory::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void IdentityManagerFactory::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + KeyedService* IdentityManagerFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new IdentityManagerWrapper(Profile::FromBrowserContext(context)); + auto identity_manager = std::make_unique<IdentityManagerWrapper>( + Profile::FromBrowserContext(context)); + for (Observer& observer : observer_list_) + observer.IdentityManagerCreated(identity_manager.get()); + return identity_manager.release(); +} + +void IdentityManagerFactory::BrowserContextShutdown( + content::BrowserContext* context) { + auto* identity_manager = static_cast<IdentityManagerWrapper*>( + GetServiceForBrowserContext(context, false)); + if (identity_manager) { + for (Observer& observer : observer_list_) + observer.IdentityManagerShutdown(identity_manager); + } + BrowserContextKeyedServiceFactory::BrowserContextShutdown(context); }
diff --git a/chrome/browser/signin/identity_manager_factory.h b/chrome/browser/signin/identity_manager_factory.h index c8417c97..f674000 100644 --- a/chrome/browser/signin/identity_manager_factory.h +++ b/chrome/browser/signin/identity_manager_factory.h
@@ -9,6 +9,7 @@ #include <string> #include "base/memory/singleton.h" +#include "base/observer_list.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" namespace identity { @@ -21,6 +22,21 @@ // Profiles. class IdentityManagerFactory : public BrowserContextKeyedServiceFactory { public: + class Observer { + public: + // Called when a IdentityManager instance is created. + virtual void IdentityManagerCreated( + identity::IdentityManager* identity_manager) {} + + // Called when a IdentityManager instance is being shut down. Observers + // of |identity_manager| should remove themselves at this point. + virtual void IdentityManagerShutdown( + identity::IdentityManager* identity_manager) {} + + protected: + virtual ~Observer() {} + }; + static identity::IdentityManager* GetForProfile(Profile* profile); static identity::IdentityManager* GetForProfileIfExists( const Profile* profile); @@ -37,6 +53,11 @@ const std::string& refresh_token, content::BrowserContext* context); + // Methods to register or remove observers of IdentityManager + // creation/shutdown. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + private: friend struct base::DefaultSingletonTraits<IdentityManagerFactory>; @@ -46,6 +67,10 @@ // BrowserContextKeyedServiceFactory: KeyedService* BuildServiceInstanceFor( content::BrowserContext* profile) const override; + void BrowserContextShutdown(content::BrowserContext* profile) override; + + // List of observers. Checks that list is empty on destruction. + mutable base::ObserverList<Observer, true>::Unchecked observer_list_; DISALLOW_COPY_AND_ASSIGN(IdentityManagerFactory); };
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index b538817..f554b00c 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -21,7 +21,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.h" #include "chrome/browser/supervised_user/permission_request_creator.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" @@ -42,12 +42,13 @@ #include "components/policy/core/browser/url_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/sync/driver/sync_user_settings.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "extensions/buildflags/buildflags.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/identity/public/cpp/accounts_mutator.h" +#include "services/identity/public/cpp/identity_manager.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/base/l10n/l10n_util.h" @@ -324,11 +325,9 @@ #if !defined(OS_ANDROID) void SupervisedUserService::InitSync(const std::string& refresh_token) { - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); - token_service->UpdateCredentials( - supervised_users::kSupervisedUserPseudoEmail, refresh_token, - signin_metrics::SourceForRefreshTokenOperation::kSupervisedUser_InitSync); + IdentityManagerFactory::GetForProfile(profile_) + ->GetAccountsMutator() + ->LegacySetRefreshTokenForSupervisedUser(refresh_token); } #endif // !defined(OS_ANDROID) @@ -378,9 +377,7 @@ if (!delegate_ || !delegate_->SetActive(active_)) { if (active_) { #if !defined(OS_ANDROID) - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); - token_service->LoadCredentials( + IdentityManagerFactory::GetForProfile(profile_)->LegacyLoadCredentials( supervised_users::kSupervisedUserPseudoEmail); #else NOTREACHED();
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc index c8e0c624..d1cc83c 100644 --- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -3,9 +3,11 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/sync/test/integration/encryption_helper.h" #include "chrome/browser/sync/test/integration/feature_toggler.h" #include "chrome/browser/sync/test/integration/passwords_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 "components/browser_sync/profile_sync_service.h" @@ -149,6 +151,51 @@ EXPECT_NE(new_encryption_key_name, prior_encryption_key_name); } +IN_PROC_BROWSER_TEST_P(SingleClientPasswordsSyncTest, + PRE_PersistProgressMarkerOnRestart) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + PasswordForm form = CreateTestPasswordForm(0); + AddLogin(GetPasswordStore(0), form); + ASSERT_EQ(1, GetPasswordCount(0)); + // Setup sync, wait for its completion, and make sure changes were synced. + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); + // Upon a local creation, the received update will be seen as reflection and + // get counted as incremental update. + EXPECT_EQ( + 1, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.PASSWORD", + /*REMOTE_NON_INITIAL_UPDATE=*/4)); +} + +IN_PROC_BROWSER_TEST_P(SingleClientPasswordsSyncTest, + PersistProgressMarkerOnRestart) { + base::HistogramTester histogram_tester; + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + ASSERT_EQ(1, GetPasswordCount(0)); +#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()); + + // If that metadata hasn't been properly persisted, the password stored on the + // server will be received at the client as an initial update or an + // incremental once. + EXPECT_EQ( + 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.PASSWORD", + /*REMOTE_INITIAL_UPDATE=*/5)); + EXPECT_EQ( + 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.PASSWORD", + /*REMOTE_NON_INITIAL_UPDATE=*/4)); +} + INSTANTIATE_TEST_SUITE_P(USS, SingleClientPasswordsSyncTest, ::testing::Values(false, true));
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index e2d9585..c5660b0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1640,10 +1640,6 @@ "webui/chromeos/login/recommend_apps_screen_handler.h", "webui/chromeos/login/reset_screen_handler.cc", "webui/chromeos/login/reset_screen_handler.h", - "webui/chromeos/login/screenlock_icon_provider.cc", - "webui/chromeos/login/screenlock_icon_provider.h", - "webui/chromeos/login/screenlock_icon_source.cc", - "webui/chromeos/login/screenlock_icon_source.h", "webui/chromeos/login/signin_screen_handler.cc", "webui/chromeos/login/signin_screen_handler.h", "webui/chromeos/login/supervision_transition_screen_handler.cc",
diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc index 63f694b..9b9b1ed98 100644 --- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
@@ -255,9 +255,16 @@ return; } - ash::ShelfAction action = - ChromeLauncherController::instance()->ActivateWindowOrMinimizeIfActive( - last_browser->window(), items.size() == 1); + ash::ShelfAction action; + if (items.size() == 1) { + action = + ChromeLauncherController::instance()->ActivateWindowOrMinimizeIfActive( + last_browser->window(), true); + } else { + // Multiple targets, a menu will be shown. No need to activate or minimize + // the recently active browser. + action = ash::SHELF_ACTION_NONE; + } std::move(callback).Run(action, std::move(items)); }
diff --git a/chrome/browser/ui/ash/test_login_screen.cc b/chrome/browser/ui/ash/test_login_screen.cc index fbcad54..2c86b25 100644 --- a/chrome/browser/ui/ash/test_login_screen.cc +++ b/chrome/browser/ui/ash/test_login_screen.cc
@@ -128,7 +128,7 @@ void TestLoginScreen::SetShowGuestButtonInOobe(bool show) {} -void TestLoginScreen::SetShowParentAccess(bool show) {} +void TestLoginScreen::SetShowParentAccessButton(bool show) {} void TestLoginScreen::FocusLoginShelf(bool reverse) {}
diff --git a/chrome/browser/ui/ash/test_login_screen.h b/chrome/browser/ui/ash/test_login_screen.h index cde5266..a0796cde 100644 --- a/chrome/browser/ui/ash/test_login_screen.h +++ b/chrome/browser/ui/ash/test_login_screen.h
@@ -82,7 +82,7 @@ void SetShutdownButtonEnabled(bool enable) override; void SetAllowLoginAsGuest(bool allow_guest) override; void SetShowGuestButtonInOobe(bool show) override; - void SetShowParentAccess(bool show) override; + void SetShowParentAccessButton(bool show) override; void FocusLoginShelf(bool reverse) override; private:
diff --git a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm index 493c9c0a..dd02d82 100644 --- a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm +++ b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm
@@ -22,7 +22,7 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/views/chrome_test_views_delegate.h" #include "components/bookmarks/test/bookmark_test_helpers.h" -#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h" +#include "components/signin/core/browser/list_accounts_test_utils.h" #include "components/sync_preferences/pref_service_syncable.h" #include "content/public/test/test_browser_thread_bundle.h" #include "ui/views/test/widget_test.h" @@ -58,7 +58,7 @@ // Always fake out the Gaia service to avoid issuing network requests. TestingProfile::TestingFactories testing_factories = { {GaiaCookieManagerServiceFactory::GetInstance(), - base::BindRepeating(&BuildFakeGaiaCookieManagerServiceWithURLLoader, + base::BindRepeating(&BuildGaiaCookieManagerServiceWithURLLoader, &test_url_loader_factory_)}}; profile_ = profile_manager_.CreateTestingProfile( @@ -80,12 +80,7 @@ base::BindRepeating(&AutocompleteClassifierFactory::BuildInstanceFor)); // Configure the GaiaCookieManagerService to return no accounts. - // This is copied from - // chrome/browser/ui/views/frame/test_with_browser_view.cc. - FakeGaiaCookieManagerService* gcms = - static_cast<FakeGaiaCookieManagerService*>( - GaiaCookieManagerServiceFactory::GetForProfile(profile_)); - gcms->SetListAccountsResponseHttpNotFound(); + signin::SetListAccountsResponseHttpNotFound(&test_url_loader_factory_); profile_->CreateBookmarkModel(true); bookmarks::test::WaitForBookmarkModelToLoad(
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc index 27d9b7f..8b724e0 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -9,7 +9,6 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/defaults.h" #include "chrome/browser/prefs/browser_prefs.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/global_error/global_error.h" #include "chrome/browser/ui/global_error/global_error_service.h" @@ -188,7 +187,6 @@ // Make sure services required for tests are initialized. GlobalErrorService* service = GlobalErrorServiceFactory::GetForProfile(browser()->profile()); - ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile()); const int command1 = 1234567; MenuError* error1 = new MenuError(command1); service->AddGlobalError(base::WrapUnique(error1));
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index 3ef92b7..1a697469 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" @@ -632,8 +631,6 @@ LoginDisplayHost* login_display_host = LoginDisplayHost::default_host(); if (login_display_host) login_display_host->SetStatusAreaVisible(true); - if (ScreenLocker::default_screen_locker()) - ScreenLocker::default_screen_locker()->delegate()->OnHeaderBarVisible(); } void CoreOobeHandler::HandleRaiseTabKeyEvent(bool reverse) {
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 263ad4e..7e264b7 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -115,7 +115,6 @@ OobeUI::kArcKioskSplashDisplay, OobeUI::kDiscoverDisplay, OobeUI::kGaiaSigninDisplay, - OobeUI::kLockDisplay, OobeUI::kLoginDisplay, OobeUI::kOobeDisplay, OobeUI::kUserAddingDisplay}; @@ -133,7 +132,6 @@ "custom_elements_user_pod.html"; constexpr char kDiscoverJSPath[] = "discover_app.js"; constexpr char kKeyboardUtilsJSPath[] = "keyboard_utils.js"; -constexpr char kLockJSPath[] = "lock.js"; constexpr char kLoginJSPath[] = "login.js"; constexpr char kOobeJSPath[] = "oobe.js"; constexpr char kProductLogoPath[] = "product-logo.png"; @@ -208,19 +206,6 @@ source->AddResourcePath(kCustomElementsJSPath, IDR_CUSTOM_ELEMENTS_OOBE_JS); } -// Default and non-shared resource definition for kLockDisplay display type. -// chrome://oobe/lock -void AddLockDisplayTypeDefaultResources(content::WebUIDataSource* source) { - // TODO(crbug.com/810170): Remove the resource files associated with - // kShowNonMdLogin switch (IDR_LOCK_HTML/JS and IDR_LOGIN_HTML/JS and the - // files those use). - source->SetDefaultResource(IDR_MD_LOCK_HTML); - source->AddResourcePath(kLockJSPath, IDR_MD_LOCK_JS); - source->AddResourcePath(kCustomElementsHTMLPath, - IDR_CUSTOM_ELEMENTS_LOCK_HTML); - source->AddResourcePath(kCustomElementsJSPath, IDR_CUSTOM_ELEMENTS_LOCK_JS); -} - // Default and non-shared resource definition for kDiscoverDisplay display type. // chrome://oobe/discover void AddDiscoverDisplayTypeDefaultResources(content::WebUIDataSource* source) { @@ -256,7 +241,7 @@ if (display_type == OobeUI::kOobeDisplay) { AddOobeDisplayTypeDefaultResources(source); } else if (display_type == OobeUI::kLockDisplay) { - AddLockDisplayTypeDefaultResources(source); + NOTREACHED(); } else if (display_type == OobeUI::kDiscoverDisplay) { AddDiscoverDisplayTypeDefaultResources(source); } else { @@ -266,13 +251,11 @@ // Configure shared resources AddProductLogoResources(source); - if (display_type != OobeUI::kLockDisplay) { - AddSyncConsentResources(source); - AddArcScreensResources(source); - AddEnterpriseEnrollmentResources(source); - } - if (display_type == OobeUI::kLockDisplay || - display_type == OobeUI::kLoginDisplay) { + AddSyncConsentResources(source); + AddArcScreensResources(source); + AddEnterpriseEnrollmentResources(source); + + if (display_type == OobeUI::kLoginDisplay) { source->AddResourcePath(kCustomElementsUserPodHTMLPath, IDR_CUSTOM_ELEMENTS_USER_POD_HTML); } @@ -495,9 +478,7 @@ if (display_type_ != OobeUI::kDiscoverDisplay) ConfigureOobeDisplay(); - if (display_type_ != OobeUI::kLockDisplay) { - AddScreenHandler(std::make_unique<DiscoverScreenHandler>()); - } + AddScreenHandler(std::make_unique<DiscoverScreenHandler>()); base::DictionaryValue localized_strings; GetLocalizedStrings(&localized_strings);
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index c34aad9b..0323e94 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -41,7 +41,6 @@ #include "chrome/browser/chromeos/login/help_app_launcher.h" #include "chrome/browser/chromeos/login/hwid_checker.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" -#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" #include "chrome/browser/chromeos/login/lock_screen_utils.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" @@ -476,7 +475,6 @@ &SigninScreenHandler::HandleToggleKioskEnableScreen); AddCallback("accountPickerReady", &SigninScreenHandler::HandleAccountPickerReady); - AddCallback("wallpaperReady", &SigninScreenHandler::HandleWallpaperReady); AddCallback("signOutUser", &SigninScreenHandler::HandleSignOutUser); AddCallback("openInternetDetailDialog", &SigninScreenHandler::HandleOpenInternetDetailDialog); @@ -1302,14 +1300,6 @@ delegate_->OnSigninScreenReady(); } -void SigninScreenHandler::HandleWallpaperReady() { - if (ScreenLocker::default_screen_locker()) { - ScreenLocker::default_screen_locker() - ->delegate() - ->OnLockBackgroundDisplayed(); - } -} - void SigninScreenHandler::HandleSignOutUser() { if (delegate_) delegate_->Signout();
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index aa931de..603a707 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -348,7 +348,6 @@ void HandleToggleResetScreen(); void HandleToggleKioskAutolaunchScreen(); void HandleAccountPickerReady(); - void HandleWallpaperReady(); void HandleSignOutUser(); void HandleOpenInternetDetailDialog(); void HandleLoginVisible(const std::string& source);
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc b/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc index f64cc92..4651c66d 100644 --- a/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc +++ b/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc
@@ -4,97 +4,15 @@ #include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" -#include "build/build_config.h" -#include "chrome/common/pref_names.h" -#include "components/contextual_search/buildflags.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/common/safe_browsing_prefs.h" - -#if !defined(OS_ANDROID) -#include "components/spellcheck/browser/pref_names.h" -#endif -#if BUILDFLAG(BUILD_CONTEXTUAL_SEARCH) -#include "components/contextual_search/core/browser/contextual_search_preference.h" -#endif - ChromeUnifiedConsentServiceClient::ChromeUnifiedConsentServiceClient( - PrefService* pref_service) - : pref_service_(pref_service) { - DCHECK(pref_service_); - ObserveServicePrefChange(Service::kSafeBrowsingExtendedReporting, - prefs::kSafeBrowsingScoutReportingEnabled, - pref_service_); -#if !defined(OS_ANDROID) - ObserveServicePrefChange(Service::kSpellCheck, - spellcheck::prefs::kSpellCheckUseSpellingService, - pref_service_); -#endif -#if BUILDFLAG(BUILD_CONTEXTUAL_SEARCH) - ObserveServicePrefChange(Service::kContextualSearch, - contextual_search::GetPrefName(), pref_service_); -#endif -} + PrefService* pref_service) {} ChromeUnifiedConsentServiceClient::~ChromeUnifiedConsentServiceClient() {} ChromeUnifiedConsentServiceClient::ServiceState ChromeUnifiedConsentServiceClient::GetServiceState(Service service) { - switch (service) { - case Service::kSafeBrowsingExtendedReporting: - return safe_browsing::IsExtendedReportingEnabled(*pref_service_) - ? ServiceState::kEnabled - : ServiceState::kDisabled; - case Service::kSpellCheck: -#if !defined(OS_ANDROID) - return pref_service_->GetBoolean( - spellcheck::prefs::kSpellCheckUseSpellingService) - ? ServiceState::kEnabled - : ServiceState::kDisabled; -#else - return ServiceState::kNotSupported; -#endif - case Service::kContextualSearch: -#if BUILDFLAG(BUILD_CONTEXTUAL_SEARCH) - return contextual_search::IsEnabled(*pref_service_) - ? ServiceState::kEnabled - : ServiceState::kDisabled; -#else - return ServiceState::kNotSupported; -#endif - } - - NOTREACHED(); + return ServiceState::kNotSupported; } void ChromeUnifiedConsentServiceClient::SetServiceEnabled(Service service, - bool enabled) { - if (GetServiceState(service) == ServiceState::kNotSupported) - return; - - switch (service) { - case Service::kSafeBrowsingExtendedReporting: - safe_browsing::SetExtendedReportingPref(pref_service_, enabled); - break; - case Service::kSpellCheck: -#if !defined(OS_ANDROID) - pref_service_->SetBoolean( - spellcheck::prefs::kSpellCheckUseSpellingService, enabled); -#else - NOTREACHED(); -#endif - break; - case Service::kContextualSearch: { -#if BUILDFLAG(BUILD_CONTEXTUAL_SEARCH) - contextual_search::ContextualSearchPreference* contextual_search_pref = - contextual_search::ContextualSearchPreference::GetInstance(); - if (enabled) - contextual_search_pref->EnableIfUndecided(pref_service_); - else - contextual_search_pref->SetPref(pref_service_, false); -#else - NOTREACHED(); -#endif - break; - } - } -} + bool enabled) {}
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.h b/chrome/browser/unified_consent/chrome_unified_consent_service_client.h index 9550cf3..7f39d76 100644 --- a/chrome/browser/unified_consent/chrome_unified_consent_service_client.h +++ b/chrome/browser/unified_consent/chrome_unified_consent_service_client.h
@@ -20,9 +20,6 @@ ServiceState GetServiceState(Service service) override; void SetServiceEnabled(Service service, bool enabled) override; - private: - PrefService* pref_service_; - DISALLOW_COPY_AND_ASSIGN(ChromeUnifiedConsentServiceClient); };
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc index 21d9ad6..0b4e105 100644 --- a/chrome/browser/unified_consent/unified_consent_browsertest.cc +++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -128,12 +128,12 @@ metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection, 1); histogram_tester_.ExpectBucketCount( "UnifiedConsent.SyncAndGoogleServicesSettings", - metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting, 1); + metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting, 0); histogram_tester_.ExpectBucketCount( "UnifiedConsent.SyncAndGoogleServicesSettings", - metrics::SettingsHistogramValue::kSpellCheck, 1); + metrics::SettingsHistogramValue::kSpellCheck, 0); histogram_tester_.ExpectTotalCount( - "UnifiedConsent.SyncAndGoogleServicesSettings", 4); + "UnifiedConsent.SyncAndGoogleServicesSettings", 2); } } // namespace
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc index fe6880f8..841b933 100644 --- a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc +++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/web_applications/components/web_app_audio_focus_id_map.h" #include "content/public/browser/media_session.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/site_instance.h" namespace web_app { @@ -18,11 +19,13 @@ WebAppTabHelperBase::~WebAppTabHelperBase() = default; -void WebAppTabHelperBase::SetAudioFocusIdMap( - WebAppAudioFocusIdMap* audio_focus_id_map) { +void WebAppTabHelperBase::Init(WebAppAudioFocusIdMap* audio_focus_id_map) { DCHECK(!audio_focus_id_map_ && audio_focus_id_map); - audio_focus_id_map_ = audio_focus_id_map; + + // Sync app_id with the initial url from WebContents (used in Tab Restore etc) + const GURL init_url = web_contents()->GetSiteInstance()->GetSiteURL(); + SetAppId(GetAppId(init_url)); } void WebAppTabHelperBase::SetAppId(const AppId& app_id) { @@ -34,12 +37,6 @@ OnAssociatedAppChanged(); } -void WebAppTabHelperBase::ResetAppId() { - app_id_.clear(); - - OnAssociatedAppChanged(); -} - void WebAppTabHelperBase::DidFinishNavigation( content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()) @@ -59,6 +56,27 @@ new_tab_helper->SetAppId(app_id()); } +void WebAppTabHelperBase::OnWebAppInstalled(const AppId& installed_app_id) { + // Check if current web_contents url is in scope for the newly installed app. + const web_app::AppId app_id = GetAppId(web_contents()->GetURL()); + if (app_id == installed_app_id) + SetAppId(app_id); +} + +void WebAppTabHelperBase::OnWebAppUninstalled(const AppId& uninstalled_app_id) { + if (app_id() == uninstalled_app_id) + ResetAppId(); +} + +void WebAppTabHelperBase::OnWebAppRegistryShutdown() { + ResetAppId(); +} + +void WebAppTabHelperBase::ResetAppId() { + app_id_.clear(); + OnAssociatedAppChanged(); +} + void WebAppTabHelperBase::OnAssociatedAppChanged() { UpdateAudioFocusGroupId(); }
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.h b/chrome/browser/web_applications/components/web_app_tab_helper_base.h index c8da080..b7df6d8 100644 --- a/chrome/browser/web_applications/components/web_app_tab_helper_base.h +++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.h
@@ -27,17 +27,16 @@ public: ~WebAppTabHelperBase() override; - // This provides a weak reference to the current audio focus id map instance - // which is owned by WebAppProvider. This is used to ensure that all web - // contents associated with a web app shared the same audio focus group id. - void SetAudioFocusIdMap(WebAppAudioFocusIdMap* audio_focus_id_map); + // |audio_focus_id_map| is a weak reference to the current audio focus id map + // instance which is owned by WebAppProvider. This is used to ensure that all + // web contents associated with a web app shared the same audio focus group + // id. + void Init(WebAppAudioFocusIdMap* audio_focus_id_map); const AppId& app_id() const { return app_id_; } - // Set app_id on web app installation or tab restore. + // Set associated app_id. void SetAppId(const AppId& app_id); - // Clear app_id on web app uninstallation. - void ResetAppId(); // content::WebContentsObserver: void DidFinishNavigation( @@ -61,6 +60,11 @@ friend class content::WebContentsUserData<WebAppTabHelperBase>; WEB_CONTENTS_USER_DATA_KEY_DECL(); + // TODO(loyso): Call these methods for new extension-independent system. + void OnWebAppInstalled(const AppId& installed_app_id); + void OnWebAppUninstalled(const AppId& uninstalled_app_id); + void OnWebAppRegistryShutdown(); + // Clone |this| tab helper (preserving a derived type). virtual WebAppTabHelperBase* CloneForWebContents( content::WebContents* web_contents) const = 0; @@ -75,6 +79,8 @@ private: friend class WebAppAudioFocusBrowserTest; + void ResetAppId(); + // Runs any logic when the associated app either changes or is removed. void OnAssociatedAppChanged();
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc index 7577c2b0..342723e 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc
@@ -17,16 +17,17 @@ namespace extensions { BookmarkAppTabHelper::BookmarkAppTabHelper(content::WebContents* web_contents) - : WebAppTabHelperBase(web_contents) {} + : WebAppTabHelperBase(web_contents) { + scoped_observer_.Add( + ExtensionRegistry::Get(web_contents->GetBrowserContext())); +} BookmarkAppTabHelper::~BookmarkAppTabHelper() = default; // static BookmarkAppTabHelper* BookmarkAppTabHelper::CreateForWebContents( content::WebContents* web_contents) { - // Do nothing if already exists. - if (FromWebContents(web_contents)) - return nullptr; + DCHECK(!FromWebContents(web_contents)); auto tab_helper = std::make_unique<BookmarkAppTabHelper>(web_contents); BookmarkAppTabHelper* result = tab_helper.get(); @@ -77,6 +78,25 @@ UrlHandlers::GetUrlHandlers(app); } +void BookmarkAppTabHelper::OnExtensionInstalled( + content::BrowserContext* browser_context, + const extensions::Extension* extension, + bool is_update) { + OnWebAppInstalled(extension->id()); +} + +void BookmarkAppTabHelper::OnExtensionUninstalled( + content::BrowserContext* browser_context, + const extensions::Extension* extension, + extensions::UninstallReason reason) { + OnWebAppUninstalled(extension->id()); +} + +void BookmarkAppTabHelper::OnShutdown(ExtensionRegistry* registry) { + OnWebAppRegistryShutdown(); + scoped_observer_.RemoveAll(); +} + const Extension* BookmarkAppTabHelper::GetExtension() const { DCHECK(!app_id().empty()); content::BrowserContext* browser_context =
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h index a7527c0f..895e204 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h
@@ -6,7 +6,9 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_TAB_HELPER_H_ #include "base/macros.h" +#include "base/scoped_observer.h" #include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" +#include "extensions/browser/extension_registry_observer.h" namespace content { class WebContents; @@ -15,9 +17,11 @@ namespace extensions { class Extension; +class ExtensionRegistry; // Allows to associate a tab with bookmark app. -class BookmarkAppTabHelper : public web_app::WebAppTabHelperBase { +class BookmarkAppTabHelper : public web_app::WebAppTabHelperBase, + public ExtensionRegistryObserver { public: explicit BookmarkAppTabHelper(content::WebContents* web_contents); ~BookmarkAppTabHelper() override; @@ -36,12 +40,24 @@ bool IsUserInstalled() const override; bool IsFromInstallButton() const override; + // ExtensionRegistryObserver: + void OnExtensionInstalled(content::BrowserContext* browser_context, + const Extension* extension, + bool is_update) override; + void OnExtensionUninstalled(content::BrowserContext* browser_context, + const Extension* extension, + UninstallReason reason) override; + void OnShutdown(ExtensionRegistry* registry) override; + private: // Get a pointer from app_id_. Semantically, we use app_id_ as a weak // reference. It might become nullptr in unforeseen circumstances (Uninstall). // TODO(loyso): Provide guarantees for app_id_. crbug.com/915034 const Extension* GetExtension() const; + ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> scoped_observer_{ + this}; + DISALLOW_COPY_AND_ASSIGN(BookmarkAppTabHelper); };
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 853d969..2f85901 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -143,15 +143,20 @@ if (!provider) return nullptr; - if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) - WebAppTabHelper::CreateForWebContents(web_contents); - else - extensions::BookmarkAppTabHelper::CreateForWebContents(web_contents); - WebAppTabHelperBase* tab_helper = WebAppTabHelperBase::FromWebContents(web_contents); - tab_helper->SetAudioFocusIdMap(provider->audio_focus_id_map_.get()); + // Do nothing if already exists. + if (tab_helper) + return tab_helper; + if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) { + tab_helper = WebAppTabHelper::CreateForWebContents(web_contents); + } else { + tab_helper = + extensions::BookmarkAppTabHelper::CreateForWebContents(web_contents); + } + + tab_helper->Init(provider->audio_focus_id_map_.get()); return tab_helper; }
diff --git a/chrome/browser/web_applications/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc index d60225f..7c8d743 100644 --- a/chrome/browser/web_applications/web_app_tab_helper.cc +++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -14,9 +14,7 @@ // static WebAppTabHelper* WebAppTabHelper::CreateForWebContents( content::WebContents* web_contents) { - // Do nothing if already exists. - if (FromWebContents(web_contents)) - return nullptr; + DCHECK(!FromWebContents(web_contents)); auto tab_helper = std::make_unique<WebAppTabHelper>(web_contents); WebAppTabHelper* result = tab_helper.get();
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index ca214540..e0eefd2 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -477,13 +477,6 @@ base::FEATURE_ENABLED_BY_DEFAULT}; #endif -#if defined(OS_CHROMEOS) -// The lock screen will be preloaded so it is instantly available when the user -// locks the Chromebook device. -const base::Feature kPreloadLockScreen{"PreloadLockScreen", - base::FEATURE_ENABLED_BY_DEFAULT}; -#endif - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // If enabled, Print Preview will use the CloudPrinterHandler instead of the // cloud print interface to communicate with the cloud print server. This
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 1f14c95..f434cbe 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -319,10 +319,6 @@ extern const base::Feature kPreferHtmlOverPlugins; #endif -#if defined(OS_CHROMEOS) -COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kPreloadLockScreen; -#endif - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kCloudPrinterHandler;
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html b/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html index ef0a3d2..3dbe2d5 100644 --- a/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html +++ b/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html
@@ -7,7 +7,6 @@ const token = "?next="; if (!query.startsWith(token)) return false; - let query_index = query.indexOf(token); window.location.href = query.substr(query_index + token.length); return true; }
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc index e7b0c0ca..61aaed0 100644 --- a/chromecast/browser/cast_network_contexts.cc +++ b/chromecast/browser/cast_network_contexts.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/task/post_task.h" +#include "chromecast/base/cast_features.h" #include "chromecast/browser/cast_browser_context.h" #include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/cast_http_user_agent_settings.h" @@ -209,6 +210,11 @@ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) return; + // Disable QUIC if instructed by DCS. This remains constant for the lifetime + // of the process. + if (!chromecast::IsFeatureEnabled(kEnableQuic)) + network_service->DisableQuic(); + // The system NetworkContext must be created first, since it sets // |primary_network_context| to true. network_service->CreateNetworkContext(MakeRequest(&system_network_context_), @@ -239,6 +245,15 @@ network_context_params->accept_language = CastHttpUserAgentSettings::AcceptLanguage(); + // Disable idle sockets close on memory pressure, if instructed by DCS. On + // memory constrained devices: + // 1. if idle sockets are closed when memory pressure happens, cast_shell will + // close and re-open lots of connections to server. + // 2. if idle sockets are kept alive when memory pressure happens, this may + // cause JS engine gc frequently, leading to JS suspending. + network_context_params->disable_idle_sockets_close_on_memory_pressure = + IsFeatureEnabled(kDisableIdleSocketsCloseOnMemoryPressure); + return network_context_params; }
diff --git a/chromeos/components/proximity_auth/screenlock_bridge.h b/chromeos/components/proximity_auth/screenlock_bridge.h index d4641aa..1aa2a94e 100644 --- a/chromeos/components/proximity_auth/screenlock_bridge.h +++ b/chromeos/components/proximity_auth/screenlock_bridge.h
@@ -110,6 +110,8 @@ virtual void HideUserPodCustomIcon(const AccountId& account_id) = 0; // (Re)enable lock screen UI. + // TODO(crbug.com/927498): Remove TestLockHandler dependency on this, and + // then remove this method. virtual void EnableInput() = 0; // Set the authentication type to be used on the lock screen.
diff --git a/components/cronet/tools/generate_javadoc.py b/components/cronet/tools/generate_javadoc.py index a76636cf..062190d4 100755 --- a/components/cronet/tools/generate_javadoc.py +++ b/components/cronet/tools/generate_javadoc.py
@@ -114,7 +114,9 @@ assert options.zip_file deps = [] for root, _, filenames in os.walk(options.input_dir): - deps.extend(os.path.join(root, f) for f in filenames) + # Ignore .pyc files here, it might be re-generated during build. + deps.extend(os.path.join(root, f) for f in filenames + if not f.endswith('.pyc')) build_utils.WriteDepfile(options.depfile, options.zip_file, deps) # Clean up temporary output directory. build_utils.DeleteDirectory(unzipped_jar_path)
diff --git a/components/gwp_asan/client/guarded_page_allocator.cc b/components/gwp_asan/client/guarded_page_allocator.cc index 798583809..a50d076 100644 --- a/components/gwp_asan/client/guarded_page_allocator.cc +++ b/components/gwp_asan/client/guarded_page_allocator.cc
@@ -17,6 +17,7 @@ #include "components/crash/core/common/crash_key.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" +#include "components/gwp_asan/common/pack_stack_trace.h" namespace gwp_asan { namespace internal { @@ -174,10 +175,13 @@ slots_[slot].alloc_size = size; slots_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr); + void* trace[AllocatorState::kMaxStackFrames]; + size_t len = + base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); + slots_[slot].alloc.trace_len = Pack(reinterpret_cast<uintptr_t*>(trace), len, + slots_[slot].alloc.packed_trace, + sizeof(slots_[slot].alloc.packed_trace)); slots_[slot].alloc.tid = base::PlatformThread::CurrentId(); - slots_[slot].alloc.trace_len = base::debug::CollectStackTrace( - reinterpret_cast<void**>(&slots_[slot].alloc.trace), - AllocatorState::kMaxStackFrames); slots_[slot].alloc.trace_collected = true; slots_[slot].dealloc.tid = base::kInvalidThreadId; @@ -187,10 +191,14 @@ } void GuardedPageAllocator::RecordDeallocationInSlot(size_t slot) { + void* trace[AllocatorState::kMaxStackFrames]; + size_t len = + base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); + slots_[slot].dealloc.trace_len = + Pack(reinterpret_cast<uintptr_t*>(trace), len, + slots_[slot].dealloc.packed_trace, + sizeof(slots_[slot].dealloc.packed_trace)); slots_[slot].dealloc.tid = base::PlatformThread::CurrentId(); - slots_[slot].dealloc.trace_len = base::debug::CollectStackTrace( - reinterpret_cast<void**>(&slots_[slot].dealloc.trace), - AllocatorState::kMaxStackFrames); slots_[slot].dealloc.trace_collected = true; }
diff --git a/components/gwp_asan/common/allocator_state.cc b/components/gwp_asan/common/allocator_state.cc index ccd2a7d..8aa839f 100644 --- a/components/gwp_asan/common/allocator_state.cc +++ b/components/gwp_asan/common/allocator_state.cc
@@ -15,6 +15,7 @@ // TODO: Delete out-of-line constexpr defininitons once C++17 is in use. constexpr size_t AllocatorState::kGpaMaxPages; constexpr size_t AllocatorState::kMaxStackFrames; +constexpr size_t AllocatorState::kMaxPackedTraceLength; AllocatorState::AllocatorState() {}
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h index d393749b..2f1f88b 100644 --- a/components/gwp_asan/common/allocator_state.h +++ b/components/gwp_asan/common/allocator_state.h
@@ -40,6 +40,9 @@ static constexpr size_t kGpaMaxPages = 256; // Maximum number of stack trace frames to collect. static constexpr size_t kMaxStackFrames = 60; + // Number of bytes to allocate for packed stack traces. This can hold + // approximately kMaxStackFrames under normal conditions. + static constexpr size_t kMaxPackedTraceLength = 200; enum class ErrorType { kUseAfterFree = 0, @@ -65,9 +68,9 @@ // (De)allocation thread id or base::kInvalidThreadId if no (de)allocation // occurred. base::PlatformThreadId tid = base::kInvalidThreadId; - // Stack trace contents. - uintptr_t trace[kMaxStackFrames]; - // Stack trace length. + // Packed stack trace. + uint8_t packed_trace[kMaxPackedTraceLength]; + // Length used to encode the packed stack trace. size_t trace_len = 0; // Whether a stack trace has been collected for this (de)allocation. bool trace_collected = false;
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc index 04e70d1..c963c8ce 100644 --- a/components/gwp_asan/crash_handler/crash_analyzer.cc +++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" +#include "components/gwp_asan/common/pack_stack_trace.h" #include "components/gwp_asan/crash_handler/crash.pb.h" #include "third_party/crashpad/crashpad/client/annotation.h" #include "third_party/crashpad/crashpad/snapshot/cpu_context.h" @@ -153,17 +154,26 @@ if (!slot_info.trace_len || !slot_info.trace_collected) return; - if (slot_info.trace_len > AllocatorState::kMaxStackFrames) { + if (slot_info.trace_len > AllocatorState::kMaxPackedTraceLength) { DLOG(ERROR) << "Stack trace length is corrupted: " << slot_info.trace_len; return; } - // On 32-bit platforms we can't copy directly to + uintptr_t unpacked_stack_trace[AllocatorState::kMaxPackedTraceLength]; + size_t unpacked_len = + Unpack(slot_info.packed_trace, slot_info.trace_len, unpacked_stack_trace, + AllocatorState::kMaxPackedTraceLength); + if (!unpacked_len) { + DLOG(ERROR) << "Failed to unpack stack trace."; + return; + } + + // On 32-bit platforms we can't copy directly into // proto_info->mutable_stack_trace()->mutable_data(). - proto_info->mutable_stack_trace()->Resize(slot_info.trace_len, 0); + proto_info->mutable_stack_trace()->Resize(unpacked_len, 0); uint64_t* output = proto_info->mutable_stack_trace()->mutable_data(); - for (size_t i = 0; i < slot_info.trace_len; i++) - output[i] = slot_info.trace[i]; + for (size_t i = 0; i < unpacked_len; i++) + output[i] = unpacked_stack_trace[i]; } } // namespace internal
diff --git a/components/safe_browsing/browser/BUILD.gn b/components/safe_browsing/browser/BUILD.gn index 9b88876e5..7d3a7b2 100644 --- a/components/safe_browsing/browser/BUILD.gn +++ b/components/safe_browsing/browser/BUILD.gn
@@ -3,8 +3,9 @@ # found in the LICENSE file. import("//build/config/features.gni") +import("//build/config/jumbo.gni") -source_set("browser") { +jumbo_source_set("browser") { sources = [ "base_parallel_resource_throttle.cc", "base_parallel_resource_throttle.h",
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 23518fd8..f6b83fb 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -82,8 +82,6 @@ "profile_oauth2_token_service.h", "signin_client.cc", "signin_client.h", - "signin_internals_util.cc", - "signin_internals_util.h", "signin_manager.cc", "signin_manager.h", "signin_manager_base.cc", @@ -144,6 +142,8 @@ "signin_error_controller.h", "signin_header_helper.cc", "signin_header_helper.h", + "signin_internals_util.cc", + "signin_internals_util.h", "signin_investigator.cc", "signin_investigator.h", "signin_status_metrics_provider.cc",
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index 5711c61..d8684e7 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -25,7 +25,6 @@ #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" -#include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_switches.h" #include "google_apis/gaia/oauth2_token_service_delegate.h" #include "net/base/backoff_entry.h"
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h index 5a5ed9d..3a1ca42 100644 --- a/components/signin/core/browser/about_signin_internals.h +++ b/components/signin/core/browser/about_signin_internals.h
@@ -16,6 +16,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_error_controller.h" +#include "components/signin/core/browser/signin_internals_util.h" #include "google_apis/gaia/oauth2_token_service.h" #include "services/identity/public/cpp/identity_manager.h"
diff --git a/components/signin/core/browser/account_info.h b/components/signin/core/browser/account_info.h index c98529c..df99283 100644 --- a/components/signin/core/browser/account_info.h +++ b/components/signin/core/browser/account_info.h
@@ -32,8 +32,6 @@ std::string account_id; std::string gaia; std::string email; - - bool is_under_advanced_protection = false; }; // Stores all the information known about an account. Part of the information @@ -55,6 +53,7 @@ std::string picture_url; gfx::Image account_image; bool is_child_account = false; + bool is_under_advanced_protection = false; // Returns true if all fields in the account info are empty. bool IsEmpty() const;
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index c896fc7..e0cfbbf 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -17,7 +17,6 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/identity_utils.h" -#include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/signin_pref_names.h" #include "google_apis/gaia/gaia_auth_util.h"
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h index a0eeed28..4582c5c 100644 --- a/components/signin/core/browser/signin_manager.h +++ b/components/signin/core/browser/signin_manager.h
@@ -40,7 +40,6 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" -#include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/signin_metrics.h" #include "net/cookies/canonical_cookie.h"
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index 3099703b..ff60c495 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -35,7 +35,6 @@ #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_member.h" #include "components/signin/core/browser/account_info.h" -#include "components/signin/core/browser/signin_internals_util.h" #include "google_apis/gaia/google_service_auth_error.h" class AccountTrackerService;
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc index f50b898..eebaaef 100644 --- a/components/sync/base/sync_prefs.cc +++ b/components/sync/base/sync_prefs.cc
@@ -34,7 +34,6 @@ pref_groups[APPS].Put(APP_SETTINGS); pref_groups[APPS].Put(APP_LIST); pref_groups[APPS].Put(ARC_PACKAGE); - pref_groups[APPS].Put(READING_LIST); pref_groups[AUTOFILL].Put(AUTOFILL_PROFILE); pref_groups[AUTOFILL].Put(AUTOFILL_WALLET_DATA);
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc index 49c8aa6..e754251 100644 --- a/components/sync/base/sync_prefs_unittest.cc +++ b/components/sync/base/sync_prefs_unittest.cc
@@ -260,7 +260,6 @@ expected_preferred_types.Put(APP_NOTIFICATIONS); expected_preferred_types.Put(APP_SETTINGS); expected_preferred_types.Put(ARC_PACKAGE); - expected_preferred_types.Put(READING_LIST); } if (type == EXTENSIONS) { expected_preferred_types.Put(EXTENSION_SETTINGS);
diff --git a/components/sync/model/fake_model_type_change_processor.cc b/components/sync/model/fake_model_type_change_processor.cc index c2fe6da..bcb050f 100644 --- a/components/sync/model/fake_model_type_change_processor.cc +++ b/components/sync/model/fake_model_type_change_processor.cc
@@ -48,6 +48,16 @@ return false; } +base::Time FakeModelTypeChangeProcessor::GetEntityCreationTime( + const std::string& storage_key) const { + return base::Time(); +} + +base::Time FakeModelTypeChangeProcessor::GetEntityModificationTime( + const std::string& storage_key) const { + return base::Time(); +} + void FakeModelTypeChangeProcessor::OnModelStarting( ModelTypeSyncBridge* bridge) {}
diff --git a/components/sync/model/fake_model_type_change_processor.h b/components/sync/model/fake_model_type_change_processor.h index 48c70965..d166b9f7 100644 --- a/components/sync/model/fake_model_type_change_processor.h +++ b/components/sync/model/fake_model_type_change_processor.h
@@ -39,6 +39,10 @@ void UntrackEntityForClientTagHash( const std::string& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; + base::Time GetEntityCreationTime( + const std::string& storage_key) const override; + base::Time GetEntityModificationTime( + const std::string& storage_key) const override; void OnModelStarting(ModelTypeSyncBridge* bridge) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override; bool IsTrackingMetadata() override;
diff --git a/components/sync/model/mock_model_type_change_processor.cc b/components/sync/model/mock_model_type_change_processor.cc index 4f204ac..398c4de 100644 --- a/components/sync/model/mock_model_type_change_processor.cc +++ b/components/sync/model/mock_model_type_change_processor.cc
@@ -53,6 +53,16 @@ return other_->IsEntityUnsynced(storage_key); } + base::Time GetEntityCreationTime( + const std::string& storage_key) const override { + return other_->GetEntityCreationTime(storage_key); + } + + base::Time GetEntityModificationTime( + const std::string& storage_key) const override { + return other_->GetEntityModificationTime(storage_key); + } + void OnModelStarting(ModelTypeSyncBridge* bridge) override { other_->OnModelStarting(bridge); }
diff --git a/components/sync/model/mock_model_type_change_processor.h b/components/sync/model/mock_model_type_change_processor.h index 725a9fd9..b8b55b18 100644 --- a/components/sync/model/mock_model_type_change_processor.h +++ b/components/sync/model/mock_model_type_change_processor.h
@@ -35,6 +35,10 @@ MOCK_METHOD1(UntrackEntityForClientTagHash, void(const std::string& client_tag_hash)); MOCK_METHOD1(IsEntityUnsynced, bool(const std::string& storage_key)); + MOCK_CONST_METHOD1(GetEntityCreationTime, + base::Time(const std::string& storage_key)); + MOCK_CONST_METHOD1(GetEntityModificationTime, + base::Time(const std::string& storage_key)); MOCK_METHOD1(OnModelStarting, void(ModelTypeSyncBridge* bridge)); MOCK_METHOD1(ModelReadyToSync, void(std::unique_ptr<MetadataBatch> batch)); MOCK_METHOD0(IsTrackingMetadata, bool());
diff --git a/components/sync/model/model_type_change_processor.h b/components/sync/model/model_type_change_processor.h index fd52c5a..872904b4 100644 --- a/components/sync/model/model_type_change_processor.h +++ b/components/sync/model/model_type_change_processor.h
@@ -11,6 +11,7 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/time/time.h" #include "components/sync/base/model_type.h" #include "components/sync/model/entity_data.h" #include "components/sync/model/model_error.h" @@ -74,6 +75,16 @@ // USS's ability to delete local data upcon commit completion. virtual bool IsEntityUnsynced(const std::string& storage_key) = 0; + // Returns the creation timestamp of the sync entity, or a null time if the + // entity is not tracked. + virtual base::Time GetEntityCreationTime( + const std::string& storage_key) const = 0; + + // Returns the modification timestamp of the sync entity, or a null time if + // the entity is not tracked. + virtual base::Time GetEntityModificationTime( + const std::string& storage_key) const = 0; + // Pass the pointer to the processor so that the processor can notify the // bridge of various events; |bridge| must not be nullptr and must outlive // this object.
diff --git a/components/sync/model/model_type_sync_bridge.cc b/components/sync/model/model_type_sync_bridge.cc index feb04a6c..05cec458 100644 --- a/components/sync/model/model_type_sync_bridge.cc +++ b/components/sync/model/model_type_sync_bridge.cc
@@ -64,6 +64,10 @@ return change_processor_.get(); } +const ModelTypeChangeProcessor* ModelTypeSyncBridge::change_processor() const { + return change_processor_.get(); +} + base::Optional<ModelError> ModelTypeSyncBridge::ApplySyncChangesWithNewEncryptionRequirements( std::unique_ptr<MetadataChangeList> metadata_change_list,
diff --git a/components/sync/model/model_type_sync_bridge.h b/components/sync/model/model_type_sync_bridge.h index dfba8bfb..1d01a53 100644 --- a/components/sync/model/model_type_sync_bridge.h +++ b/components/sync/model/model_type_sync_bridge.h
@@ -178,6 +178,7 @@ // Put(). The changing metadata should be stored to persistent storage // before or atomically with the model changes. ModelTypeChangeProcessor* change_processor(); + const ModelTypeChangeProcessor* change_processor() const; // Similar to ApplySyncChanges(), but notifies the bridge that the processor // is about to recommit all data due to encryption changes.
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 abd575e..b6bc204 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
@@ -531,6 +531,24 @@ return entity->IsUnsynced(); } +base::Time ClientTagBasedModelTypeProcessor::GetEntityCreationTime( + const std::string& storage_key) const { + const ProcessorEntityTracker* entity = GetEntityForStorageKey(storage_key); + if (entity == nullptr) { + return base::Time(); + } + return ProtoTimeToTime(entity->metadata().creation_time()); +} + +base::Time ClientTagBasedModelTypeProcessor::GetEntityModificationTime( + const std::string& storage_key) const { + const ProcessorEntityTracker* entity = GetEntityForStorageKey(storage_key); + if (entity == nullptr) { + return base::Time(); + } + return ProtoTimeToTime(entity->metadata().modification_time()); +} + void ClientTagBasedModelTypeProcessor::NudgeForCommitIfNeeded() { // Don't bother sending anything if there's no one to send to. if (!IsConnected()) @@ -1221,12 +1239,28 @@ : GetEntityForTagHash(iter->second); } +const ProcessorEntityTracker* +ClientTagBasedModelTypeProcessor::GetEntityForStorageKey( + const std::string& storage_key) const { + auto iter = storage_key_to_tag_hash_.find(storage_key); + return iter == storage_key_to_tag_hash_.end() + ? nullptr + : GetEntityForTagHash(iter->second); +} + ProcessorEntityTracker* ClientTagBasedModelTypeProcessor::GetEntityForTagHash( const std::string& tag_hash) { auto it = entities_.find(tag_hash); return it != entities_.end() ? it->second.get() : nullptr; } +const ProcessorEntityTracker* +ClientTagBasedModelTypeProcessor::GetEntityForTagHash( + const std::string& tag_hash) const { + auto it = entities_.find(tag_hash); + return it != entities_.end() ? it->second.get() : nullptr; +} + ProcessorEntityTracker* ClientTagBasedModelTypeProcessor::CreateEntity( const std::string& storage_key, const EntityData& data) {
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 1e8ed33..5ee7c4a 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
@@ -70,6 +70,10 @@ void UntrackEntityForClientTagHash( const std::string& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; + base::Time GetEntityCreationTime( + const std::string& storage_key) const override; + base::Time GetEntityModificationTime( + const std::string& storage_key) const override; void OnModelStarting(ModelTypeSyncBridge* bridge) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override; bool IsTrackingMetadata() override; @@ -190,9 +194,13 @@ // Gets the entity for the given storage key, or null if there isn't one. ProcessorEntityTracker* GetEntityForStorageKey( const std::string& storage_key); + const ProcessorEntityTracker* GetEntityForStorageKey( + const std::string& storage_key) const; // Gets the entity for the given tag hash, or null if there isn't one. ProcessorEntityTracker* GetEntityForTagHash(const std::string& tag_hash); + const ProcessorEntityTracker* GetEntityForTagHash( + const std::string& tag_hash) const; // Create an entity in the entity map for |storage_key| and return a pointer // to it.
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc index e081e869..ae7939b 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
@@ -15,6 +15,7 @@ #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_task_environment.h" +#include "base/threading/platform_thread.h" #include "components/sync/base/model_type.h" #include "components/sync/base/storage_option.h" #include "components/sync/base/time.h" @@ -695,10 +696,16 @@ // Thoroughly tests the data generated by a local item creation. TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldCommitLocalCreation) { InitializeToReadyState(); - EXPECT_EQ(0U, worker()->GetNumPendingCommits()); + ASSERT_EQ(0U, worker()->GetNumPendingCommits()); + ASSERT_FALSE(type_processor()->IsEntityUnsynced(kKey1)); bridge()->WriteItem(kKey1, kValue1); + EXPECT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); + EXPECT_FALSE(type_processor()->GetEntityCreationTime(kKey1).is_null()); + EXPECT_EQ(type_processor()->GetEntityCreationTime(kKey1), + type_processor()->GetEntityModificationTime(kKey1)); + // Verify the commit request this operation has triggered. worker()->VerifyPendingCommits({{kHash1}}); const CommitRequestData& tag1_request_data = @@ -727,6 +734,7 @@ EXPECT_TRUE(metadata.has_specifics_hash()); worker()->AckOnePendingCommit(); + EXPECT_FALSE(type_processor()->IsEntityUnsynced(kKey1)); EXPECT_EQ(1U, db().metadata_count()); const EntityMetadata acked_metadata = db().GetMetadata(kKey1); EXPECT_TRUE(acked_metadata.has_server_id()); @@ -807,7 +815,7 @@ EXPECT_NE(metadata_v1.specifics_hash(), metadata_v2.specifics_hash()); } -// Creates a new local item then modifies it. +// Creates a new local item, then modifies it after it has been acked. // Thoroughly tests data generated by modification of server-unknown item. TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldCommitLocalUpdate) { InitializeToReadyState(); @@ -821,10 +829,94 @@ const EntityData& data_v1 = request_data_v1.entity.value(); const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); + worker()->AckOnePendingCommit(); + ASSERT_FALSE(type_processor()->IsEntityUnsynced(kKey1)); + const base::Time ctime = type_processor()->GetEntityCreationTime(kKey1); + ASSERT_FALSE(ctime.is_null()); + ASSERT_EQ(ctime, type_processor()->GetEntityModificationTime(kKey1)); + + // Make sure the clock advances. + base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); + ASSERT_NE(ctime, base::Time::Now()); + + bridge()->WriteItem(kKey1, kValue2); + EXPECT_EQ(1U, db().metadata_count()); + worker()->VerifyPendingCommits({{kHash1}}); + + EXPECT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); + EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); + const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); + EXPECT_NE(ctime, mtime); + + const CommitRequestData& request_data_v2 = + worker()->GetLatestPendingCommitForHash(kHash1); + const EntityData& data_v2 = request_data_v2.entity.value(); + const EntityMetadata metadata_v2 = db().GetMetadata(kKey1); + + // Test some of the relations between old and new commit requests. + EXPECT_GT(request_data_v2.sequence_number, request_data_v1.sequence_number); + EXPECT_EQ(data_v1.specifics.preference().value(), kValue1); + + // Perform a thorough examination of the update-generated request. + EXPECT_NE(kUncommittedVersion, request_data_v2.base_version); + EXPECT_FALSE(data_v2.id.empty()); + EXPECT_EQ(ctime, data_v2.creation_time); + EXPECT_EQ(mtime, data_v2.modification_time); + EXPECT_EQ(kKey1, data_v2.non_unique_name); + EXPECT_FALSE(data_v2.is_deleted()); + EXPECT_EQ(kKey1, data_v2.specifics.preference().name()); + EXPECT_EQ(kValue2, data_v2.specifics.preference().value()); + + // Perform a thorough examination of the local sync metadata. + EXPECT_FALSE(metadata_v1.has_server_id()); + EXPECT_FALSE(metadata_v1.is_deleted()); + EXPECT_EQ(1, metadata_v1.sequence_number()); + EXPECT_EQ(0, metadata_v1.acked_sequence_number()); + EXPECT_EQ(kUncommittedVersion, metadata_v1.server_version()); + + EXPECT_FALSE(metadata_v2.server_id().empty()); + EXPECT_FALSE(metadata_v2.is_deleted()); + EXPECT_EQ(2, metadata_v2.sequence_number()); + EXPECT_EQ(1, metadata_v2.acked_sequence_number()); + EXPECT_NE(kUncommittedVersion, metadata_v2.server_version()); + + EXPECT_EQ(metadata_v1.client_tag_hash(), metadata_v2.client_tag_hash()); + EXPECT_NE(metadata_v1.specifics_hash(), metadata_v2.specifics_hash()); +} + +// Same as above, but modifies the item BEFORE it has been acked. +// Thoroughly tests data generated by modification of server-unknown item. +TEST_F(ClientTagBasedModelTypeProcessorTest, + ShouldCommitLocalUpdateBeforeCreationAck) { + InitializeToReadyState(); + + bridge()->WriteItem(kKey1, kValue1); + ASSERT_EQ(1U, db().metadata_count()); + worker()->VerifyPendingCommits({{kHash1}}); + + const CommitRequestData& request_data_v1 = + worker()->GetLatestPendingCommitForHash(kHash1); + const EntityData& data_v1 = request_data_v1.entity.value(); + const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); + + ASSERT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); + const base::Time ctime = type_processor()->GetEntityCreationTime(kKey1); + ASSERT_EQ(ctime, type_processor()->GetEntityModificationTime(kKey1)); + ASSERT_FALSE(ctime.is_null()); + + // Make sure the clock advances. + base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); + ASSERT_NE(ctime, base::Time::Now()); + bridge()->WriteItem(kKey1, kValue2); EXPECT_EQ(1U, db().metadata_count()); worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); + EXPECT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); + EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); + const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); + EXPECT_NE(mtime, ctime); + const CommitRequestData& request_data_v2 = worker()->GetLatestPendingCommitForHash(kHash1); const EntityData& data_v2 = request_data_v2.entity.value(); @@ -837,13 +929,14 @@ // Perform a thorough examination of the update-generated request. EXPECT_EQ(kUncommittedVersion, request_data_v2.base_version); EXPECT_TRUE(data_v2.id.empty()); - EXPECT_FALSE(data_v2.creation_time.is_null()); - EXPECT_FALSE(data_v2.modification_time.is_null()); + EXPECT_EQ(ctime, data_v2.creation_time); + EXPECT_EQ(mtime, data_v2.modification_time); EXPECT_EQ(kKey1, data_v2.non_unique_name); EXPECT_FALSE(data_v2.is_deleted()); EXPECT_EQ(kKey1, data_v2.specifics.preference().name()); EXPECT_EQ(kValue2, data_v2.specifics.preference().value()); + // Perform a thorough examination of the local sync metadata. EXPECT_FALSE(metadata_v1.has_server_id()); EXPECT_FALSE(metadata_v1.is_deleted()); EXPECT_EQ(1, metadata_v1.sequence_number()); @@ -865,11 +958,19 @@ TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldIgnoreRedundantLocalUpdate) { InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); - EXPECT_EQ(1U, db().metadata_count()); + ASSERT_EQ(1U, db().metadata_count()); worker()->VerifyPendingCommits({{kHash1}}); + const base::Time ctime = type_processor()->GetEntityCreationTime(kKey1); + const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); + ASSERT_FALSE(ctime.is_null()); + ASSERT_FALSE(mtime.is_null()); + bridge()->WriteItem(kKey1, kValue1); worker()->VerifyPendingCommits({{kHash1}}); + + EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); + EXPECT_EQ(mtime, type_processor()->GetEntityModificationTime(kKey1)); } // Thoroughly tests the data generated by a server item creation.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 81ecaf42..d4a58e89 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -4,6 +4,7 @@ #include "components/viz/service/display_embedder/skia_output_surface_impl.h" +#include <memory> #include <utility> #include <vector> @@ -23,6 +24,7 @@ #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/service/scheduler.h" #include "gpu/command_buffer/service/shared_image_representation.h" +#include "gpu/ipc/command_buffer_task_executor.h" #include "third_party/skia/include/core/SkYUVAIndex.h" #include "ui/gfx/skia_util.h" #include "ui/gl/gl_bindings.h" @@ -45,6 +47,8 @@ base::RepeatingCallback<void(Args...)> CreateSafeCallback( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const base::RepeatingCallback<void(Args...)>& callback) { + if (!task_runner) + return callback; return base::BindRepeating(&PostAsyncTask<Args...>, task_runner, callback); } @@ -291,6 +295,20 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } +SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl( + scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor, + scoped_refptr<gl::GLSurface> gl_surface, + scoped_refptr<gpu::SharedContextState> shared_context_state) + : gpu_service_(nullptr), + task_executor_(std::move(task_executor)), + gl_surface_(std::move(gl_surface)), + shared_context_state_(std::move(shared_context_state)), + is_using_vulkan_(false), + surface_handle_(gpu::kNullSurfaceHandle), + synthetic_begin_frame_source_(nullptr), + show_overdraw_feedback_(false), + weak_ptr_factory_(this) {} + SkiaOutputSurfaceImpl::~SkiaOutputSurfaceImpl() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); recorder_.reset(); @@ -311,8 +329,12 @@ client_ = client; weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); - client_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - + if (task_executor_) { + DCHECK(!sequence_); + sequence_ = task_executor_->CreateSequence(); + } else { + client_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + } base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); auto callback = base::BindOnce(&SkiaOutputSurfaceImpl::InitializeOnGpuThread, @@ -572,12 +594,12 @@ callback = base::BindOnce( &SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass, base::Unretained(impl_on_gpu_.get()), current_render_pass_id_, - std::move(ddl), sync_fence_release_); + std::move(ddl), resource_sync_tokens_, sync_fence_release_); } else { - callback = - base::BindOnce(&SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame, - base::Unretained(impl_on_gpu_.get()), std::move(ddl), - std::move(overdraw_ddl), sync_fence_release_); + callback = base::BindOnce( + &SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame, + base::Unretained(impl_on_gpu_.get()), std::move(ddl), + std::move(overdraw_ddl), resource_sync_tokens_, sync_fence_release_); } ScheduleGpuTask(std::move(callback), std::move(resource_sync_tokens_)); current_render_pass_id_ = 0; @@ -637,20 +659,36 @@ } void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event) { - base::ScopedClosureRunner scoped_runner( - base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event))); + base::Optional<base::ScopedClosureRunner> scoped_runner; + if (event) { + scoped_runner.emplace( + base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event))); + } + auto did_swap_buffer_complete_callback = base::BindRepeating( &SkiaOutputSurfaceImpl::DidSwapBuffersComplete, weak_ptr_); + did_swap_buffer_complete_callback = CreateSafeCallback( + client_thread_task_runner_, did_swap_buffer_complete_callback); auto buffer_presented_callback = base::BindRepeating(&SkiaOutputSurfaceImpl::BufferPresented, weak_ptr_); + buffer_presented_callback = + CreateSafeCallback(client_thread_task_runner_, buffer_presented_callback); auto context_lost_callback = base::BindRepeating(&SkiaOutputSurfaceImpl::ContextLost, weak_ptr_); - impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>( - gpu_service_, surface_handle_, - CreateSafeCallback(client_thread_task_runner_, - did_swap_buffer_complete_callback), - CreateSafeCallback(client_thread_task_runner_, buffer_presented_callback), - CreateSafeCallback(client_thread_task_runner_, context_lost_callback)); + context_lost_callback = + CreateSafeCallback(client_thread_task_runner_, context_lost_callback); + + if (task_executor_) { + impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>( + task_executor_.get(), std::move(gl_surface_), + std::move(shared_context_state_), sequence_->GetSequenceId(), + did_swap_buffer_complete_callback, buffer_presented_callback, + context_lost_callback); + } else { + impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>( + gpu_service_, surface_handle_, did_swap_buffer_complete_callback, + buffer_presented_callback, context_lost_callback); + } capabilities_ = impl_on_gpu_->capabilities(); } @@ -734,9 +772,13 @@ void SkiaOutputSurfaceImpl::ScheduleGpuTask( base::OnceClosure callback, std::vector<gpu::SyncToken> sync_tokens) { - auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); - gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task( - sequence_id, std::move(callback), std::move(sync_tokens))); + if (gpu_service_) { + auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); + gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task( + sequence_id, std::move(callback), std::move(sync_tokens))); + } else { + sequence_->ScheduleTask(std::move(callback), std::move(sync_tokens)); + } } } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index cd7a199f..4476db3a 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -22,6 +22,15 @@ class WaitableEvent; } +namespace gl { +class GLSurface; +} + +namespace gpu { +class CommandBufferTaskExecutor; +class SharedContextState; +} // namespace gpu + namespace viz { class GpuServiceImpl; @@ -44,6 +53,10 @@ gpu::SurfaceHandle surface_handle, SyntheticBeginFrameSource* synthetic_begin_frame_source, bool show_overdraw_feedback); + SkiaOutputSurfaceImpl( + scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor, + scoped_refptr<gl::GLSurface> gl_surface, + scoped_refptr<gpu::SharedContextState> shared_context_state); ~SkiaOutputSurfaceImpl() override; // OutputSurface implementation: @@ -121,7 +134,15 @@ std::vector<gpu::SyncToken> sync_tokens); uint64_t sync_fence_release_ = 0; + GpuServiceImpl* const gpu_service_; + + // Stuffs for running with |task_executor_| instead of |gpu_service_|. + scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor_; + scoped_refptr<gl::GLSurface> gl_surface_; + scoped_refptr<gpu::SharedContextState> shared_context_state_; + std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence> sequence_; + const bool is_using_vulkan_; const gpu::SurfaceHandle surface_handle_; SyntheticBeginFrameSource* const synthetic_begin_frame_source_;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index aa67edf7..4fdb435 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -24,6 +24,7 @@ #include "gpu/command_buffer/service/texture_base.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/config/gpu_preferences.h" +#include "gpu/ipc/command_buffer_task_executor.h" #include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/ipc/service/image_transport_surface.h" @@ -76,6 +77,14 @@ channel_manager->gpu_feature_info()); } +scoped_refptr<gpu::gles2::FeatureInfo> CreateFeatureInfo( + gpu::CommandBufferTaskExecutor* task_executor) { + return base::MakeRefCounted<gpu::gles2::FeatureInfo>( + gpu::GpuDriverBugWorkarounds( + task_executor->gpu_feature_info().enabled_gpu_driver_bug_workarounds), + task_executor->gpu_feature_info()); +} + scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState( GpuServiceImpl* gpu_service) { auto command_buffer_id = gpu::CommandBufferId::FromUnsafeValue( @@ -85,6 +94,16 @@ gpu_service->skia_output_surface_sequence_id()); } +scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState( + gpu::CommandBufferTaskExecutor* task_executor, + gpu::SequenceId sequence_id) { + auto command_buffer_id = gpu::CommandBufferId::FromUnsafeValue( + g_next_command_buffer_id.GetNext() + 1); + return task_executor->sync_point_manager()->CreateSyncPointClientState( + gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, command_buffer_id, + sequence_id); +} + std::unique_ptr<gpu::SharedImageRepresentationFactory> CreateSharedImageRepresentationFactory(GpuServiceImpl* gpu_service) { // TODO(https://crbug.com/899905): Use a real MemoryTracker, not nullptr. @@ -92,6 +111,12 @@ gpu_service->shared_image_manager(), nullptr); } +std::unique_ptr<gpu::SharedImageRepresentationFactory> +CreateSharedImageRepresentationFactory( + gpu::CommandBufferTaskExecutor* task_executor) { + return nullptr; +} + } // namespace SkiaOutputSurfaceImplOnGpu::OffscreenSurface::OffscreenSurface() = default; @@ -136,12 +161,6 @@ weak_ptr_factory_(this) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); - -#if defined(USE_OZONE) - window_surface_ = ui::OzonePlatform::GetInstance() - ->GetSurfaceFactoryOzone() - ->CreatePlatformWindowSurface(surface_handle); -#endif } SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu( @@ -161,10 +180,41 @@ did_swap_buffer_complete_callback, buffer_presented_callback, context_lost_callback) { +#if defined(USE_OZONE) + window_surface_ = ui::OzonePlatform::GetInstance() + ->GetSurfaceFactoryOzone() + ->CreatePlatformWindowSurface(surface_handle); +#endif + if (is_using_vulkan()) InitializeForVulkan(gpu_service); else - InitializeForGL(gpu_service); + InitializeForGLWithGpuService(gpu_service); +} + +SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu( + gpu::CommandBufferTaskExecutor* task_executor, + scoped_refptr<gl::GLSurface> gl_surface, + scoped_refptr<gpu::SharedContextState> shared_context_state, + gpu::SequenceId sequence_id, + const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback, + const BufferPresentedCallback& buffer_presented_callback, + const ContextLostCallback& context_lost_callback) + : SkiaOutputSurfaceImplOnGpu( + gpu::kNullSurfaceHandle, + CreateFeatureInfo(task_executor), + task_executor->mailbox_manager(), + CreateSyncPointClientState(task_executor, sequence_id), + CreateSharedImageRepresentationFactory(task_executor), + nullptr /* gr_shader_cache */, + nullptr /* vulkan_context_provider */, + did_swap_buffer_complete_callback, + buffer_presented_callback, + context_lost_callback) { + DCHECK(!is_using_vulkan()); + gl_surface_ = std::move(gl_surface); + context_state_ = std::move(shared_context_state); + InitializeForGL(); } SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() { @@ -197,6 +247,8 @@ if (!is_using_vulkan()) { if (!MakeCurrent()) return; + size_ = size; + color_space_ = color_space; // Conversion to GLSurface's color space follows the same logic as in // gl::GetGLColorSpace(). gl::GLSurface::ColorSpace surface_color_space = @@ -208,26 +260,7 @@ // TODO(penghuang): Handle the failure. } DCHECK(gr_context()); - - SkSurfaceProps surface_props = - SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType); - - GrGLFramebufferInfo framebuffer_info; - framebuffer_info.fFBOID = 0; - if (supports_alpha_) { - framebuffer_info.fFormat = - gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8; - } else { - framebuffer_info.fFormat = GL_RGB8_OES; - } - - GrBackendRenderTarget render_target(size.width(), size.height(), 0, 8, - framebuffer_info); - - sk_surface_ = SkSurface::MakeFromBackendRenderTarget( - gr_context(), render_target, kBottomLeft_GrSurfaceOrigin, - FramebufferColorType(), color_space.ToSkColorSpace(), &surface_props); - DCHECK(sk_surface_); + CreateSkSurfaceForGL(); } else { #if BUILDFLAG(ENABLE_VULKAN) gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget; @@ -273,6 +306,7 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame( std::unique_ptr<SkDeferredDisplayList> ddl, std::unique_ptr<SkDeferredDisplayList> overdraw_ddl, + std::vector<gpu::SyncToken> sync_tokens, uint64_t sync_fence_release) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(ddl); @@ -281,11 +315,16 @@ if (!MakeCurrent()) return; + PullTextureUpdates(std::move(sync_tokens)); + { base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use; if (gr_shader_cache_) { cache_use.emplace(gr_shader_cache_, gpu::kInProcessCommandBufferClientId); } + if (backing_framebuffer_object_ != + gl_surface_->GetBackingFramebufferObject()) + CreateSkSurfaceForGL(); sk_surface_->draw(ddl.get()); gr_context()->flush(); } @@ -293,7 +332,7 @@ // Note that the ScopedCacheUse for GrShaderCache is scoped until the // ReleaseFenceSync call here since releasing the fence may schedule a // different decoder's stream which also uses the shader cache. - sync_point_client_state_->ReleaseFenceSync(sync_fence_release); + ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); if (overdraw_ddl) { base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use; @@ -367,6 +406,7 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass( RenderPassId id, std::unique_ptr<SkDeferredDisplayList> ddl, + std::vector<gpu::SyncToken> sync_tokens, uint64_t sync_fence_release) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(ddl); @@ -374,6 +414,8 @@ if (!MakeCurrent()) return; + PullTextureUpdates(std::move(sync_tokens)); + auto& surface = offscreen_surfaces_[id].surface; SkSurfaceCharacterization characterization; // TODO(penghuang): Using characterization != ddl->characterization(), when @@ -391,7 +433,7 @@ surface->draw(ddl.get()); gr_context()->flush(); } - sync_point_client_state_->ReleaseFenceSync(sync_fence_release); + ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); } void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource( @@ -478,7 +520,11 @@ const ResourceFormat resource_format, std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!*shared_image_out && mailbox_holder.mailbox.IsSharedImage()) { + + if (!shared_image_representation_factory_) { + // TODO(https://crbug.com/900973): support shared image for Android + // WebView. + } else if (!*shared_image_out && mailbox_holder.mailbox.IsSharedImage()) { std::unique_ptr<gpu::SharedImageRepresentationSkia> shared_image = shared_image_representation_factory_->ProduceSkia( mailbox_holder.mailbox); @@ -554,7 +600,7 @@ uint64_t sync_fence_release) { MakeCurrent(); images.clear(); - sync_point_client_state_->ReleaseFenceSync(sync_fence_release); + ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); } #if defined(OS_WIN) @@ -604,26 +650,7 @@ return 0; } -void SkiaOutputSurfaceImplOnGpu::InitializeForGL(GpuServiceImpl* gpu_service) { - if (surface_handle_) { - gl_surface_ = gpu::ImageTransportSurface::CreateNativeSurface( - weak_ptr_factory_.GetWeakPtr(), surface_handle_, gl::GLSurfaceFormat()); - } else { - // surface_ could be null for pixel tests. Use FakeOnScreenSurface so that - // virtual contexts always render to the surface. - scoped_refptr<gl::GLSurface> offscreen_surface = - gl::init::CreateOffscreenGLSurface(gfx::Size(1, 1)); - gl_surface_ = - base::MakeRefCounted<FakeOnScreenSurface>(offscreen_surface.get()); - } - DCHECK(gl_surface_); - - context_state_ = gpu_service->GetContextStateForGLSurface(gl_surface_.get()); - if (!context_state_) { - LOG(FATAL) << "Failed to create GrContext"; - // TODO(penghuang): handle the failure. - } - +void SkiaOutputSurfaceImplOnGpu::InitializeForGL() { if (!MakeCurrent()) return; @@ -656,6 +683,29 @@ supports_alpha_ = alpha_bits > 0; } +void SkiaOutputSurfaceImplOnGpu::InitializeForGLWithGpuService( + GpuServiceImpl* gpu_service) { + if (surface_handle_) { + gl_surface_ = gpu::ImageTransportSurface::CreateNativeSurface( + weak_ptr_factory_.GetWeakPtr(), surface_handle_, gl::GLSurfaceFormat()); + } else { + // surface_ could be null for pixel tests. Use FakeOnScreenSurface so that + // virtual contexts always render to the surface. + scoped_refptr<gl::GLSurface> offscreen_surface = + gl::init::CreateOffscreenGLSurface(gfx::Size(1, 1)); + gl_surface_ = + base::MakeRefCounted<FakeOnScreenSurface>(offscreen_surface.get()); + } + DCHECK(gl_surface_); + + context_state_ = gpu_service->GetContextStateForGLSurface(gl_surface_.get()); + if (!context_state_) { + LOG(FATAL) << "Failed to create GrContext"; + // TODO(penghuang): handle the failure. + } + InitializeForGL(); +} + void SkiaOutputSurfaceImplOnGpu::InitializeForVulkan( GpuServiceImpl* gpu_service) { context_state_ = gpu_service->GetContextStateForVulkan(); @@ -696,6 +746,29 @@ pending_swap_completed_params_.emplace_back(swap_id, pixel_size); } +void SkiaOutputSurfaceImplOnGpu::CreateSkSurfaceForGL() { + SkSurfaceProps surface_props = + SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType); + + GrGLFramebufferInfo framebuffer_info; + backing_framebuffer_object_ = gl_surface_->GetBackingFramebufferObject(); + framebuffer_info.fFBOID = backing_framebuffer_object_; + if (supports_alpha_) { + framebuffer_info.fFormat = + gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8; + } else { + framebuffer_info.fFormat = GL_RGB8_OES; + } + + GrBackendRenderTarget render_target(size_.width(), size_.height(), 0, 8, + framebuffer_info); + + sk_surface_ = SkSurface::MakeFromBackendRenderTarget( + gr_context(), render_target, kBottomLeft_GrSurfaceOrigin, + FramebufferColorType(), color_space_.ToSkColorSpace(), &surface_props); + DCHECK(sk_surface_); +} + void SkiaOutputSurfaceImplOnGpu::CreateSkSurfaceForVulkan() { #if BUILDFLAG(ENABLE_VULKAN) auto* swap_chain = vulkan_surface_->GetSwapChain(); @@ -742,4 +815,32 @@ return true; } +void SkiaOutputSurfaceImplOnGpu::PullTextureUpdates( + std::vector<gpu::SyncToken> sync_tokens) { + if (mailbox_manager_->UsesSync()) { + for (auto& sync_token : sync_tokens) + mailbox_manager_->PullTextureUpdates(sync_token); + } +} + +void SkiaOutputSurfaceImplOnGpu::ReleaseFenceSyncAndPushTextureUpdates( + uint64_t sync_fence_release) { + if (mailbox_manager_->UsesSync()) { + // If MailboxManagerSync is used, we are sharing textures between threads. + // In this case, sync point can only guarantee GL commands are issued in + // correct order across threads and GL contexts. However GPU driver may + // execute GL commands out of the issuing order across GL contexts. So we + // have to use PushTextureUpdates() and PullTextureUpdates() to ensure the + // correct GL commands executing order. + // PushTextureUpdates(token) will insert a GL fence into the current GL + // context, PullTextureUpdates(token) will wait the GL fence associated with + // the give token on the current GL context. + // Reconstruct sync_token from sync_fence_release. + gpu::SyncToken sync_token(gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, + command_buffer_id(), sync_fence_release); + mailbox_manager_->PushTextureUpdates(sync_token); + } + sync_point_client_state_->ReleaseFenceSync(sync_fence_release); +} + } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 50c9521..e4c85ba 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -43,6 +43,7 @@ } namespace gpu { +class CommandBufferTaskExecutor; class SyncPointClientState; class SharedImageRepresentationSkia; @@ -89,6 +90,15 @@ const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback, const BufferPresentedCallback& buffer_presented_callback, const ContextLostCallback& context_lost_callback); + SkiaOutputSurfaceImplOnGpu( + gpu::CommandBufferTaskExecutor* task_executor, + scoped_refptr<gl::GLSurface> gl_surface, + scoped_refptr<gpu::SharedContextState> shared_context_state, + gpu::SequenceId sequence_id, + const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback, + const BufferPresentedCallback& buffer_presented_callback, + const ContextLostCallback& context_lost_callback); + ~SkiaOutputSurfaceImplOnGpu() override; gpu::CommandBufferId command_buffer_id() const { @@ -111,12 +121,13 @@ void FinishPaintCurrentFrame( std::unique_ptr<SkDeferredDisplayList> ddl, std::unique_ptr<SkDeferredDisplayList> overdraw_ddl, + std::vector<gpu::SyncToken> sync_tokens, uint64_t sync_fence_release); void SwapBuffers(OutputSurfaceFrame frame); - void FinishPaintRenderPass( - RenderPassId id, - std::unique_ptr<SkDeferredDisplayList> ddl, - uint64_t sync_fence_release); + void FinishPaintRenderPass(RenderPassId id, + std::unique_ptr<SkDeferredDisplayList> ddl, + std::vector<gpu::SyncToken> sync_tokens, + uint64_t sync_fence_release); void RemoveRenderPassResource(std::vector<RenderPassId> ids); void CopyOutput(RenderPassId id, const gfx::Rect& copy_rect, @@ -159,7 +170,11 @@ void AddFilter(IPC::MessageFilter* message_filter) override; int32_t GetRouteID() const override; - void InitializeForGL(GpuServiceImpl* gpu_service); + void InitializeForGL(); + void InitializeForGLWithGpuService(GpuServiceImpl* gpu_service); + void InitializeForGLWithTaskExecutor( + gpu::CommandBufferTaskExecutor* task_executor, + scoped_refptr<gl::GLSurface> gl_surface); void InitializeForVulkan(GpuServiceImpl* gpu_service); void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base); @@ -167,12 +182,17 @@ // Generage the next swap ID and push it to our pending swap ID queues. void OnSwapBuffers(); + void CreateSkSurfaceForGL(); void CreateSkSurfaceForVulkan(); // Make context current for GL, and return false if the context is lost. // It will do nothing when Vulkan is used. bool MakeCurrent(); + void PullTextureUpdates(std::vector<gpu::SyncToken> sync_token); + + void ReleaseFenceSyncAndPushTextureUpdates(uint64_t sync_fence_release); + GrContext* gr_context() { return context_state_->gr_context(); } SkColorType FramebufferColorType() { @@ -199,7 +219,10 @@ #endif gpu::GpuPreferences gpu_preferences_; + gfx::Size size_; + gfx::ColorSpace color_space_; scoped_refptr<gl::GLSurface> gl_surface_; + unsigned int backing_framebuffer_object_ = 0; sk_sp<SkSurface> sk_surface_; scoped_refptr<gpu::SharedContextState> context_state_; const gl::GLVersionInfo* gl_version_info_ = nullptr;
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc index 3c0ec0d..f52e203 100644 --- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc +++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -270,7 +270,7 @@ } void Match(blink::mojom::FetchAPIRequestPtr request, - blink::mojom::QueryParamsPtr match_params, + blink::mojom::MultiQueryParamsPtr match_params, blink::mojom::CacheStorage::MatchCallback callback) override { content::CacheStorage* cache_storage = GetOrCreateCacheStorage(); if (!cache_storage) { @@ -295,13 +295,15 @@ std::move(callback)); if (!match_params->cache_name) { - cache_storage->MatchAllCaches(std::move(request), std::move(match_params), + cache_storage->MatchAllCaches(std::move(request), + std::move(match_params->query_params), std::move(on_match)); return; } std::string cache_name = base::UTF16ToUTF8(*match_params->cache_name); cache_storage->MatchCache(std::move(cache_name), std::move(request), - std::move(match_params), std::move(on_match)); + std::move(match_params->query_params), + std::move(on_match)); } void Open(const base::string16& cache_name,
diff --git a/content/browser/contacts/contacts_manager_impl.cc b/content/browser/contacts/contacts_manager_impl.cc index 7170bb3..f830af86 100644 --- a/content/browser/contacts/contacts_manager_impl.cc +++ b/content/browser/contacts/contacts_manager_impl.cc
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "build/build_config.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "mojo/public/cpp/bindings/strong_binding.h" #if defined(OS_ANDROID) @@ -22,6 +23,8 @@ std::unique_ptr<ContactsProvider> CreateProvider( RenderFrameHostImpl* render_frame_host) { + if (render_frame_host->GetParent()) + return nullptr; // This API is only supported on the main frame. #if defined(OS_ANDROID) return std::make_unique<ContactsProviderAndroid>(render_frame_host); #else
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index 3155764..bb83f83e 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -264,8 +264,8 @@ } touch_event_ack_queue_->UpdateQueueAfterTargetDestroyed(view); - if (view == wheel_target_.target) - wheel_target_.target = nullptr; + if (view == wheel_target_) + wheel_target_ = nullptr; // If the target that's being destroyed is in the gesture target map, we // replace it with nullptr so that we maintain the 1:1 correspondence between @@ -281,8 +281,8 @@ if (view == touchscreen_gesture_target_.target) touchscreen_gesture_target_.target = nullptr; - if (view == touchpad_gesture_target_.target) - touchpad_gesture_target_.target = nullptr; + if (view == touchpad_gesture_target_) + touchpad_gesture_target_ = nullptr; if (view == bubbling_gesture_scroll_target_) { bubbling_gesture_scroll_target_ = nullptr; @@ -586,20 +586,13 @@ const blink::WebMouseWheelEvent& mouse_wheel_event, const ui::LatencyInfo& latency, const base::Optional<gfx::PointF>& target_location) { - base::Optional<gfx::PointF> point_in_target = target_location; if (!root_view->IsMouseLocked()) { if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseBegan) { - wheel_target_.target = target; - if (target_location.has_value()) { - wheel_target_.delta = - target_location.value() - mouse_wheel_event.PositionInWidget(); - } + wheel_target_ = target; } else { - if (wheel_target_.target) { - DCHECK(!target && !target_location.has_value()); - target = wheel_target_.target; - point_in_target.emplace(mouse_wheel_event.PositionInWidget() + - wheel_target_.delta); + if (wheel_target_) { + DCHECK(!target); + target = wheel_target_; } else if ((mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded || mouse_wheel_event.momentum_phase == @@ -618,21 +611,22 @@ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); return; } - // If target_location doesn't have a value, it can be for two reasons: - // 1. |target| is null, in which case we would have early returned from the - // check above. - // 2. The event we are receiving is not a phaseBegan, in which case we should - // have got a valid |point_in_target| from wheel_target_.delta above. - DCHECK(point_in_target.has_value()); blink::WebMouseWheelEvent event = mouse_wheel_event; - event.SetPositionInWidget(point_in_target->x(), point_in_target->y()); + gfx::PointF point_in_target; + if (target_location) { + point_in_target = target_location.value(); + } else { + point_in_target = target->TransformRootPointToViewCoordSpace( + mouse_wheel_event.PositionInWidget()); + } + event.SetPositionInWidget(point_in_target.x(), point_in_target.y()); target->ProcessMouseWheelEvent(event, latency); if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded || mouse_wheel_event.momentum_phase == blink::WebMouseWheelEvent::kPhaseEnded) { - wheel_target_.target = nullptr; + wheel_target_ = nullptr; } } @@ -1023,7 +1017,7 @@ // should inform the child view, so that it does not go on to send us // the updates. See https://crbug.com/828422 if (target_view == touchscreen_gesture_target_.target || - target_view == touchpad_gesture_target_.target || + target_view == touchpad_gesture_target_ || target_view == touch_target_.target) { return; } @@ -1524,12 +1518,14 @@ // of routing. if (touchpad_gesture_event.GetType() == blink::WebInputEvent::kGestureFlingStart) { - if (wheel_target_.target) { + if (wheel_target_) { blink::WebGestureEvent gesture_fling = touchpad_gesture_event; - gesture_fling.SetPositionInWidget(gesture_fling.PositionInWidget() + - wheel_target_.delta); - wheel_target_.target->ProcessGestureEvent(gesture_fling, latency); - last_fling_start_target_ = wheel_target_.target; + gfx::PointF point_in_target = + wheel_target_->TransformRootPointToViewCoordSpace( + gesture_fling.PositionInWidget()); + gesture_fling.SetPositionInWidget(point_in_target); + wheel_target_->ProcessGestureEvent(gesture_fling, latency); + last_fling_start_target_ = wheel_target_; } else { root_view->GestureEventAck(touchpad_gesture_event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); @@ -1552,37 +1548,35 @@ } if (target) { - touchpad_gesture_target_.target = target; - // TODO(mohsen): Instead of just computing a delta, we should extract the - // complete transform. We assume it doesn't change for the duration of the - // touchpad gesture sequence, though this could be wrong; a better approach - // might be to always transform each point to the - // |touchpad_gesture_target_.target| for the duration of the sequence. - DCHECK(target_location.has_value()); - touchpad_gesture_target_.delta = - target_location.value() - touchpad_gesture_event.PositionInWidget(); + touchpad_gesture_target_ = target; // Abort any scroll bubbling in progress to avoid double entry. - CancelScrollBubblingIfConflicting(touchpad_gesture_target_.target); + CancelScrollBubblingIfConflicting(touchpad_gesture_target_); } - if (!touchpad_gesture_target_.target) { + if (!touchpad_gesture_target_) { root_view->GestureEventAck(touchpad_gesture_event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); return; } blink::WebGestureEvent gesture_event = touchpad_gesture_event; - // TODO(mohsen): Add tests to check event location. - gesture_event.SetPositionInWidget(gesture_event.PositionInWidget() + - touchpad_gesture_target_.delta); - touchpad_gesture_target_.target->ProcessGestureEvent(gesture_event, latency); + gfx::PointF point_in_target; + if (target_location) { + point_in_target = target_location.value(); + } else { + point_in_target = + touchpad_gesture_target_->TransformRootPointToViewCoordSpace( + gesture_event.PositionInWidget()); + } + gesture_event.SetPositionInWidget(point_in_target); + touchpad_gesture_target_->ProcessGestureEvent(gesture_event, latency); if (touchpad_gesture_event.GetType() == blink::WebInputEvent::kGesturePinchEnd || touchpad_gesture_event.GetType() == blink::WebInputEvent::kGestureDoubleTap) { - touchpad_gesture_target_.target = nullptr; + touchpad_gesture_target_ = nullptr; } }
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h index 9065d43..9774213 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.h +++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -189,7 +189,6 @@ viz::FrameSinkIdHash>; struct TargetData { RenderWidgetHostViewBase* target; - gfx::Vector2dF delta; gfx::Transform transform; TargetData() : target(nullptr) {} @@ -331,11 +330,11 @@ // The following variable is temporary, for diagnosis of // https://crbug.com/824774. bool touchscreen_gesture_target_in_map_; - TargetData touchpad_gesture_target_; + RenderWidgetHostViewBase* touchpad_gesture_target_ = nullptr; RenderWidgetHostViewBase* bubbling_gesture_scroll_target_ = nullptr; RenderWidgetHostViewChildFrame* bubbling_gesture_scroll_origin_ = nullptr; // Used to target wheel events for the duration of a scroll. - TargetData wheel_target_; + RenderWidgetHostViewBase* wheel_target_ = nullptr; // Maintains the same target between mouse down and mouse up. TargetData mouse_capture_target_;
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc index 896a724..5480595a 100644 --- a/content/browser/service_worker/embedded_worker_registry.cc +++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -78,14 +78,6 @@ return found->second; } -bool EmbeddedWorkerRegistry::CanHandle(int embedded_worker_id) const { - if (embedded_worker_id < initial_embedded_worker_id_ || - next_embedded_worker_id_ <= embedded_worker_id) { - return false; - } - return true; -} - EmbeddedWorkerRegistry::EmbeddedWorkerRegistry( const base::WeakPtr<ServiceWorkerContextCore>& context, int initial_embedded_worker_id)
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h index 8aa97437..5d429fe 100644 --- a/content/browser/service_worker/embedded_worker_registry.h +++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -61,9 +61,6 @@ // Returns an embedded worker instance for given |embedded_worker_id|. EmbeddedWorkerInstance* GetWorker(int embedded_worker_id); - // Returns true if |embedded_worker_id| is managed by this registry. - bool CanHandle(int embedded_worker_id) const; - private: friend class base::RefCounted<EmbeddedWorkerRegistry>; friend class MojoEmbeddedWorkerInstanceTest;
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 46c93d2f..9df3997 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -3539,7 +3539,7 @@ SendMouseWheel(pos); waiter.Wait(); - EXPECT_EQ(child_rwhv, router->wheel_target_.target); + EXPECT_EQ(child_rwhv, router->wheel_target_); // Send a mouse wheel event to the main frame. It will be still routed to // child till the end of current scrolling sequence. Since wheel scroll @@ -3547,7 +3547,7 @@ // InputEventAckWaiter is not needed here. TestInputEventObserver child_frame_monitor(child_rwhv->GetRenderWidgetHost()); SendMouseWheel(pos); - EXPECT_EQ(child_rwhv, router->wheel_target_.target); + EXPECT_EQ(child_rwhv, router->wheel_target_); // Verify that this a mouse wheel event was sent to the child frame renderer. EXPECT_TRUE(child_frame_monitor.EventWasReceived()); @@ -3561,7 +3561,133 @@ child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); child_process->Shutdown(0); crash_observer.Wait(); - EXPECT_EQ(nullptr, router->wheel_target_.target); + EXPECT_EQ(nullptr, router->wheel_target_); +} + +// Ensure that the positions of mouse wheel events sent to cross-process +// subframes account for any change in the position of the subframe during the +// scroll sequence. +IN_PROC_BROWSER_TEST_P(SitePerProcessMouseWheelHitTestBrowserTest, + MouseWheelEventPositionChange) { + GURL main_url(embedded_test_server()->GetURL( + "/frame_tree/page_with_tall_positioned_frame.html")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + auto* rwhv_root = static_cast<RenderWidgetHostViewAura*>( + web_contents()->GetRenderWidgetHostView()); + set_rwhv_root(rwhv_root); + + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + ASSERT_EQ(1U, root->child_count()); + + // Synchronize with the child and parent renderers to guarantee that the + // surface information required for event hit testing is ready. + RenderWidgetHostViewChildFrame* child_rwhv = + static_cast<RenderWidgetHostViewChildFrame*>( + root->child_at(0)->current_frame_host()->GetView()); + WaitForHitTestDataOrChildSurfaceReady( + root->child_at(0)->current_frame_host()); + + RenderWidgetHostInputEventRouter* router = + web_contents()->GetInputEventRouter(); + + auto await_gesture_event_with_position = base::BindRepeating( + [](blink::WebInputEvent::Type expected_type, + RenderWidgetHostViewBase* rwhv, gfx::PointF expected_position, + gfx::PointF expected_position_in_root, InputEventAckSource, + InputEventAckState, const blink::WebInputEvent& event) { + if (event.GetType() != expected_type) + return false; + + const auto& gesture_event = + static_cast<const blink::WebGestureEvent&>(event); + const gfx::PointF root_point = rwhv->TransformPointToRootCoordSpaceF( + gesture_event.PositionInWidget()); + + EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().x, + expected_position.x()); + EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().y, + expected_position.y()); + EXPECT_FLOAT_EQ(root_point.x(), expected_position_in_root.x()); + EXPECT_FLOAT_EQ(root_point.y(), expected_position_in_root.y()); + return true; + }); + MainThreadFrameObserver thread_observer(rwhv_root->GetRenderWidgetHost()); + + // Send a mouse wheel begin event to child. + blink::WebMouseWheelEvent scroll_event( + blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers, + blink::WebInputEvent::GetStaticTimeStampForTests()); + gfx::Point child_point_in_root(90, 90); + SetWebEventPositions(&scroll_event, child_point_in_root, rwhv_root); + scroll_event.delta_x = 0.0f; + scroll_event.delta_y = -20.0f; + scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; + scroll_event.has_precise_scrolling_deltas = true; + + { + InputEventAckWaiter await_begin_in_child( + child_rwhv->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureScrollBegin, + child_rwhv, gfx::PointF(38, 38), + gfx::PointF(child_point_in_root))); + InputEventAckWaiter await_update_in_child( + child_rwhv->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureScrollUpdate, + child_rwhv, gfx::PointF(38, 38), + gfx::PointF(child_point_in_root))); + InputEventAckWaiter await_update_in_root( + rwhv_root->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureScrollUpdate, + rwhv_root, gfx::PointF(child_point_in_root), + gfx::PointF(child_point_in_root))); + router->RouteMouseWheelEvent(rwhv_root, &scroll_event, ui::LatencyInfo()); + await_begin_in_child.Wait(); + await_update_in_child.Wait(); + await_update_in_root.Wait(); + thread_observer.Wait(); + } + + // Send mouse wheel update event to child. + { + scroll_event.phase = blink::WebMouseWheelEvent::kPhaseChanged; + InputEventAckWaiter await_update_in_child( + child_rwhv->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureScrollUpdate, + child_rwhv, gfx::PointF(38, 58), + gfx::PointF(child_point_in_root))); + InputEventAckWaiter await_update_in_root( + rwhv_root->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureScrollUpdate, + rwhv_root, gfx::PointF(child_point_in_root), + gfx::PointF(child_point_in_root))); + router->RouteMouseWheelEvent(rwhv_root, &scroll_event, ui::LatencyInfo()); + await_update_in_child.Wait(); + await_update_in_root.Wait(); + thread_observer.Wait(); + } + +#if !defined(OS_WIN) + { + ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START, child_point_in_root, + ui::EventTimeForNow(), 0, 10, 0, 10, 0, 1); + UpdateEventRootLocation(&fling_start, rwhv_root); + + InputEventAckWaiter await_fling_start_in_child( + child_rwhv->GetRenderWidgetHost(), + base::BindRepeating(await_gesture_event_with_position, + blink::WebInputEvent::kGestureFlingStart, + child_rwhv, gfx::PointF(38, 78), + gfx::PointF(child_point_in_root))); + rwhv_root->OnScrollEvent(&fling_start); + await_fling_start_in_child.Wait(); + thread_observer.Wait(); + } +#endif } // Ensure that a cross-process subframe with a touch-handler can receive touch @@ -4186,7 +4312,7 @@ contents->GetRenderWidgetHostView()); RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter(); - EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target); + EXPECT_EQ(nullptr, router->touchpad_gesture_target_); // TODO(848050): If we send multiple touchpad pinch sequences to separate // views and the timing of the acks are such that the begin ack of the second @@ -4215,38 +4341,37 @@ gfx::Point child_center(150, 150); // Send touchpad pinch sequence to main-frame. - SendTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target, - rwhv_parent); + SendTouchpadPinchSequenceWithExpectedTarget(rwhv_parent, main_frame_point, + router->touchpad_gesture_target_, + rwhv_parent); wait_for_pinch_sequence_end.Run(); // Send touchpad pinch sequence to child. SendTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, child_center, router->touchpad_gesture_target_.target, - rwhv_child); + rwhv_parent, child_center, router->touchpad_gesture_target_, rwhv_child); wait_for_pinch_sequence_end.Run(); // Send another touchpad pinch sequence to main frame. - SendTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target, - rwhv_parent); + SendTouchpadPinchSequenceWithExpectedTarget(rwhv_parent, main_frame_point, + router->touchpad_gesture_target_, + rwhv_parent); #if !defined(OS_WIN) // Sending touchpad fling events is not supported on Windows. // Send touchpad fling sequence to main-frame. SendTouchpadFlingSequenceWithExpectedTarget( - rwhv_parent, main_frame_point, router->wheel_target_.target, rwhv_parent); + rwhv_parent, main_frame_point, router->wheel_target_, rwhv_parent); // Send touchpad fling sequence to child. SendTouchpadFlingSequenceWithExpectedTarget( - rwhv_parent, child_center, router->wheel_target_.target, rwhv_child); + rwhv_parent, child_center, router->wheel_target_, rwhv_child); // Send another touchpad fling sequence to main frame. SendTouchpadFlingSequenceWithExpectedTarget( - rwhv_parent, main_frame_point, router->wheel_target_.target, rwhv_parent); + rwhv_parent, main_frame_point, router->wheel_target_, rwhv_parent); #endif } @@ -4279,7 +4404,7 @@ contents->GetRenderWidgetHostView()); RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter(); - EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target); + EXPECT_EQ(nullptr, router->touchpad_gesture_target_); const float scale_factor = render_frame_submission_observer.LastRenderFrameMetadata() @@ -4288,9 +4413,9 @@ gfx::ToCeiledInt(100 * scale_factor)); content::TestPageScaleObserver scale_observer(shell()->web_contents()); - SendTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, point_in_child, router->touchpad_gesture_target_.target, - rwhv_child); + SendTouchpadPinchSequenceWithExpectedTarget(rwhv_parent, point_in_child, + router->touchpad_gesture_target_, + rwhv_child); // Ensure the child frame saw the wheel event. bool default_prevented = false;
diff --git a/content/browser/site_per_process_mac_browsertest.mm b/content/browser/site_per_process_mac_browsertest.mm index e9a246f..ade271b3 100644 --- a/content/browser/site_per_process_mac_browsertest.mm +++ b/content/browser/site_per_process_mac_browsertest.mm
@@ -313,20 +313,19 @@ contents->GetRenderWidgetHostView()); RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter(); - EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target); + EXPECT_EQ(nullptr, router->touchpad_gesture_target_); gfx::Point main_frame_point(25, 575); gfx::Point child_center(150, 450); // Send touchpad pinch sequence to main-frame. SendMacTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target, + rwhv_parent, main_frame_point, router->touchpad_gesture_target_, rwhv_parent); // Send touchpad pinch sequence to child. SendMacTouchpadPinchSequenceWithExpectedTarget( - rwhv_parent, child_center, router->touchpad_gesture_target_.target, - rwhv_child); + rwhv_parent, child_center, router->touchpad_gesture_target_, rwhv_child); } } // namespace content
diff --git a/content/browser/web_package/http_structured_header.cc b/content/browser/web_package/http_structured_header.cc index 2fafca72..cab233b 100644 --- a/content/browser/web_package/http_structured_header.cc +++ b/content/browser/web_package/http_structured_header.cc
@@ -4,7 +4,11 @@ #include "content/browser/web_package/http_structured_header.h" +#include <string> +#include <utility> + #include "base/base64.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" namespace content { @@ -12,78 +16,135 @@ namespace { -// This covers the characters allowed in Integers and Identifiers. -// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.5 -// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.8 -constexpr char kTokenChars[] = "0123456789abcdefghijklmnopqrstuvwxyz_-*/"; +#define DIGIT "0123456789" +#define LCALPHA "abcdefghijklmnopqrstuvwxyz" +#define UCALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.9 +constexpr char kTokenChars[] = DIGIT UCALPHA LCALPHA "_-.:%*/"; +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.1 +constexpr char kKeyChars[] = DIGIT LCALPHA "_-"; +#undef DIGIT +#undef LCALPHA +#undef UCALPHA -// Parser for (a subset of) Structured Headers defined in [SH]. -// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04 +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.8 +bool IsPrintableASCII(char c) { + return ' ' <= c && c <= '~'; // 0x20 (' ') to 0x7E ('~') +} + +// Parser for (a subset of) Structured Headers for HTTP defined in [SH]. +// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09 class StructuredHeaderParser { public: - explicit StructuredHeaderParser(const base::StringPiece& str) - : input_(str), failed_(false) {} + explicit StructuredHeaderParser(const base::StringPiece& str) : input_(str) { + // [SH] 4.2. Step 1. Discard any leading OWS from input_string. + SkipWhitespaces(); + } - // Callers should call this after ParseSomething(), to check if parser has + // Callers should call this after ReadSomething(), to check if parser has // consumed all the input successfully. - bool ParsedSuccessfully() const { return !failed_ && input_.empty(); } + bool FinishParsing() { + // [SH] 4.2 Step 7. Discard any leading OWS from input_string. + SkipWhitespaces(); + // [SH] 4.2 Step 8. If input_string is not empty, fail parsing. + return input_.empty(); + } - // Parses a Parameterised List ([SH] 4.3). - void ParseParameterisedList(std::vector<ParameterisedIdentifier>* values) { - values->push_back(ParameterisedIdentifier()); - ParseParameterisedIdentifier(&values->back()); - while (!failed_) { - SkipWhitespaces(); - if (!ConsumeChar(',')) - break; - SkipWhitespaces(); - values->push_back(ParameterisedIdentifier()); - ParseParameterisedIdentifier(&values->back()); + // Parses an Item ([SH] 4.2.7). + // Currently only limited types (non-negative integers, strings, tokens and + // byte sequences) are supported, and all types are returned as a string + // regardless of the item type. E.g. both 123 (number) and "123" (string) are + // returned as "123". + // TODO(ksakamoto): Add support for other types, and return a value with type + // info. + base::Optional<std::string> ReadItem() { + if (input_.empty()) { + DVLOG(1) << "ReadItem: unexpected EOF"; + return base::nullopt; + } + switch (input_.front()) { + case '"': + return ReadString(); + case '*': + return ReadByteSequence(); + default: + if (base::IsAsciiDigit(input_.front())) + return ReadNumber(); + else + return ReadToken(); } } - // Parses a Parameterised Identifier ([SH] 4.3.2). - void ParseParameterisedIdentifier(ParameterisedIdentifier* out) { - std::string identifier = ReadToken(); - if (identifier.empty()) { - DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '" - << input_.front() << "'"; - failed_ = true; - return; - } - out->identifier = identifier; - - while (!failed_) { + // Parses a Parameterised List ([SH] 4.2.5). + base::Optional<ParameterisedList> ReadParameterisedList() { + ParameterisedList items; + while (true) { + base::Optional<ParameterisedIdentifier> item = + ReadParameterisedIdentifier(); + if (!item) + return base::nullopt; + items.push_back(std::move(*item)); SkipWhitespaces(); - if (!ConsumeChar(';')) - break; + if (!ConsumeChar(',')) + return items; SkipWhitespaces(); - - std::string name = ReadToken(); - if (name.empty()) { - DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '" - << input_.front() << "'"; - failed_ = true; - return; - } - std::string value; - if (ConsumeChar('=')) - value = ReadItem(); - if (!out->params.insert(std::make_pair(name, value)).second) { - DVLOG(1) << "ParseParameterisedIdentifier: duplicated parameter: " - << name; - failed_ = true; - return; - } } } private: - void SkipWhitespaces() { - input_ = base::TrimWhitespaceASCII(input_, base::TRIM_LEADING); + // Parses a Parameterised Identifier ([SH] 4.2.6). + base::Optional<ParameterisedIdentifier> ReadParameterisedIdentifier() { + base::Optional<std::string> primary_identifier = ReadToken(); + if (!primary_identifier) + return base::nullopt; + + ParameterisedIdentifier::Parameters parameters; + + SkipWhitespaces(); + while (ConsumeChar(';')) { + SkipWhitespaces(); + + base::Optional<std::string> name = ReadKey(); + if (!name) + return base::nullopt; + + std::string value; + if (ConsumeChar('=')) { + auto item = ReadItem(); + if (!item) + return base::nullopt; + value = *item; + } + if (!parameters.insert(std::make_pair(*name, value)).second) { + DVLOG(1) << "ReadParameterisedIdentifier: duplicated parameter: " + << *name; + return base::nullopt; + } + SkipWhitespaces(); + } + return ParameterisedIdentifier(*primary_identifier, std::move(parameters)); } - std::string ReadToken() { + // Parses a Key ([SH] 4.2.2). + base::Optional<std::string> ReadKey() { + if (input_.empty() || !base::IsAsciiLower(input_.front())) { + LogParseError("ReadKey", "lcalpha"); + return base::nullopt; + } + size_t len = input_.find_first_not_of(kKeyChars); + if (len == base::StringPiece::npos) + len = input_.size(); + std::string key(input_.substr(0, len)); + input_.remove_prefix(len); + return key; + } + + // Parses a Token ([SH] 4.2.10). + base::Optional<std::string> ReadToken() { + if (input_.empty() || !base::IsAsciiAlpha(input_.front())) { + LogParseError("ReadToken", "ALPHA"); + return base::nullopt; + } size_t len = input_.find_first_not_of(kTokenChars); if (len == base::StringPiece::npos) len = input_.size(); @@ -92,6 +153,96 @@ return token; } + // Parses a Number ([SH] 4.2.8). + // Currently only supports non-negative integers. + base::Optional<std::string> ReadNumber() { + size_t i = 0; + for (; i < input_.size(); ++i) { + if (!base::IsAsciiDigit(input_[i])) + break; + } + if (i == 0) { + LogParseError("ReadNumber", "DIGIT"); + return base::nullopt; + } + std::string output_number_string(input_.substr(0, i)); + input_.remove_prefix(i); + + // Check if it fits in a 64-bit signed integer. + int64_t n; + if (!base::StringToInt64(output_number_string, &n)) + return base::nullopt; + return output_number_string; + } + + // Parses a String ([SH] 4.2.9). + base::Optional<std::string> ReadString() { + std::string s; + if (!ConsumeChar('"')) { + LogParseError("ReadString", "'\"'"); + return base::nullopt; + } + while (!ConsumeChar('"')) { + size_t i = 0; + for (; i < input_.size(); ++i) { + if (!IsPrintableASCII(input_[i])) { + DVLOG(1) << "ReadString: non printable-ASCII character"; + return base::nullopt; + } + if (input_[i] == '"' || input_[i] == '\\') + break; + } + if (i == input_.size()) { + DVLOG(1) << "ReadString: missing closing '\"'"; + return base::nullopt; + } + s.append(std::string(input_.substr(0, i))); + input_.remove_prefix(i); + if (ConsumeChar('\\')) { + if (input_.empty()) { + DVLOG(1) << "ReadString: backslash at string end"; + return base::nullopt; + } + if (input_[0] != '"' && input_[0] != '\\') { + DVLOG(1) << "ReadString: invalid escape"; + return base::nullopt; + } + s.push_back(input_.front()); + input_.remove_prefix(1); + } + } + return s; + } + + // Parses a Byte Sequence ([SH] 4.2.11). + base::Optional<std::string> ReadByteSequence() { + if (!ConsumeChar('*')) { + LogParseError("ReadByteSequence", "'*'"); + return base::nullopt; + } + size_t len = input_.find('*'); + if (len == base::StringPiece::npos) { + DVLOG(1) << "ReadByteSequence: missing closing '*'"; + return base::nullopt; + } + std::string base64(input_.substr(0, len)); + // Append the necessary padding characters. + base64.resize((base64.size() + 3) / 4 * 4, '='); + + std::string binary; + if (!base::Base64Decode(base64, &binary)) { + DVLOG(1) << "ReadByteSequence: failed to decode base64: " << base64; + return base::nullopt; + } + input_.remove_prefix(len); + ConsumeChar('*'); + return binary; + } + + void SkipWhitespaces() { + input_ = base::TrimWhitespaceASCII(input_, base::TRIM_LEADING); + } + bool ConsumeChar(char expected) { if (!input_.empty() && input_.front() == expected) { input_.remove_prefix(1); @@ -100,96 +251,39 @@ return false; } - // [SH] 4.7. Strings - std::string ReadString() { - std::string s; - if (!ConsumeChar('"')) { - DVLOG(1) << "ReadString: '\"' expected, got '" << input_.front() << "'"; - failed_ = true; - return s; - } - while (!ConsumeChar('"')) { - size_t len = input_.find_first_of("\"\\"); - if (len == base::StringPiece::npos) { - DVLOG(1) << "ReadString: missing closing '\"'"; - failed_ = true; - return s; - } - s.append(std::string(input_.substr(0, len))); - input_.remove_prefix(len); - if (ConsumeChar('\\')) { - if (input_.empty()) { - DVLOG(1) << "ReadString: backslash at string end"; - failed_ = true; - return s; - } - s.push_back(input_.front()); - input_.remove_prefix(1); - } - } - return s; - } - - // [SH] 4.9. Binary Content - std::string ReadBinary() { - if (!ConsumeChar('*')) { - DVLOG(1) << "ReadBinary: '*' expected, got '" << input_.front() << "'"; - failed_ = true; - return std::string(); - } - size_t len = input_.find('*'); - if (len == base::StringPiece::npos) { - DVLOG(1) << "ReadBinary: missing closing '*'"; - failed_ = true; - return std::string(); - } - base::StringPiece base64 = input_.substr(0, len); - std::string binary; - if (!base::Base64Decode(base64, &binary)) { - DVLOG(1) << "ReadBinary: failed to decode base64: " << base64; - failed_ = true; - } - input_.remove_prefix(len); - ConsumeChar('*'); - return binary; - } - - // [SH] 4.4. Items - std::string ReadItem() { - if (input_.empty()) { - DVLOG(1) << "ReadItem: unexpected EOF"; - failed_ = true; - return std::string(); - } - switch (input_.front()) { - case '"': - return ReadString(); - case '*': - return ReadBinary(); - default: // identifier or integer - return ReadToken(); - } + void LogParseError(const char* func, const char* expected) { + DVLOG(1) << func << ": " << expected << " expected, got " + << (input_.empty() ? "'" + input_.substr(0, 1).as_string() + "'" + : "EOS"); } base::StringPiece input_; - bool failed_; DISALLOW_COPY_AND_ASSIGN(StructuredHeaderParser); }; } // namespace -ParameterisedIdentifier::ParameterisedIdentifier() = default; ParameterisedIdentifier::ParameterisedIdentifier( const ParameterisedIdentifier&) = default; +ParameterisedIdentifier::ParameterisedIdentifier(const std::string& id, + const Parameters& ps) + : identifier(id), params(ps) {} ParameterisedIdentifier::~ParameterisedIdentifier() = default; +base::Optional<std::string> ParseItem(const base::StringPiece& str) { + StructuredHeaderParser parser(str); + base::Optional<std::string> item = parser.ReadItem(); + if (item && parser.FinishParsing()) + return item; + return base::nullopt; +} + base::Optional<ParameterisedList> ParseParameterisedList( const base::StringPiece& str) { StructuredHeaderParser parser(str); - ParameterisedList values; - parser.ParseParameterisedList(&values); - if (parser.ParsedSuccessfully()) - return base::make_optional(std::move(values)); + base::Optional<ParameterisedList> param_list = parser.ReadParameterisedList(); + if (param_list && parser.FinishParsing()) + return param_list; return base::nullopt; }
diff --git a/content/browser/web_package/http_structured_header.h b/content/browser/web_package/http_structured_header.h index e7ff5878..d31dbad3 100644 --- a/content/browser/web_package/http_structured_header.h +++ b/content/browser/web_package/http_structured_header.h
@@ -6,7 +6,9 @@ #define CONTENT_BROWSER_WEB_PACKAGE_HTTP_STRUCTURED_HEADER_H_ #include <map> +#include <string> #include <vector> + #include "base/optional.h" #include "base/strings/string_piece.h" #include "content/common/content_export.h" @@ -15,16 +17,20 @@ namespace http_structured_header { struct CONTENT_EXPORT ParameterisedIdentifier { - std::string identifier; - std::map<std::string, std::string> params; + using Parameters = std::map<std::string, std::string>; - ParameterisedIdentifier(); + std::string identifier; + Parameters params; + ParameterisedIdentifier(const ParameterisedIdentifier&); + ParameterisedIdentifier(const std::string&, const Parameters&); ~ParameterisedIdentifier(); }; typedef std::vector<ParameterisedIdentifier> ParameterisedList; +CONTENT_EXPORT base::Optional<std::string> ParseItem( + const base::StringPiece& str); CONTENT_EXPORT base::Optional<ParameterisedList> ParseParameterisedList( const base::StringPiece& str);
diff --git a/content/browser/web_package/http_structured_header_unittest.cc b/content/browser/web_package/http_structured_header_unittest.cc new file mode 100644 index 0000000..083a2ec --- /dev/null +++ b/content/browser/web_package/http_structured_header_unittest.cc
@@ -0,0 +1,138 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/web_package/http_structured_header.h" + +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { +namespace http_structured_header { + +// Test cases are taken from https://github.com/httpwg/structured-header-tests. + +TEST(StructuredHeaderTest, ParseItem) { + struct TestCase { + const char* name; + const char* raw; + const char* expected; // nullptr if parse error is expected + } cases[] = { + // Item + {"basic token - item", "a_b-c.d3:f%00/*", "a_b-c.d3:f%00/*"}, + {"token with capitals - item", "fooBar", "fooBar"}, + {"token starting with capitals - item", "FooBar", "FooBar"}, + {"bad token - item", "abc$%!", nullptr}, + {"leading whitespace", " foo", "foo"}, + {"trailing whitespace", "foo ", "foo"}, + // Number + {"basic integer", "42", "42"}, + {"zero integer", "0", "0"}, + {"comma", "2,3", nullptr}, + {"long integer", "9223372036854775807", "9223372036854775807"}, + {"too long integer", "9223372036854775808", nullptr}, + // Byte Sequence + {"basic binary", "*aGVsbG8=*", "hello"}, + {"empty binary", "**", ""}, + {"bad paddding", "*aGVsbG8*", "hello"}, + {"bad end delimiter", "*aGVsbG8=", nullptr}, + {"extra whitespace", "*aGVsb G8=*", nullptr}, + {"extra chars", "*aGVsbG!8=*", nullptr}, + {"suffix chars", "*aGVsbG8=!*", nullptr}, + {"non-zero pad bits", "*iZ==*", "\x89"}, + {"non-ASCII binary", "*/+Ah*", "\xFF\xE0!"}, + {"base64url binary", "*_-Ah*", nullptr}, + // String + {"basic string", "\"foo\"", "foo"}, + {"empty string", "\"\"", ""}, + {"long string", + "\"foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo \"", + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo " + "foo foo foo foo foo foo foo foo foo foo foo foo foo foo "}, + {"whitespace string", "\" \"", " "}, + {"non-ascii string", "\"f\xC3\xBC\xC3\xBC\"", nullptr}, + {"tab in string", "\"\t\"", nullptr}, + {"newline in string", "\" \n \"", nullptr}, + {"single quoted string", "'foo'", nullptr}, + {"unbalanced string", "\"foo", nullptr}, + {"string quoting", "\"foo \\\"bar\\\" \\\\ baz\"", "foo \"bar\" \\ baz"}, + {"bad string quoting", "\"foo \\,\"", nullptr}, + {"ending string quote", "\"foo \\\"", nullptr}, + {"abruptly ending string quote", "\"foo \\", nullptr}, + }; + for (const auto& c : cases) { + base::Optional<std::string> result = ParseItem(c.raw); + if (c.expected) { + EXPECT_TRUE(result.has_value()) << c.name; + EXPECT_EQ(*result, c.expected) << c.name; + } else { + EXPECT_FALSE(result.has_value()) << c.name; + } + } +} + +inline bool operator==(const ParameterisedIdentifier& lhs, + const ParameterisedIdentifier& rhs) { + return lhs.identifier == rhs.identifier && lhs.params == rhs.params; +} + +TEST(StructuredHeaderTest, ParseParameterisedList) { + struct TestCase { + const char* name; + const char* raw; + ParameterisedList expected; // empty if parse error is expected + } cases[] = { + {"basic param-list", + "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"", + { + {"abc_123", {{"a", "1"}, {"b", "2"}, {"cdef_456", ""}}}, + {"ghi", {{"q", "9"}, {"r", "w"}}}, + }}, + {"empty param-list", "", {}}, + {"single item param-list", + "text/html;q=1", + {{"text/html", {{"q", "1"}}}}}, + {"no whitespace param-list", + "text/html,text/plain;q=1", + {{"text/html", {}}, {"text/plain", {{"q", "1"}}}}}, + {"whitespace before = param-list", "text/html, text/plain;q =1", {}}, + {"whitespace after = param-list", "text/html, text/plain;q= 1", {}}, + {"extra whitespace param-list", + "text/html , text/plain ; q=1", + {{"text/html", {}}, {"text/plain", {{"q", "1"}}}}}, + {"duplicate key", "abc;a=1;b=2;a=1", {}}, + {"numeric key", "abc;a=1;1b=2;c=1", {}}, + {"uppercase key", "abc;a=1;B=2;c=1", {}}, + {"bad key", "abc;a=1;b!=2;c=1", {}}, + {"another bad key", "abc;a=1;b==2;c=1", {}}, + {"empty key name", "abc;a=1;=2;c=1", {}}, + {"empty parameter", "abc;a=1;;c=1", {}}, + {"empty list item", "abc;a=1,,def;b=1", {}}, + {"extra semicolon", "abc;a=1;b=1;", {}}, + {"extra comma", "abc;a=1,def;b=1,", {}}, + {"leading semicolon", ";abc;a=1", {}}, + {"leading comma", ",abc;a=1", {}}, + }; + for (const auto& c : cases) { + base::Optional<ParameterisedList> result = ParseParameterisedList(c.raw); + if (c.expected.empty()) { + EXPECT_FALSE(result.has_value()) << c.name; + continue; + } + EXPECT_TRUE(result.has_value()) << c.name; + EXPECT_EQ(result->size(), c.expected.size()) << c.name; + if (result->size() == c.expected.size()) { + for (size_t i = 0; i < c.expected.size(); ++i) + EXPECT_EQ((*result)[i], c.expected[i]) << c.name; + } + } +} + +} // namespace http_structured_header +} // namespace content
diff --git a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc index cc18540..1e6366e 100644 --- a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc +++ b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
@@ -165,8 +165,15 @@ DisconnectFromService(); } +#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER) +#define MAYBE_RemoveVirtualDeviceAfterItHasBeenEnumerated \ + DISABLED_RemoveVirtualDeviceAfterItHasBeenEnumerated +#else +#define MAYBE_RemoveVirtualDeviceAfterItHasBeenEnumerated \ + RemoveVirtualDeviceAfterItHasBeenEnumerated +#endif IN_PROC_BROWSER_TEST_F(WebRtcVideoCaptureServiceEnumerationBrowserTest, - RemoveVirtualDeviceAfterItHasBeenEnumerated) { + MAYBE_RemoveVirtualDeviceAfterItHasBeenEnumerated) { // TODO(chfremer): Remove this when https://crbug.com/876892 is resolved. if (base::FeatureList::IsEnabled(features::kMediaDevicesSystemMonitorCache)) { LOG(WARNING) << "Skipping test, because feature not yet supported when "
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom index 88bb5a3b..7a60504 100644 --- a/content/common/service_worker/embedded_worker.mojom +++ b/content/common/service_worker/embedded_worker.mojom
@@ -28,9 +28,10 @@ // Parameters to launch a service worker. This is passed from the browser to the // renderer at mojom::EmbeddedWorkerInstanceClient::StartWorker(). struct EmbeddedWorkerStartParams { - // The id of the embedded worker. This changes when the service worker is - // stopped and restarted. + // DEPRECATED: This is only used in unit tests. + // TODO(https://crbug.com/927651): Remove this. int32 embedded_worker_id; + // The id of the service worker being started. This remains fixed even if the // worker is stopped and restarted, or even if the browser restarts. int64 service_worker_version_id;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 24d1e1d..c557a57 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -512,12 +512,14 @@ "service_worker/controller_service_worker_impl.h", "service_worker/embedded_worker_instance_client_impl.cc", "service_worker/embedded_worker_instance_client_impl.h", + "service_worker/navigation_preload_request.cc", + "service_worker/navigation_preload_request.h", "service_worker/service_worker_context_client.cc", "service_worker/service_worker_context_client.h", "service_worker/service_worker_fetch_context_impl.cc", "service_worker/service_worker_fetch_context_impl.h", - "service_worker/service_worker_network_provider.cc", - "service_worker/service_worker_network_provider.h", + "service_worker/service_worker_network_provider_for_service_worker.cc", + "service_worker/service_worker_network_provider_for_service_worker.h", "service_worker/service_worker_provider_context.cc", "service_worker/service_worker_provider_context.h", "service_worker/service_worker_provider_state_for_client.cc",
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc index 3e018e1..1f016c03 100644 --- a/content/renderer/pepper/v8_var_converter_unittest.cc +++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -120,7 +120,8 @@ if (v8_array->Length() != array_var->elements().size()) return false; for (uint32_t i = 0; i < v8_array->Length(); ++i) { - v8::Local<v8::Value> child_v8 = v8_array->Get(i); + v8::Local<v8::Value> child_v8 = + v8_array->Get(context, i).ToLocalChecked(); if (!Equals(array_var->elements()[i].get(), child_v8, visited_ids)) return false; } @@ -394,7 +395,7 @@ ASSERT_FALSE(FromV8ValueSync(object, context, &var_result)); // Array with self reference. - array->Set(0, array); + array->Set(context, 0, array).Check(); ASSERT_FALSE(FromV8ValueSync(array, context, &var_result)); } }
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc index 2ec6f562..06bc6bf 100644 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -64,8 +64,7 @@ params->renderer_preferences->enable_referrers); auto client = std::make_unique<ServiceWorkerContextClient>( - params->embedded_worker_id, params->service_worker_version_id, - params->scope, params->script_url, + params->service_worker_version_id, params->scope, params->script_url, !params->installed_scripts_info.is_null(), std::move(params->renderer_preferences), std::move(params->service_worker_request),
diff --git a/content/renderer/service_worker/navigation_preload_request.cc b/content/renderer/service_worker/navigation_preload_request.cc new file mode 100644 index 0000000..01373aa8b --- /dev/null +++ b/content/renderer/service_worker/navigation_preload_request.cc
@@ -0,0 +1,154 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/service_worker/navigation_preload_request.h" + +#include <utility> + +#include "content/renderer/loader/web_url_loader_impl.h" +#include "content/renderer/service_worker/service_worker_context_client.h" +#include "net/http/http_response_headers.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h" +#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h" + +namespace content { + +NavigationPreloadRequest::NavigationPreloadRequest( + int fetch_event_id, + const GURL& url, + blink::mojom::FetchEventPreloadHandlePtr preload_handle) + : fetch_event_id_(fetch_event_id), + url_(url), + url_loader_(std::move(preload_handle->url_loader)), + binding_(this, std::move(preload_handle->url_loader_client_request)) {} + +NavigationPreloadRequest::~NavigationPreloadRequest() = default; + +void NavigationPreloadRequest::OnReceiveResponse( + const network::ResourceResponseHead& response_head) { + DCHECK(!response_); + response_ = std::make_unique<blink::WebURLResponse>(); + // TODO(horo): Set report_security_info to true when DevTools is attached. + const bool report_security_info = false; + WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(), + report_security_info, + -1 /* request_id */); + MaybeReportResponseToClient(); +} + +void NavigationPreloadRequest::OnReceiveRedirect( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head) { + DCHECK(!response_); + DCHECK(net::HttpResponseHeaders::IsRedirectResponseCode( + response_head.headers->response_code())); + + ServiceWorkerContextClient* client = + ServiceWorkerContextClient::ThreadSpecificInstance(); + if (!client) + return; + response_ = std::make_unique<blink::WebURLResponse>(); + WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(), + false /* report_security_info */, + -1 /* request_id */); + client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), + mojo::ScopedDataPipeConsumerHandle()); + // This will delete |this|. + client->OnNavigationPreloadComplete( + fetch_event_id_, response_head.response_start, + response_head.encoded_data_length, 0 /* encoded_body_length */, + 0 /* decoded_body_length */); +} + +void NavigationPreloadRequest::OnUploadProgress( + int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) { + NOTREACHED(); +} + +void NavigationPreloadRequest::OnReceiveCachedMetadata( + const std::vector<uint8_t>& data) {} + +void NavigationPreloadRequest::OnTransferSizeUpdated( + int32_t transfer_size_diff) {} + +void NavigationPreloadRequest::OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) { + DCHECK(!body_.is_valid()); + body_ = std::move(body); + MaybeReportResponseToClient(); +} + +void NavigationPreloadRequest::OnComplete( + const network::URLLoaderCompletionStatus& status) { + if (status.error_code != net::OK) { + std::string message; + std::string unsanitized_message; + if (status.error_code == net::ERR_ABORTED) { + message = + "The service worker navigation preload request was cancelled " + "before 'preloadResponse' settled. If you intend to use " + "'preloadResponse', use waitUntil() or respondWith() to wait for " + "the promise to settle."; + } else { + message = + "The service worker navigation preload request failed with a " + "network error."; + unsanitized_message = + "The service worker navigation preload request failed with network " + "error: " + + net::ErrorToString(status.error_code) + "."; + } + + // This will delete |this|. + ReportErrorToClient(message, unsanitized_message); + return; + } + + ServiceWorkerContextClient* client = + ServiceWorkerContextClient::ThreadSpecificInstance(); + if (!client) + return; + if (response_) { + // When the response body from the server is empty, OnComplete() is called + // without OnStartLoadingResponseBody(). + DCHECK(!body_.is_valid()); + client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), + mojo::ScopedDataPipeConsumerHandle()); + } + // This will delete |this|. + client->OnNavigationPreloadComplete( + fetch_event_id_, status.completion_time, status.encoded_data_length, + status.encoded_body_length, status.decoded_body_length); +} + +void NavigationPreloadRequest::MaybeReportResponseToClient() { + if (!response_ || !body_.is_valid()) + return; + ServiceWorkerContextClient* client = + ServiceWorkerContextClient::ThreadSpecificInstance(); + if (!client) + return; + + client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), + std::move(body_)); +} + +void NavigationPreloadRequest::ReportErrorToClient( + const std::string& message, + const std::string& unsanitized_message) { + ServiceWorkerContextClient* client = + ServiceWorkerContextClient::ThreadSpecificInstance(); + if (!client) + return; + // This will delete |this|. + client->OnNavigationPreloadError( + fetch_event_id_, std::make_unique<blink::WebServiceWorkerError>( + blink::mojom::ServiceWorkerErrorType::kNetwork, + blink::WebString::FromUTF8(message), + blink::WebString::FromUTF8(unsanitized_message))); +} + +} // namespace content
diff --git a/content/renderer/service_worker/navigation_preload_request.h b/content/renderer/service_worker/navigation_preload_request.h new file mode 100644 index 0000000..b662b0de --- /dev/null +++ b/content/renderer/service_worker/navigation_preload_request.h
@@ -0,0 +1,65 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST_H_ +#define CONTENT_RENDERER_SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom.h" +#include "third_party/blink/public/platform/web_url_response.h" +#include "url/gurl.h" + +namespace content { + +// The URLLoaderClient for receiving a navigation preload response. It reports +// the response back to ServiceWorkerContextClient. +// +// This class lives on the service worker thread and is owned by +// ServiceWorkerContextClient. +class NavigationPreloadRequest final : public network::mojom::URLLoaderClient { + public: + NavigationPreloadRequest( + int fetch_event_id, + const GURL& url, + blink::mojom::FetchEventPreloadHandlePtr preload_handle); + ~NavigationPreloadRequest() override; + + // network::mojom::URLLoaderClient: + void OnReceiveResponse( + const network::ResourceResponseHead& response_head) override; + void OnReceiveRedirect( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head) override; + void OnUploadProgress(int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) override; + void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override; + void OnTransferSizeUpdated(int32_t transfer_size_diff) override; + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override; + void OnComplete(const network::URLLoaderCompletionStatus& status) override; + + private: + void MaybeReportResponseToClient(); + void ReportErrorToClient(const std::string& message, + const std::string& unsanitized_message); + + const int fetch_event_id_; + const GURL url_; + network::mojom::URLLoaderPtr url_loader_; + mojo::Binding<network::mojom::URLLoaderClient> binding_; + + std::unique_ptr<blink::WebURLResponse> response_; + mojo::ScopedDataPipeConsumerHandle body_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST_H_
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 2f7c3a2..bd8df1b 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -7,6 +7,7 @@ #include <map> #include <memory> #include <utility> +#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" @@ -30,7 +31,6 @@ #include "content/public/renderer/document_state.h" #include "content/public/renderer/worker_thread.h" #include "content/renderer/loader/child_url_loader_factory_bundle.h" -#include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/tracked_child_url_loader_factory_bundle.h" #include "content/renderer/loader/web_data_consumer_handle_impl.h" #include "content/renderer/loader/web_url_loader_impl.h" @@ -40,14 +40,13 @@ #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/service_worker/controller_service_worker_impl.h" #include "content/renderer/service_worker/embedded_worker_instance_client_impl.h" +#include "content/renderer/service_worker/navigation_preload_request.h" #include "content/renderer/service_worker/service_worker_fetch_context_impl.h" +#include "content/renderer/service_worker/service_worker_network_provider_for_service_worker.h" #include "content/renderer/service_worker/service_worker_timeout_timer.h" #include "content/renderer/service_worker/service_worker_type_converters.h" #include "content/renderer/service_worker/service_worker_type_util.h" -#include "ipc/ipc_message.h" -#include "ipc/ipc_message_macros.h" #include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/request_context_frame_type.mojom.h" @@ -60,7 +59,6 @@ #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" @@ -71,7 +69,6 @@ #include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h" #include "third_party/blink/public/platform/platform.h" @@ -80,6 +77,7 @@ #include "third_party/blink/public/platform/web_http_body.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" @@ -98,79 +96,6 @@ base::LazyInstance<base::ThreadLocalPointer<ServiceWorkerContextClient>>:: Leaky g_worker_client_tls = LAZY_INSTANCE_INITIALIZER; -// Called on the main thread only and blink owns it. -class WebServiceWorkerNetworkProviderImpl - : public blink::WebServiceWorkerNetworkProvider { - public: - WebServiceWorkerNetworkProviderImpl( - int provider_id, - network::mojom::URLLoaderFactoryAssociatedPtrInfo - script_loader_factory_info) - : provider_id_(provider_id), - script_loader_factory_(std::move(script_loader_factory_info)) {} - - // This is only called for the main script request from the shadow page. - // TODO(https://crbug.com/538751): Remove this once the shadow page is - // removed. - void WillSendRequest(WebURLRequest& request) override { - ResourceType resource_type = WebURLRequestToResourceType(request); - DCHECK_EQ(resource_type, ResourceType::RESOURCE_TYPE_SERVICE_WORKER); - - auto extra_data = std::make_unique<RequestExtraData>(); - extra_data->set_service_worker_provider_id(provider_id_); - extra_data->set_originated_from_service_worker(true); - // Service workers are only available in secure contexts, so all requests - // are initiated in a secure context. - extra_data->set_initiated_in_secure_context(true); - - // The RenderThreadImpl or its URLLoaderThrottleProvider member may not be - // valid in some tests. - RenderThreadImpl* render_thread = RenderThreadImpl::current(); - if (render_thread && render_thread->url_loader_throttle_provider()) { - extra_data->set_url_loader_throttles( - render_thread->url_loader_throttle_provider()->CreateThrottles( - MSG_ROUTING_NONE, request, resource_type)); - } - - request.SetExtraData(std::move(extra_data)); - } - - std::unique_ptr<blink::WebURLLoader> CreateURLLoader( - const WebURLRequest& request, - std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> - task_runner_handle) override { - RenderThreadImpl* render_thread = RenderThreadImpl::current(); - if (render_thread && script_loader_factory() && - blink::ServiceWorkerUtils::IsServicificationEnabled() && - IsScriptRequest(request)) { - // TODO(crbug.com/796425): Temporarily wrap the raw - // mojom::URLLoaderFactory pointer into SharedURLLoaderFactory. - return std::make_unique<WebURLLoaderImpl>( - render_thread->resource_dispatcher(), std::move(task_runner_handle), - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - script_loader_factory())); - } - return nullptr; - } - - network::mojom::URLLoaderFactory* script_loader_factory() { - return script_loader_factory_.get(); - } - - private: - static bool IsScriptRequest(const WebURLRequest& request) { - auto request_context = request.GetRequestContext(); - return request_context == - blink::mojom::RequestContextType::SERVICE_WORKER || - request_context == blink::mojom::RequestContextType::SCRIPT || - request_context == blink::mojom::RequestContextType::IMPORT; - } - - const int provider_id_; - // The URL loader factory for loading the service worker's scripts. - network::mojom::URLLoaderFactoryAssociatedPtr script_loader_factory_; -}; - class StreamHandleListener : public blink::WebServiceWorkerStreamHandle::Listener { public: @@ -361,159 +286,12 @@ base::WeakPtrFactory<blink::WebServiceWorkerContextProxy> proxy_weak_factory; }; -class ServiceWorkerContextClient::NavigationPreloadRequest final - : public network::mojom::URLLoaderClient { - public: - NavigationPreloadRequest( - int fetch_event_id, - const GURL& url, - blink::mojom::FetchEventPreloadHandlePtr preload_handle) - : fetch_event_id_(fetch_event_id), - url_(url), - url_loader_(std::move(preload_handle->url_loader)), - binding_(this, std::move(preload_handle->url_loader_client_request)) {} - - ~NavigationPreloadRequest() override {} - - void OnReceiveResponse( - const network::ResourceResponseHead& response_head) override { - DCHECK(!response_); - response_ = std::make_unique<blink::WebURLResponse>(); - // TODO(horo): Set report_security_info to true when DevTools is attached. - const bool report_security_info = false; - WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(), - report_security_info, - -1 /* request_id */); - MaybeReportResponseToClient(); - } - - void OnReceiveRedirect( - const net::RedirectInfo& redirect_info, - const network::ResourceResponseHead& response_head) override { - DCHECK(!response_); - DCHECK(net::HttpResponseHeaders::IsRedirectResponseCode( - response_head.headers->response_code())); - - ServiceWorkerContextClient* client = - ServiceWorkerContextClient::ThreadSpecificInstance(); - if (!client) - return; - response_ = std::make_unique<blink::WebURLResponse>(); - WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(), - false /* report_security_info */, - -1 /* request_id */); - client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), - mojo::ScopedDataPipeConsumerHandle()); - // This will delete |this|. - client->OnNavigationPreloadComplete( - fetch_event_id_, response_head.response_start, - response_head.encoded_data_length, 0 /* encoded_body_length */, - 0 /* decoded_body_length */); - } - - void OnUploadProgress(int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) override { - NOTREACHED(); - } - - void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} - - void OnTransferSizeUpdated(int32_t transfer_size_diff) override { - } - - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override { - DCHECK(!body_.is_valid()); - body_ = std::move(body); - MaybeReportResponseToClient(); - } - - void OnComplete(const network::URLLoaderCompletionStatus& status) override { - if (status.error_code != net::OK) { - std::string message; - std::string unsanitized_message; - if (status.error_code == net::ERR_ABORTED) { - message = - "The service worker navigation preload request was cancelled " - "before 'preloadResponse' settled. If you intend to use " - "'preloadResponse', use waitUntil() or respondWith() to wait for " - "the promise to settle."; - } else { - message = - "The service worker navigation preload request failed with a " - "network error."; - unsanitized_message = - "The service worker navigation preload request failed with network " - "error: " + - net::ErrorToString(status.error_code) + "."; - } - - // This will delete |this|. - ReportErrorToClient(message, unsanitized_message); - return; - } - - ServiceWorkerContextClient* client = - ServiceWorkerContextClient::ThreadSpecificInstance(); - if (!client) - return; - if (response_) { - // When the response body from the server is empty, OnComplete() is called - // without OnStartLoadingResponseBody(). - DCHECK(!body_.is_valid()); - client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), - mojo::ScopedDataPipeConsumerHandle()); - } - // This will delete |this|. - client->OnNavigationPreloadComplete( - fetch_event_id_, status.completion_time, status.encoded_data_length, - status.encoded_body_length, status.decoded_body_length); - } - - private: - void MaybeReportResponseToClient() { - if (!response_ || !body_.is_valid()) - return; - ServiceWorkerContextClient* client = - ServiceWorkerContextClient::ThreadSpecificInstance(); - if (!client) - return; - - client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_), - std::move(body_)); - } - - void ReportErrorToClient(const std::string& message, - const std::string& unsanitized_message) { - ServiceWorkerContextClient* client = - ServiceWorkerContextClient::ThreadSpecificInstance(); - if (!client) - return; - // This will delete |this|. - client->OnNavigationPreloadError( - fetch_event_id_, std::make_unique<blink::WebServiceWorkerError>( - blink::mojom::ServiceWorkerErrorType::kNetwork, - blink::WebString::FromUTF8(message), - blink::WebString::FromUTF8(unsanitized_message))); - } - - const int fetch_event_id_; - const GURL url_; - network::mojom::URLLoaderPtr url_loader_; - mojo::Binding<network::mojom::URLLoaderClient> binding_; - - std::unique_ptr<blink::WebURLResponse> response_; - mojo::ScopedDataPipeConsumerHandle body_; -}; - ServiceWorkerContextClient* ServiceWorkerContextClient::ThreadSpecificInstance() { return g_worker_client_tls.Pointer()->Get(); } ServiceWorkerContextClient::ServiceWorkerContextClient( - int embedded_worker_id, int64_t service_worker_version_id, const GURL& service_worker_scope, const GURL& script_url, @@ -528,8 +306,7 @@ blink::mojom::RendererPreferenceWatcherRequest preference_watcher_request, std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loaders, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) - : embedded_worker_id_(embedded_worker_id), - service_worker_version_id_(service_worker_version_id), + : service_worker_version_id_(service_worker_version_id), service_worker_scope_(service_worker_scope), script_url_(script_url), is_starting_installed_worker_(is_starting_installed_worker), @@ -1200,7 +977,7 @@ std::unique_ptr<blink::WebServiceWorkerNetworkProvider> ServiceWorkerContextClient::CreateServiceWorkerNetworkProvider() { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - return std::make_unique<WebServiceWorkerNetworkProviderImpl>( + return std::make_unique<ServiceWorkerNetworkProviderForServiceWorker>( service_worker_provider_info_->provider_id, std::move(service_worker_provider_info_->script_loader_factory_ptr_info)); } @@ -1228,7 +1005,7 @@ // mojom::URLLoaderFactory pointer into SharedURLLoaderFactory. script_loader_factory_info = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - static_cast<WebServiceWorkerNetworkProviderImpl*>(provider) + static_cast<ServiceWorkerNetworkProviderForServiceWorker*>(provider) ->script_loader_factory()) ->Clone(); } @@ -1359,6 +1136,53 @@ proxy_->DispatchPaymentRequestEvent(event_id, webEventData); } +void ServiceWorkerContextClient::OnNavigationPreloadResponse( + int fetch_event_id, + std::unique_ptr<blink::WebURLResponse> response, + mojo::ScopedDataPipeConsumerHandle data_pipe) { + DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + TRACE_EVENT_WITH_FLOW0( + "ServiceWorker", + "ServiceWorkerContextClient::OnNavigationPreloadResponse", + TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, + TRACE_ID_LOCAL(fetch_event_id)), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + proxy_->OnNavigationPreloadResponse(fetch_event_id, std::move(response), + std::move(data_pipe)); +} + +void ServiceWorkerContextClient::OnNavigationPreloadError( + int fetch_event_id, + std::unique_ptr<blink::WebServiceWorkerError> error) { + DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + TRACE_EVENT_WITH_FLOW0("ServiceWorker", + "ServiceWorkerContextClient::OnNavigationPreloadError", + TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, + TRACE_ID_LOCAL(fetch_event_id)), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + proxy_->OnNavigationPreloadError(fetch_event_id, std::move(error)); + context_->preload_requests.Remove(fetch_event_id); +} + +void ServiceWorkerContextClient::OnNavigationPreloadComplete( + int fetch_event_id, + base::TimeTicks completion_time, + int64_t encoded_data_length, + int64_t encoded_body_length, + int64_t decoded_body_length) { + DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + TRACE_EVENT_WITH_FLOW0( + "ServiceWorker", + "ServiceWorkerContextClient::OnNavigationPreloadComplete", + TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, + TRACE_ID_LOCAL(fetch_event_id)), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + proxy_->OnNavigationPreloadComplete(fetch_event_id, completion_time, + encoded_data_length, encoded_body_length, + decoded_body_length); + context_->preload_requests.Remove(fetch_event_id); +} + void ServiceWorkerContextClient::ToWebServiceWorkerRequestForFetchEvent( blink::mojom::FetchAPIRequestPtr request, const std::string& client_id, @@ -1783,53 +1607,6 @@ context_->timeout_timer->SetIdleTimerDelayToZero(); } -void ServiceWorkerContextClient::OnNavigationPreloadResponse( - int fetch_event_id, - std::unique_ptr<blink::WebURLResponse> response, - mojo::ScopedDataPipeConsumerHandle data_pipe) { - DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT_WITH_FLOW0( - "ServiceWorker", - "ServiceWorkerContextClient::OnNavigationPreloadResponse", - TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, - TRACE_ID_LOCAL(fetch_event_id)), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - proxy_->OnNavigationPreloadResponse(fetch_event_id, std::move(response), - std::move(data_pipe)); -} - -void ServiceWorkerContextClient::OnNavigationPreloadError( - int fetch_event_id, - std::unique_ptr<blink::WebServiceWorkerError> error) { - DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT_WITH_FLOW0("ServiceWorker", - "ServiceWorkerContextClient::OnNavigationPreloadError", - TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, - TRACE_ID_LOCAL(fetch_event_id)), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - proxy_->OnNavigationPreloadError(fetch_event_id, std::move(error)); - context_->preload_requests.Remove(fetch_event_id); -} - -void ServiceWorkerContextClient::OnNavigationPreloadComplete( - int fetch_event_id, - base::TimeTicks completion_time, - int64_t encoded_data_length, - int64_t encoded_body_length, - int64_t decoded_body_length) { - DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT_WITH_FLOW0( - "ServiceWorker", - "ServiceWorkerContextClient::OnNavigationPreloadComplete", - TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, - TRACE_ID_LOCAL(fetch_event_id)), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - proxy_->OnNavigationPreloadComplete(fetch_event_id, completion_time, - encoded_data_length, encoded_body_length, - decoded_body_length); - context_->preload_requests.Remove(fetch_event_id); -} - void ServiceWorkerContextClient::SetupNavigationPreload( int fetch_event_id, const GURL& url, @@ -1899,8 +1676,11 @@ } void ServiceWorkerContextClient::RecordDebugLog(const char* message) { + const size_t kMaxDebugLogSize = 512; base::AutoLock lock(debug_log_lock_); debug_log_.emplace_back(message); + if (debug_log_.size() > kMaxDebugLogSize) + debug_log_.pop_front(); } } // namespace content
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 4f991d88..7d1b0c08 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -8,10 +8,10 @@ #include <stddef.h> #include <stdint.h> +#include <deque> #include <map> #include <memory> #include <string> -#include <vector> #include "base/callback.h" #include "base/containers/id_map.h" @@ -83,7 +83,6 @@ // |start_worker_received_time|. This instance will fill in the rest during // startup. ServiceWorkerContextClient( - int embedded_worker_id, int64_t service_worker_version_id, const GURL& service_worker_scope, const GURL& script_url, @@ -218,9 +217,33 @@ report_debug_log_ = report_debug_log; } + ///////////////////////////////////////////////////////////////////////////// + // The following are for use by NavigationPreloadRequest. + // + // Called to resolve the FetchEvent.preloadResponse promise. + void OnNavigationPreloadResponse( + int fetch_event_id, + std::unique_ptr<blink::WebURLResponse> response, + mojo::ScopedDataPipeConsumerHandle data_pipe); + + // Called when the navigation preload request completed. Either + // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be + // called to release the preload related resources. + void OnNavigationPreloadComplete(int fetch_event_id, + base::TimeTicks completion_time, + int64_t encoded_data_length, + int64_t encoded_body_length, + int64_t decoded_body_length); + + // Called when an error occurred while receiving the response of the + // navigation preload request. + void OnNavigationPreloadError( + int fetch_event_id, + std::unique_ptr<blink::WebServiceWorkerError> error); + ///////////////////////////////////////////////////////////////////////////// + private: struct WorkerContextData; - class NavigationPreloadRequest; friend class ControllerServiceWorkerImpl; friend class ServiceWorkerContextClientTest; FRIEND_TEST_ALL_PREFIXES( @@ -238,10 +261,6 @@ const std::string& client_id, blink::WebServiceWorkerRequest* web_request); - // Get routing_id for sending message to the ServiceWorkerVersion - // in the browser process. - int GetRoutingID() const { return embedded_worker_id_; } - void SendWorkerStarted(blink::mojom::ServiceWorkerStartStatus status); // Implements blink::mojom::ServiceWorker. @@ -327,24 +346,6 @@ int request_id, const blink::mojom::ServiceWorkerClientInfo& client); void OnNavigateClientError(int request_id, const GURL& url); - // Called to resolve the FetchEvent.preloadResponse promise. - void OnNavigationPreloadResponse( - int fetch_event_id, - std::unique_ptr<blink::WebURLResponse> response, - mojo::ScopedDataPipeConsumerHandle data_pipe); - // Called when the navigation preload request completed. Either - // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be - // called to release the preload related resources. - void OnNavigationPreloadComplete(int fetch_event_id, - base::TimeTicks completion_time, - int64_t encoded_data_length, - int64_t encoded_body_length, - int64_t decoded_body_length); - // Called when an error occurred while receiving the response of the - // navigation preload request. - void OnNavigationPreloadError( - int fetch_event_id, - std::unique_ptr<blink::WebServiceWorkerError> error); void SetupNavigationPreload( int fetch_event_id, @@ -373,7 +374,6 @@ // TODO(crbug.com/907311): Remove after we identified the cause of crash. void RecordDebugLog(const char* message); - const int embedded_worker_id_; const int64_t service_worker_version_id_; const GURL service_worker_scope_; const GURL script_url_; @@ -432,7 +432,7 @@ // TODO(crbug.com/907311): Remove after we identified the cause of crash. bool report_debug_log_ = true; base::Lock debug_log_lock_; - std::vector<std::string> debug_log_ GUARDED_BY(debug_log_lock_); + std::deque<std::string> debug_log_ GUARDED_BY(debug_log_lock_); DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextClient); };
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc index d0950b4..25a53acd 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -312,8 +312,8 @@ const GURL kScope("https://example.com"); const GURL kScript("https://example.com/SW.js"); auto context_client = std::make_unique<ServiceWorkerContextClient>( - 1 /* embedded_worker_id */, 1 /* service_worker_version_id */, kScope, - kScript, false /* is_script_streaming */, + 1 /* service_worker_version_id */, kScope, kScript, + false /* is_script_streaming */, blink::mojom::RendererPreferences::New(), std::move(service_worker_request), std::move(controller_request), embedded_worker_host_ptr.PassInterface(), CreateProviderInfo(),
diff --git a/content/renderer/service_worker/service_worker_network_provider.cc b/content/renderer/service_worker/service_worker_network_provider.cc deleted file mode 100644 index 1f90baeb..0000000 --- a/content/renderer/service_worker/service_worker_network_provider.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/service_worker/service_worker_network_provider.h" - -#include "base/atomic_sequence_num.h" - -namespace content { - -// Must be unique in the child process. -int GetNextServiceWorkerProviderId() { - static base::AtomicSequenceNumber sequence; - return sequence.GetNext(); // We start at zero. -} - -} // namespace content
diff --git a/content/renderer/service_worker/service_worker_network_provider.h b/content/renderer/service_worker/service_worker_network_provider.h deleted file mode 100644 index c6dde50..0000000 --- a/content/renderer/service_worker/service_worker_network_provider.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_ -#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_ - -namespace content { - -int GetNextServiceWorkerProviderId(); - -} // namespace content - -#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
diff --git a/content/renderer/service_worker/service_worker_network_provider_for_service_worker.cc b/content/renderer/service_worker/service_worker_network_provider_for_service_worker.cc new file mode 100644 index 0000000..89e6e44 --- /dev/null +++ b/content/renderer/service_worker/service_worker_network_provider_for_service_worker.cc
@@ -0,0 +1,89 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/service_worker/service_worker_network_provider_for_service_worker.h" + +#include <utility> + +#include "content/public/common/resource_type.h" +#include "content/public/renderer/url_loader_throttle_provider.h" +#include "content/renderer/loader/request_extra_data.h" +#include "content/renderer/loader/web_url_loader_impl.h" +#include "content/renderer/loader/web_url_request_util.h" +#include "content/renderer/render_thread_impl.h" +#include "ipc/ipc_message.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "third_party/blink/public/common/service_worker/service_worker_utils.h" + +namespace content { + +ServiceWorkerNetworkProviderForServiceWorker:: + ServiceWorkerNetworkProviderForServiceWorker( + int provider_id, + network::mojom::URLLoaderFactoryAssociatedPtrInfo + script_loader_factory_info) + : provider_id_(provider_id), + script_loader_factory_(std::move(script_loader_factory_info)) {} + +ServiceWorkerNetworkProviderForServiceWorker:: + ~ServiceWorkerNetworkProviderForServiceWorker() = default; + +void ServiceWorkerNetworkProviderForServiceWorker::WillSendRequest( + blink::WebURLRequest& request) { + ResourceType resource_type = WebURLRequestToResourceType(request); + DCHECK_EQ(resource_type, ResourceType::RESOURCE_TYPE_SERVICE_WORKER); + + auto extra_data = std::make_unique<RequestExtraData>(); + extra_data->set_service_worker_provider_id(provider_id_); + extra_data->set_originated_from_service_worker(true); + // Service workers are only available in secure contexts, so all requests + // are initiated in a secure context. + extra_data->set_initiated_in_secure_context(true); + + // The RenderThreadImpl or its URLLoaderThrottleProvider member may not be + // valid in some tests. + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + if (render_thread && render_thread->url_loader_throttle_provider()) { + extra_data->set_url_loader_throttles( + render_thread->url_loader_throttle_provider()->CreateThrottles( + MSG_ROUTING_NONE, request, resource_type)); + } + + request.SetExtraData(std::move(extra_data)); +} + +std::unique_ptr<blink::WebURLLoader> +ServiceWorkerNetworkProviderForServiceWorker::CreateURLLoader( + const blink::WebURLRequest& request, + std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> + task_runner_handle) { + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + // RenderThreadImpl may be null in some tests. + if (render_thread && script_loader_factory() && + blink::ServiceWorkerUtils::IsServicificationEnabled() && + IsScriptRequest(request)) { + // TODO(crbug.com/796425): Temporarily wrap the raw + // mojom::URLLoaderFactory pointer into SharedURLLoaderFactory. + return std::make_unique<WebURLLoaderImpl>( + render_thread->resource_dispatcher(), std::move(task_runner_handle), + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + script_loader_factory())); + } + return nullptr; +} + +// TODO(falken): This class is only used for the shadow page so import +// scripts shouldn't come here. Change the callsite to be a DCHECK that only +// SERVICE_WORKER is used. +// +// static +bool ServiceWorkerNetworkProviderForServiceWorker::IsScriptRequest( + const blink::WebURLRequest& request) { + auto request_context = request.GetRequestContext(); + return request_context == blink::mojom::RequestContextType::SERVICE_WORKER || + request_context == blink::mojom::RequestContextType::SCRIPT || + request_context == blink::mojom::RequestContextType::IMPORT; +} + +} // namespace content
diff --git a/content/renderer/service_worker/service_worker_network_provider_for_service_worker.h b/content/renderer/service_worker/service_worker_network_provider_for_service_worker.h new file mode 100644 index 0000000..86f1f22 --- /dev/null +++ b/content/renderer/service_worker/service_worker_network_provider_for_service_worker.h
@@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_FOR_SERVICE_WORKER_H_ +#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_FOR_SERVICE_WORKER_H_ + +#include <memory> + +#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" +#include "third_party/blink/public/platform/web_url_request.h" + +namespace content { + +// The WebServiceWorkerNetworkProvider implementation for service worker +// execution contexts. +// +// This class is only used for the main script request from the shadow page. +// Remove it when the shadow page is removed (https://crbug.com/538751). +class ServiceWorkerNetworkProviderForServiceWorker final + : public blink::WebServiceWorkerNetworkProvider { + public: + ServiceWorkerNetworkProviderForServiceWorker( + int provider_id, + network::mojom::URLLoaderFactoryAssociatedPtrInfo + script_loader_factory_info); + ~ServiceWorkerNetworkProviderForServiceWorker() override; + + // blink::WebServiceWorkerNetworkProvider: + void WillSendRequest(blink::WebURLRequest& request) override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> + task_runner_handle) override; + + network::mojom::URLLoaderFactory* script_loader_factory() { + return script_loader_factory_.get(); + } + + private: + static bool IsScriptRequest(const blink::WebURLRequest& request); + + const int provider_id_; + // The URL loader factory for loading the service worker's scripts. + network::mojom::URLLoaderFactoryAssociatedPtr script_loader_factory_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_FOR_SERVICE_WORKER_H_
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc index 1fb66eb..c965488 100644 --- a/content/renderer/service_worker/service_worker_provider_context.cc +++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include "base/atomic_sequence_num.h" #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -55,6 +56,12 @@ } // namespace +// static +int ServiceWorkerProviderContext::GetNextId() { + static base::AtomicSequenceNumber sequence; + return sequence.GetNext(); // We start at zero. +} + // For service worker clients. ServiceWorkerProviderContext::ServiceWorkerProviderContext( int provider_id,
diff --git a/content/renderer/service_worker/service_worker_provider_context.h b/content/renderer/service_worker/service_worker_provider_context.h index a8ed9398..8071e54 100644 --- a/content/renderer/service_worker/service_worker_provider_context.h +++ b/content/renderer/service_worker/service_worker_provider_context.h
@@ -44,10 +44,10 @@ class WebServiceWorkerRegistrationImpl; struct ServiceWorkerProviderContextDeleter; -// ServiceWorkerProviderContext stores common state for service worker -// "providers" (currently WebServiceWorkerProviderImpl and -// ServiceWorkerNetworkProvider). Providers for the same underlying entity hold -// strong references to a shared instance of this class. +// ServiceWorkerProviderContext stores common state for "providers" for service +// worker clients (currently WebServiceWorkerProviderImpl and +// WebServiceWorkerNetworkProviderImplFor{Frame,Worker}). Providers for the same +// underlying entity hold strong references to a shared instance of this class. // // ServiceWorkerProviderContext is also a // blink::mojom::ServiceWorkerWorkerClientRegistry. If it's a provider for a @@ -64,6 +64,9 @@ public blink::mojom::ServiceWorkerContainer, public blink::mojom::ServiceWorkerWorkerClientRegistry { public: + // Returns a unique id within this process. + static int GetNextId(); + // |provider_id| is used to identify this provider in IPC messages to the // browser process. |request| is an endpoint which is connected to // the content::ServiceWorkerProviderHost that notifies of changes to the
diff --git a/content/renderer/service_worker/web_service_worker_network_provider_impl_for_frame.cc b/content/renderer/service_worker/web_service_worker_network_provider_impl_for_frame.cc index 89c1a888..7ca7c55e 100644 --- a/content/renderer/service_worker/web_service_worker_network_provider_impl_for_frame.cc +++ b/content/renderer/service_worker/web_service_worker_network_provider_impl_for_frame.cc
@@ -13,7 +13,7 @@ #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/render_thread_impl.h" -#include "content/renderer/service_worker/service_worker_network_provider.h" +#include "content/renderer/service_worker/service_worker_provider_context.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -115,7 +115,7 @@ DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id) || provider_id == kInvalidServiceWorkerProviderId); if (provider_id == kInvalidServiceWorkerProviderId) - provider_id = GetNextServiceWorkerProviderId(); + provider_id = ServiceWorkerProviderContext::GetNextId(); auto provider = base::WrapUnique(new WebServiceWorkerNetworkProviderImplForFrame(frame));
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc index 479b262..d65555e 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -24,7 +24,6 @@ #include "content/renderer/loader/web_worker_fetch_context_impl.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/renderer_blink_platform_impl.h" -#include "content/renderer/service_worker/service_worker_network_provider.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/shared_worker/web_service_worker_network_provider_impl_for_worker.h" #include "ipc/ipc_message_macros.h"
diff --git a/content/renderer/shared_worker/web_service_worker_network_provider_impl_for_worker.cc b/content/renderer/shared_worker/web_service_worker_network_provider_impl_for_worker.cc index 9d183e1..f483fc5 100644 --- a/content/renderer/shared_worker/web_service_worker_network_provider_impl_for_worker.cc +++ b/content/renderer/shared_worker/web_service_worker_network_provider_impl_for_worker.cc
@@ -12,7 +12,7 @@ #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/web_url_loader_impl.h" #include "content/renderer/render_thread_impl.h" -#include "content/renderer/service_worker/service_worker_network_provider.h" +#include "content/renderer/service_worker/service_worker_provider_context.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h" @@ -44,7 +44,7 @@ } } else { DCHECK(!info); - int provider_id = GetNextServiceWorkerProviderId(); + int provider_id = ServiceWorkerProviderContext::GetNextId(); auto host_info = blink::mojom::ServiceWorkerProviderHostInfo::New( provider_id, MSG_ROUTING_NONE, blink::mojom::ServiceWorkerProviderType::kForSharedWorker,
diff --git a/content/renderer/v8_value_converter_impl.cc b/content/renderer/v8_value_converter_impl.cc index 90b588a..c33074d7 100644 --- a/content/renderer/v8_value_converter_impl.cc +++ b/content/renderer/v8_value_converter_impl.cc
@@ -470,7 +470,7 @@ // Only fields with integer keys are carried over to the ListValue. for (uint32_t i = 0; i < val->Length(); ++i) { v8::TryCatch try_catch(isolate); - v8::Local<v8::Value> child_v8 = val->Get(i); + v8::Local<v8::Value> child_v8; v8::MaybeLocal<v8::Value> maybe_child = val->Get(isolate->GetCurrentContext(), i); if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) {
diff --git a/content/renderer/v8_value_converter_impl_unittest.cc b/content/renderer/v8_value_converter_impl_unittest.cc index 124078b..e60f671 100644 --- a/content/renderer/v8_value_converter_impl_unittest.cc +++ b/content/renderer/v8_value_converter_impl_unittest.cc
@@ -75,17 +75,17 @@ } std::string GetString(v8::Local<v8::Object> value, const std::string& key) { - v8::Local<v8::String> temp = - value - ->Get(v8::String::NewFromUtf8(isolate_, key.c_str(), - v8::NewStringType::kInternalized) - .ToLocalChecked()) - .As<v8::String>(); - if (temp.IsEmpty()) { + v8::Local<v8::Value> temp; + if (!value + ->Get(isolate_->GetCurrentContext(), + v8::String::NewFromUtf8(isolate_, key.c_str(), + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocal(&temp)) { ADD_FAILURE(); return std::string(); } - v8::String::Utf8Value utf8(isolate_, temp); + v8::String::Utf8Value utf8(isolate_, temp.As<v8::String>()); return std::string(*utf8, utf8.length()); } @@ -99,36 +99,36 @@ } std::string GetString(v8::Local<v8::Array> value, uint32_t index) { - v8::Local<v8::String> temp = value->Get(index).As<v8::String>(); - if (temp.IsEmpty()) { + v8::Local<v8::Value> temp; + if (!value->Get(isolate_->GetCurrentContext(), index).ToLocal(&temp)) { ADD_FAILURE(); return std::string(); } - v8::String::Utf8Value utf8(isolate_, temp); + v8::String::Utf8Value utf8(isolate_, temp.As<v8::String>()); return std::string(*utf8, utf8.length()); } int32_t GetInt(v8::Local<v8::Object> value, const std::string& key) { - v8::Local<v8::Int32> temp = - value - ->Get(v8::String::NewFromUtf8(isolate_, key.c_str(), - v8::NewStringType::kInternalized) - .ToLocalChecked()) - .As<v8::Int32>(); - if (temp.IsEmpty()) { + v8::Local<v8::Value> temp; + if (!value + ->Get(isolate_->GetCurrentContext(), + v8::String::NewFromUtf8(isolate_, key.c_str(), + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocal(&temp)) { ADD_FAILURE(); return -1; } - return temp->Value(); + return temp.As<v8::Int32>()->Value(); } int32_t GetInt(v8::Local<v8::Object> value, uint32_t index) { - v8::Local<v8::Int32> temp = value->Get(index).As<v8::Int32>(); - if (temp.IsEmpty()) { + v8::Local<v8::Value> temp; + if (!value->Get(isolate_->GetCurrentContext(), index).ToLocal(&temp)) { ADD_FAILURE(); return -1; } - return temp->Value(); + return temp.As<v8::Int32>()->Value(); } bool IsNull(base::DictionaryValue* value, const std::string& key) { @@ -141,11 +141,13 @@ } bool IsNull(v8::Local<v8::Object> value, const std::string& key) { - v8::Local<v8::Value> child = - value->Get(v8::String::NewFromUtf8(isolate_, key.c_str(), + v8::Local<v8::Value> child; + if (!value + ->Get(isolate_->GetCurrentContext(), + v8::String::NewFromUtf8(isolate_, key.c_str(), v8::NewStringType::kInternalized) - .ToLocalChecked()); - if (child.IsEmpty()) { + .ToLocalChecked()) + .ToLocal(&child)) { ADD_FAILURE(); return false; } @@ -162,8 +164,8 @@ } bool IsNull(v8::Local<v8::Array> value, uint32_t index) { - v8::Local<v8::Value> child = value->Get(index); - if (child.IsEmpty()) { + v8::Local<v8::Value> child; + if (!value->Get(isolate_->GetCurrentContext(), index).ToLocal(&child)) { ADD_FAILURE(); return false; } @@ -187,10 +189,13 @@ } v8::Local<v8::Object> object(v8::Object::New(isolate_)); - object->Set(v8::String::NewFromUtf8(isolate_, "test", - v8::NewStringType::kInternalized) - .ToLocalChecked(), - val); + object + ->Set(context, + v8::String::NewFromUtf8(isolate_, "test", + v8::NewStringType::kInternalized) + .ToLocalChecked(), + val) + .Check(); std::unique_ptr<base::DictionaryValue> dictionary( base::DictionaryValue::From(converter.FromV8Value(object, context))); ASSERT_TRUE(dictionary.get()); @@ -205,7 +210,7 @@ } v8::Local<v8::Array> array(v8::Array::New(isolate_)); - array->Set(0, val); + array->Set(context, 0, val).Check(); std::unique_ptr<base::ListValue> list( base::ListValue::From(converter.FromV8Value(array, context))); ASSERT_TRUE(list.get()); @@ -277,85 +282,104 @@ EXPECT_EQ(static_cast<const base::DictionaryValue&>(*original_root).size(), v8_object->GetPropertyNames(context).ToLocalChecked()->Length()); + EXPECT_TRUE( + v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "null", v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsNull()); + EXPECT_TRUE( + v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "true", v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsTrue()); EXPECT_TRUE(v8_object - ->Get(v8::String::NewFromUtf8( - isolate_, "null", v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsNull()); - EXPECT_TRUE(v8_object - ->Get(v8::String::NewFromUtf8( - isolate_, "true", v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsTrue()); - EXPECT_TRUE(v8_object - ->Get(v8::String::NewFromUtf8( + ->Get(context, + v8::String::NewFromUtf8( isolate_, "false", v8::NewStringType::kInternalized) .ToLocalChecked()) + .ToLocalChecked() ->IsFalse()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "positive-int", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsInt32()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "negative-int", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsInt32()); EXPECT_TRUE(v8_object - ->Get(v8::String::NewFromUtf8( - isolate_, "zero", v8::NewStringType::kInternalized) - .ToLocalChecked()) + ->Get(context, v8::String::NewFromUtf8( + isolate_, "positive-int", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsInt32()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "negative-int", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() ->IsInt32()); EXPECT_TRUE( v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "double", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsNumber()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "big-integral-double", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsNumber()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "string", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsString()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "empty-string", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsString()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "dictionary", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsObject()); - EXPECT_TRUE( - v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "empty-dictionary", - v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsObject()); + ->Get(context, v8::String::NewFromUtf8( + isolate_, "zero", v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsInt32()); EXPECT_TRUE(v8_object - ->Get(v8::String::NewFromUtf8( - isolate_, "list", v8::NewStringType::kInternalized) - .ToLocalChecked()) - ->IsArray()); + ->Get(context, v8::String::NewFromUtf8( + isolate_, "double", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsNumber()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "big-integral-double", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsNumber()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "string", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsString()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "empty-string", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsString()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "dictionary", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsObject()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "empty-dictionary", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsObject()); EXPECT_TRUE( v8_object - ->Get(v8::String::NewFromUtf8(isolate_, "empty-list", - v8::NewStringType::kInternalized) - .ToLocalChecked()) + ->Get(context, v8::String::NewFromUtf8( + isolate_, "list", v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() ->IsArray()); + EXPECT_TRUE(v8_object + ->Get(context, v8::String::NewFromUtf8( + isolate_, "empty-list", + v8::NewStringType::kInternalized) + .ToLocalChecked()) + .ToLocalChecked() + ->IsArray()); std::unique_ptr<base::Value> new_root( converter.FromV8Value(v8_object, context)); @@ -400,7 +424,7 @@ v8::Local<v8::String> bar = v8::String::NewFromUtf8(isolate_, "bar", v8::NewStringType::kInternalized) .ToLocalChecked(); - object->Set(bar, bar); + object->Set(context, bar, bar).Check(); // Converting from v8 value should replace the foo property with null. V8ValueConverterImpl converter; @@ -690,15 +714,21 @@ v8::Local<v8::Object> object = v8::Object::New(isolate_).As<v8::Object>(); ASSERT_FALSE(object.IsEmpty()); - object->Set( - v8::String::NewFromUtf8(isolate_, "foo", v8::NewStringType::kInternalized) - .ToLocalChecked(), - v8::String::NewFromUtf8(isolate_, "bar", v8::NewStringType::kNormal) - .ToLocalChecked()); - object->Set( - v8::String::NewFromUtf8(isolate_, "obj", v8::NewStringType::kInternalized) - .ToLocalChecked(), - object); + object + ->Set(context, + v8::String::NewFromUtf8(isolate_, "foo", + v8::NewStringType::kInternalized) + .ToLocalChecked(), + v8::String::NewFromUtf8(isolate_, "bar", v8::NewStringType::kNormal) + .ToLocalChecked()) + .Check(); + object + ->Set(context, + v8::String::NewFromUtf8(isolate_, "obj", + v8::NewStringType::kInternalized) + .ToLocalChecked(), + object) + .Check(); std::unique_ptr<base::DictionaryValue> object_result( base::DictionaryValue::From(converter.FromV8Value(object, context))); @@ -708,10 +738,12 @@ v8::Local<v8::Array> array = v8::Array::New(isolate_).As<v8::Array>(); ASSERT_FALSE(array.IsEmpty()); - array->Set(0, - v8::String::NewFromUtf8(isolate_, "1", v8::NewStringType::kNormal) - .ToLocalChecked()); - array->Set(1, array); + array + ->Set(context, 0, + v8::String::NewFromUtf8(isolate_, "1", v8::NewStringType::kNormal) + .ToLocalChecked()) + .Check(); + array->Set(context, 1, array).Check(); std::unique_ptr<base::ListValue> list_result( base::ListValue::From(converter.FromV8Value(array, context))); @@ -842,10 +874,14 @@ // Create the v8::Object to be converted. v8::Local<v8::Array> root(v8::Array::New(isolate_, 4)); - root->Set(0, v8::Local<v8::Object>(v8::Object::New(isolate_))); - root->Set(1, v8::Local<v8::Object>(v8::Object::New(isolate_))); - root->Set(2, v8::Local<v8::Object>(v8::Array::New(isolate_, 0))); - root->Set(3, v8::Local<v8::Object>(v8::Array::New(isolate_, 0))); + root->Set(context, 0, v8::Local<v8::Object>(v8::Object::New(isolate_))) + .Check(); + root->Set(context, 1, v8::Local<v8::Object>(v8::Object::New(isolate_))) + .Check(); + root->Set(context, 2, v8::Local<v8::Object>(v8::Array::New(isolate_, 0))) + .Check(); + root->Set(context, 3, v8::Local<v8::Object>(v8::Array::New(isolate_, 0))) + .Check(); // The expected base::Value result. std::unique_ptr<base::Value> expected = @@ -868,7 +904,7 @@ // Create a recursive array. v8::Local<v8::Array> recursive_array(v8::Array::New(isolate_, 1)); - recursive_array->Set(0, recursive_array); + recursive_array->Set(context, 0, recursive_array).Check(); // The first repetition should be trimmed and replaced by a null value. base::ListValue expected_list; @@ -884,13 +920,14 @@ // Now create a recursive object const std::string key("key"); v8::Local<v8::Object> recursive_object(v8::Object::New(isolate_)); - v8::TryCatch try_catch(isolate_); - recursive_object->Set( - v8::String::NewFromUtf8(isolate_, key.c_str(), - v8::NewStringType::kInternalized, key.length()) - .ToLocalChecked(), - recursive_object); - ASSERT_FALSE(try_catch.HasCaught()); + recursive_object + ->Set(context, + v8::String::NewFromUtf8(isolate_, key.c_str(), + v8::NewStringType::kInternalized, + key.length()) + .ToLocalChecked(), + recursive_object) + .Check(); // The first repetition should be trimmed and replaced by a null value. base::DictionaryValue expected_dictionary; @@ -981,10 +1018,12 @@ v8::Local<v8::Object> leaf = deep_object; for (int i = 0; i < kDepth; ++i) { v8::Local<v8::Object> new_object = v8::Object::New(isolate_); - leaf->Set(v8::String::NewFromUtf8(isolate_, kKey, + leaf->Set(context, + v8::String::NewFromUtf8(isolate_, kKey, v8::NewStringType::kInternalized) .ToLocalChecked(), - new_object); + new_object) + .Check(); leaf = new_object; }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index bdf583e..1a0934fa 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1663,6 +1663,7 @@ "../browser/web_contents/web_contents_view_mac_unittest.mm", "../browser/web_contents/web_drag_dest_mac_unittest.mm", "../browser/web_contents/web_drag_source_mac_unittest.mm", + "../browser/web_package/http_structured_header_unittest.cc", "../browser/web_package/origins_list_unittest.cc", "../browser/web_package/signed_exchange_cert_fetcher_unittest.cc", "../browser/web_package/signed_exchange_certificate_chain_unittest.cc",
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 74f9916f..35a5304c 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -118,8 +118,6 @@ "authentication_service_fake.mm", "fake_gaia_cookie_manager_service_builder.cc", "fake_gaia_cookie_manager_service_builder.h", - "fake_oauth2_token_service_builder.h", - "fake_oauth2_token_service_builder.mm", "identity_test_environment_chrome_browser_state_adaptor.cc", "identity_test_environment_chrome_browser_state_adaptor.h", ]
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 69e26d7..68403bf 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -22,7 +22,6 @@ #include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/prefs/browser_prefs.h" -#include "ios/chrome/browser/signin/account_tracker_service_factory.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_delegate_fake.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" @@ -40,6 +39,7 @@ #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h" #include "ios/web/public/test/test_web_thread_bundle.h" +#include "services/identity/public/cpp/identity_manager.h" #import "services/identity/public/cpp/identity_test_environment.h" #include "base/bind.h" @@ -263,13 +263,12 @@ ProfileOAuth2TokenService* token_service = ProfileOAuth2TokenServiceFactory::GetForBrowserState( browser_state_.get()); - AccountTrackerService* account_tracker = - ios::AccountTrackerServiceFactory::GetForBrowserState( - browser_state_.get()); std::string user_email = base::SysNSStringToUTF8([identity_ userEmail]); AccountInfo account_info = - account_tracker->FindAccountInfoByEmail(user_email); + identity_manager() + ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(user_email) + .value(); EXPECT_EQ(user_email, account_info.email); EXPECT_EQ(base::SysNSStringToUTF8([identity_ gaiaID]), account_info.gaia); EXPECT_TRUE(token_service->RefreshTokenIsAvailable(account_info.account_id)); @@ -392,20 +391,18 @@ StoreAccountsInPrefs(); accounts = GetAccountsInPrefs(); ASSERT_EQ(2u, accounts.size()); - AccountTrackerService* account_tracker = - ios::AccountTrackerServiceFactory::GetForBrowserState( - browser_state_.get()); - switch (account_tracker->GetMigrationState()) { - case AccountTrackerService::MIGRATION_NOT_STARTED: + + switch (identity_manager()->GetAccountIdMigrationState()) { + case identity::IdentityManager::MIGRATION_NOT_STARTED: EXPECT_EQ("foo2@foo.com", accounts[0]); EXPECT_EQ("foo@foo.com", accounts[1]); break; - case AccountTrackerService::MIGRATION_IN_PROGRESS: - case AccountTrackerService::MIGRATION_DONE: + case identity::IdentityManager::MIGRATION_IN_PROGRESS: + case identity::IdentityManager::MIGRATION_DONE: EXPECT_EQ("foo2ID", accounts[0]); EXPECT_EQ("fooID", accounts[1]); break; - case AccountTrackerService::NUM_MIGRATION_STATES: + case identity::IdentityManager::NUM_MIGRATION_STATES: FAIL() << "NUM_MIGRATION_STATES is not a real migration state."; break; } @@ -427,20 +424,18 @@ identity_manager()->GetAccountsWithRefreshTokens(); std::sort(accounts.begin(), accounts.end(), account_compare_func); ASSERT_EQ(2u, accounts.size()); - AccountTrackerService* account_tracker = - ios::AccountTrackerServiceFactory::GetForBrowserState( - browser_state_.get()); - switch (account_tracker->GetMigrationState()) { - case AccountTrackerService::MIGRATION_NOT_STARTED: + + switch (identity_manager()->GetAccountIdMigrationState()) { + case identity::IdentityManager::MIGRATION_NOT_STARTED: EXPECT_EQ("foo2@foo.com", accounts[0].account_id); EXPECT_EQ("foo@foo.com", accounts[1].account_id); break; - case AccountTrackerService::MIGRATION_IN_PROGRESS: - case AccountTrackerService::MIGRATION_DONE: + case identity::IdentityManager::MIGRATION_IN_PROGRESS: + case identity::IdentityManager::MIGRATION_DONE: EXPECT_EQ("foo2ID", accounts[0].account_id); EXPECT_EQ("fooID", accounts[1].account_id); break; - case AccountTrackerService::NUM_MIGRATION_STATES: + case identity::IdentityManager::NUM_MIGRATION_STATES: FAIL() << "NUM_MIGRATION_STATES is not a real migration state."; break; } @@ -455,19 +450,19 @@ accounts = identity_manager()->GetAccountsWithRefreshTokens(); std::sort(accounts.begin(), accounts.end(), account_compare_func); ASSERT_EQ(3u, accounts.size()); - switch (account_tracker->GetMigrationState()) { - case AccountTrackerService::MIGRATION_NOT_STARTED: + switch (identity_manager()->GetAccountIdMigrationState()) { + case identity::IdentityManager::MIGRATION_NOT_STARTED: EXPECT_EQ("foo2@foo.com", accounts[0].account_id); EXPECT_EQ("foo3@foo.com", accounts[1].account_id); EXPECT_EQ("foo@foo.com", accounts[2].account_id); break; - case AccountTrackerService::MIGRATION_IN_PROGRESS: - case AccountTrackerService::MIGRATION_DONE: + case identity::IdentityManager::MIGRATION_IN_PROGRESS: + case identity::IdentityManager::MIGRATION_DONE: EXPECT_EQ("foo2ID", accounts[0].account_id); EXPECT_EQ("foo3ID", accounts[1].account_id); EXPECT_EQ("fooID", accounts[2].account_id); break; - case AccountTrackerService::NUM_MIGRATION_STATES: + case identity::IdentityManager::NUM_MIGRATION_STATES: FAIL() << "NUM_MIGRATION_STATES is not a real migration state."; break; } @@ -541,11 +536,8 @@ } TEST_F(AuthenticationServiceTest, MigrateAccountsStoredInPref) { - AccountTrackerService* account_tracker = - ios::AccountTrackerServiceFactory::GetForBrowserState( - browser_state_.get()); - if (account_tracker->GetMigrationState() == - AccountTrackerService::MIGRATION_NOT_STARTED) { + if (identity_manager()->GetAccountIdMigrationState() == + identity::IdentityManager::MIGRATION_NOT_STARTED) { // The account tracker is not migratable. Skip the test as the accounts // cannot be migrated. return; @@ -554,7 +546,7 @@ // Force the migration state to MIGRATION_NOT_STARTED before signing in. browser_state_->GetPrefs()->SetInteger( prefs::kAccountIdMigrationState, - AccountTrackerService::MIGRATION_NOT_STARTED); + identity::IdentityManager::MIGRATION_NOT_STARTED); browser_state_->GetPrefs()->SetBoolean(prefs::kSigninLastAccountsMigrated, false); @@ -566,11 +558,10 @@ EXPECT_EQ("foo2@foo.com", accounts_in_prefs[0]); EXPECT_EQ("foo@foo.com", accounts_in_prefs[1]); - // Migrate the accounts (this actually requires a shutdown and re-initialize - // of the account tracker). - account_tracker->Shutdown(); - account_tracker->Initialize(browser_state_->GetPrefs(), base::FilePath()); - account_tracker->SetMigrationDone(); + // Migrate the accounts. + browser_state_->GetPrefs()->SetInteger( + prefs::kAccountIdMigrationState, + identity::IdentityManager::MIGRATION_DONE); // Reload all credentials to find account info with the refresh token. // If it tries to find refresh token with gaia ID after
diff --git a/ios/chrome/browser/signin/fake_oauth2_token_service_builder.h b/ios/chrome/browser/signin/fake_oauth2_token_service_builder.h deleted file mode 100644 index 0887666..0000000 --- a/ios/chrome/browser/signin/fake_oauth2_token_service_builder.h +++ /dev/null
@@ -1,22 +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. - -#ifndef IOS_CHROME_BROWSER_SIGNIN_FAKE_OAUTH2_TOKEN_SERVICE_BUILDER_H_ -#define IOS_CHROME_BROWSER_SIGNIN_FAKE_OAUTH2_TOKEN_SERVICE_BUILDER_H_ - -#include <memory> - -namespace web { -class BrowserState; -} - -class KeyedService; - -// Helper function to be used with -// BrowserStateKeyedServiceFactory::SetTestingFactory() that returns a -// FakeProfileOAuth2TokenService object. -std::unique_ptr<KeyedService> BuildFakeOAuth2TokenService( - web::BrowserState* context); - -#endif // IOS_CHROME_BROWSER_SIGNIN_FAKE_OAUTH2_TOKEN_SERVICE_BUILDER_H_
diff --git a/ios/chrome/browser/signin/fake_oauth2_token_service_builder.mm b/ios/chrome/browser/signin/fake_oauth2_token_service_builder.mm deleted file mode 100644 index 44391e6..0000000 --- a/ios/chrome/browser/signin/fake_oauth2_token_service_builder.mm +++ /dev/null
@@ -1,29 +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. - -#include "ios/chrome/browser/signin/fake_oauth2_token_service_builder.h" - -#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" -#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/signin/account_tracker_service_factory.h" -#include "ios/chrome/browser/signin/profile_oauth2_token_service_ios_provider_impl.h" -#include "ios/chrome/browser/signin/signin_client_factory.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -std::unique_ptr<KeyedService> BuildFakeOAuth2TokenService( - web::BrowserState* context) { - ios::ChromeBrowserState* browser_state = - ios::ChromeBrowserState::FromBrowserState(context); - std::unique_ptr<OAuth2TokenServiceDelegate> delegate = - std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( - SigninClientFactory::GetForBrowserState(browser_state), - std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), - ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state)); - return std::make_unique<FakeProfileOAuth2TokenService>( - browser_state->GetPrefs(), std::move(delegate)); -}
diff --git a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc index 8d2b2a32..e63a8e8 100644 --- a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc +++ b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
@@ -4,13 +4,19 @@ #include "ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.h" +#include <memory> +#include <utility> + #include "base/bind.h" +#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/account_tracker_service_factory.h" #include "ios/chrome/browser/signin/fake_gaia_cookie_manager_service_builder.h" -#include "ios/chrome/browser/signin/fake_oauth2_token_service_builder.h" #include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "ios/chrome/browser/signin/profile_oauth2_token_service_ios_provider_impl.h" #include "ios/chrome/browser/signin/signin_client_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" @@ -34,6 +40,19 @@ return manager; } +std::unique_ptr<KeyedService> BuildFakeOAuth2TokenService( + web::BrowserState* context) { + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + std::unique_ptr<OAuth2TokenServiceDelegate> delegate = + std::make_unique<ProfileOAuth2TokenServiceIOSDelegate>( + SigninClientFactory::GetForBrowserState(browser_state), + std::make_unique<ProfileOAuth2TokenServiceIOSProviderImpl>(), + ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state)); + return std::make_unique<FakeProfileOAuth2TokenService>( + browser_state->GetPrefs(), std::move(delegate)); +} + TestChromeBrowserState::TestingFactories GetIdentityTestEnvironmentFactories() { return {{ProfileOAuth2TokenServiceFactory::GetInstance(), base::BindRepeating(&BuildFakeOAuth2TokenService)},
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index efe2005..463b35a2 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -96,6 +96,7 @@ "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/favicon", "//ios/chrome/browser/find_in_page", + "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sessions", "//ios/chrome/browser/snapshots", @@ -108,6 +109,7 @@ "//ios/chrome/browser/ui/ntp:ntp_controller", "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/test", + "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/browser_view_controller+private.h b/ios/chrome/browser/ui/browser_view_controller+private.h index 47fe60e..b4e696a2 100644 --- a/ios/chrome/browser/ui/browser_view_controller+private.h +++ b/ios/chrome/browser/ui/browser_view_controller+private.h
@@ -24,6 +24,10 @@ - (void)clearPresentedStateWithCompletion:(ProceduralBlock)completion dismissOmnibox:(BOOL)dismissOmnibox; +// Switch to the tab best represented by the given |params|. +- (void)switchToTabWithParams: + (const web::NavigationManager::WebLoadParams&)params; + // Called before the instance is deallocated. - (void)shutdown;
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 3d3a21f..a13495d 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -159,6 +159,8 @@ #import "ios/chrome/browser/url_loading/url_loading_notifier.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_factory.h" #import "ios/chrome/browser/url_loading/url_loading_observer_bridge.h" +#import "ios/chrome/browser/url_loading/url_loading_service.h" +#import "ios/chrome/browser/url_loading/url_loading_service_factory.h" #import "ios/chrome/browser/url_loading/url_loading_util.h" #import "ios/chrome/browser/voice/voice_search_navigations_tab_helper.h" #import "ios/chrome/browser/web/blocked_popup_tab_helper.h" @@ -1376,6 +1378,11 @@ _browserState); if (webUsageEnabler) webUsageEnabler->SetWebStateList(nullptr); + + UrlLoadingNotifier* urlLoadingNotifier = + UrlLoadingNotifierFactory::GetForBrowserState(_browserState); + if (urlLoadingNotifier) + urlLoadingNotifier->RemoveObserver(_URLLoadingObserverBridge.get()); } // Disconnect child coordinators. @@ -1861,7 +1868,7 @@ _URLLoadingObserverBridge = std::make_unique<UrlLoadingObserverBridge>(self); UrlLoadingNotifier* urlLoadingNotifier = - ios::UrlLoadingNotifierFactory::GetForBrowserState(_browserState); + UrlLoadingNotifierFactory::GetForBrowserState(_browserState); urlLoadingNotifier->AddObserver(_URLLoadingObserverBridge.get()); NSUInteger count = self.tabModel.count; @@ -3944,34 +3951,16 @@ #pragma mark - UrlLoader (Public) - (void)loadURLWithParams:(const ChromeLoadParams&)chromeParams { - URLLoadResult result = - LoadURL(chromeParams, self.browserState, self.tabModel.webStateList, - /* SessionWindowRestoring */ self.tabModel); - switch (result) { - case URLLoadResult::SWITCH_TO_TAB: { - [self switchToTabWithParams:chromeParams.web_params]; - break; - } - case URLLoadResult::DISALLOWED_IN_INCOGNITO: { - OpenNewTabCommand* command = - [[OpenNewTabCommand alloc] initWithURL:chromeParams.web_params.url - referrer:web::Referrer() - inIncognito:NO - inBackground:NO - appendTo:kCurrentTab]; - [self webPageOrderedOpen:command]; - break; - } - case URLLoadResult::INDUCED_CRASH: - case URLLoadResult::LOADED_PRERENDER: - case URLLoadResult::RELOADED: - case URLLoadResult::NORMAL_LOAD: - // Page load was handled, so nothing else to do. - break; - } + // TODO(crbug.com/907527): call UrlLoadingService directly where we call + // this method. + UrlLoadingService* urlLoadingService = + UrlLoadingServiceFactory::GetForBrowserState(self.browserState); + urlLoadingService->LoadUrlInCurrentTab(chromeParams); } - (void)webPageOrderedOpen:(OpenNewTabCommand*)command { + // TODO(crbug.com/907527): move to UrlLoadingService::OpenUrlInNewTab. + // Send either the "New Tab Opened" or "New Incognito Tab" opened to the // feature_engagement::Tracker based on |inIncognito|. feature_engagement::NotifyNewTabEvent(self.tabModel.browserState,
diff --git a/ios/chrome/browser/ui/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view_controller_unittest.mm index dbb1723..8e00416 100644 --- a/ios/chrome/browser/ui/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view_controller_unittest.mm
@@ -24,6 +24,7 @@ #include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" +#include "ios/chrome/browser/main/test_browser.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" @@ -46,6 +47,8 @@ #import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/ui_util.h" +#import "ios/chrome/browser/url_loading/url_loading_service.h" +#import "ios/chrome/browser/url_loading/url_loading_service_factory.h" #import "ios/chrome/browser/web/sad_tab_tab_helper.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" @@ -149,6 +152,32 @@ } @end +@interface URLLoadingServiceTestDelegate : NSObject <URLLoadingServiceDelegate> +@property(nonatomic, readonly) BrowserViewController* bvc; +@end + +@implementation URLLoadingServiceTestDelegate + +- (instancetype)initWithBrowserViewController:(BrowserViewController*)bvc { + if ((self = [super init])) { + _bvc = bvc; + } + return self; +} + +#pragma mark - URLLoadingServiceDelegate + +- (void)switchToTabWithParams: + (const web::NavigationManager::WebLoadParams&)params { + [self.bvc switchToTabWithParams:params]; +} + +- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command { + [self.bvc webPageOrderedOpen:command]; +} + +@end + #pragma mark - namespace { @@ -246,6 +275,16 @@ chrome_browser_state_.get()); template_url_service->Load(); + browser_ = new TestBrowser(chrome_browser_state_.get(), tabModel); + + url_loading_delegate_ = [[URLLoadingServiceTestDelegate alloc] + initWithBrowserViewController:bvc_]; + UrlLoadingService* urlLoadingService = + UrlLoadingServiceFactory::GetForBrowserState( + chrome_browser_state_.get()); + urlLoadingService->SetDelegate(url_loading_delegate_); + urlLoadingService->SetBrowser(browser_); + // Force the view to load. UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectZero]; [window addSubview:[bvc_ view]]; @@ -256,6 +295,11 @@ [[bvc_ view] removeFromSuperview]; [bvc_ shutdown]; + // Cleanup to avoid debugger crash in non empty observer lists. + WebStateList* web_state_list = tabModel_.webStateList; + web_state_list->CloseAllWebStates( + WebStateList::ClosingFlags::CLOSE_NO_FLAGS); + BlockCleanupTest::TearDown(); } @@ -284,6 +328,8 @@ OCMockObject* dependencyFactory_; CommandDispatcher* command_dispatcher_; BrowserViewController* bvc_; + Browser* browser_; + URLLoadingServiceTestDelegate* url_loading_delegate_; UIWindow* window_; };
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index a702707b..09b7783 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -48,6 +48,7 @@ "//ios/chrome/browser/ui/recent_tabs", "//ios/chrome/browser/ui/snackbar", "//ios/chrome/browser/ui/translate", + "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web", "//ios/chrome/browser/web:tab_helper_delegates", "//ios/chrome/browser/web:web_internal",
diff --git a/ios/chrome/browser/ui/main/browser_coordinator.mm b/ios/chrome/browser/ui/main/browser_coordinator.mm index 19d9e39..238ba0c5 100644 --- a/ios/chrome/browser/ui/main/browser_coordinator.mm +++ b/ios/chrome/browser/ui/main/browser_coordinator.mm
@@ -40,6 +40,8 @@ #import "ios/chrome/browser/ui/snackbar/snackbar_coordinator.h" #import "ios/chrome/browser/ui/translate/language_selection_coordinator.h" #import "ios/chrome/browser/ui/translate/translate_infobar_coordinator.h" +#import "ios/chrome/browser/url_loading/url_loading_service.h" +#import "ios/chrome/browser/url_loading/url_loading_service_factory.h" #import "ios/chrome/browser/web/print_tab_helper.h" #import "ios/chrome/browser/web/repost_form_tab_helper.h" #import "ios/chrome/browser/web/repost_form_tab_helper_delegate.h" @@ -53,6 +55,7 @@ @interface BrowserCoordinator () <FormInputAccessoryCoordinatorDelegate, RepostFormTabHelperDelegate, + URLLoadingServiceDelegate, WebStateListObserving> // Whether the coordinator is started. @@ -142,6 +145,7 @@ startDispatchingToTarget:self forProtocol:@protocol(BrowserCoordinatorCommands)]; [self installDelegatesForAllWebStates]; + [self installDelegatesForBrowserState]; [self addWebStateListObserver]; [super start]; self.started = YES; @@ -152,6 +156,7 @@ return; [super stop]; [self removeWebStateListObserver]; + [self uninstallDelegatesForBrowserState]; [self uninstallDelegatesForAllWebStates]; [self.dispatcher stopDispatchingToTarget:self]; [self stopChildCoordinators]; @@ -424,6 +429,17 @@ self.repostFormCoordinator = nil; } +#pragma mark - URLLoadingServiceDelegate + +- (void)switchToTabWithParams: + (const web::NavigationManager::WebLoadParams&)params { + [self.viewController switchToTabWithParams:params]; +} + +- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command { + [self.viewController webPageOrderedOpen:command]; +} + // TODO(crbug.com/906525) : Move WebStateListObserving out of // BrowserCoordinator. #pragma mark - WebStateListObserving @@ -477,6 +493,26 @@ } } +// Installs delegates for self.browserState. +- (void)installDelegatesForBrowserState { + UrlLoadingService* urlLoadingService = + UrlLoadingServiceFactory::GetForBrowserState(self.browserState); + if (urlLoadingService) { + urlLoadingService->SetDelegate(self); + urlLoadingService->SetBrowser(self.browser); + } +} + +// Uninstalls delegates for self.browserState. +- (void)uninstallDelegatesForBrowserState { + UrlLoadingService* urlLoadingService = + UrlLoadingServiceFactory::GetForBrowserState(self.browserState); + if (urlLoadingService) { + urlLoadingService->SetDelegate(nil); + urlLoadingService->SetBrowser(nil); + } +} + // Uninstalls delegates for each WebState in WebStateList. - (void)uninstallDelegatesForAllWebStates { for (int i = 0; i < self.tabModel.webStateList->count(); i++) {
diff --git a/ios/chrome/browser/url_loading/BUILD.gn b/ios/chrome/browser/url_loading/BUILD.gn index eaee360c..bea66357 100644 --- a/ios/chrome/browser/url_loading/BUILD.gn +++ b/ios/chrome/browser/url_loading/BUILD.gn
@@ -11,6 +11,10 @@ "url_loading_notifier_factory.h", "url_loading_observer_bridge.h", "url_loading_observer_bridge.mm", + "url_loading_service.h", + "url_loading_service.mm", + "url_loading_service_factory.h", + "url_loading_service_factory.mm", "url_loading_util.h", "url_loading_util.mm", ] @@ -20,10 +24,12 @@ "//components/sessions", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/main", "//ios/chrome/browser/prerender", "//ios/chrome/browser/sessions", "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui", + "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list", "//ios/web/public",
diff --git a/ios/chrome/browser/url_loading/url_loading_notifier_factory.cc b/ios/chrome/browser/url_loading/url_loading_notifier_factory.cc index 4a8008c..12131b7a 100644 --- a/ios/chrome/browser/url_loading/url_loading_notifier_factory.cc +++ b/ios/chrome/browser/url_loading/url_loading_notifier_factory.cc
@@ -9,9 +9,6 @@ #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/url_loading/url_loading_notifier.h" -#include "ios/chrome/browser/url_loading/url_loading_notifier_factory.h" - -namespace ios { // static UrlLoadingNotifier* UrlLoadingNotifierFactory::GetForBrowserState( @@ -29,11 +26,7 @@ UrlLoadingNotifierFactory::UrlLoadingNotifierFactory() : BrowserStateKeyedServiceFactory( "UrlLoadingNotifier", - BrowserStateDependencyManager::GetInstance()) { - // TODO(crbug.com/907527): add when available: - // DependsOn(UrlLoadingServiceFactory::GetInstance()); -} - + BrowserStateDependencyManager::GetInstance()) {} UrlLoadingNotifierFactory::~UrlLoadingNotifierFactory() {} std::unique_ptr<KeyedService> @@ -46,5 +39,3 @@ web::BrowserState* context) const { return GetBrowserStateOwnInstanceInIncognito(context); } - -} // namespace ios
diff --git a/ios/chrome/browser/url_loading/url_loading_notifier_factory.h b/ios/chrome/browser/url_loading/url_loading_notifier_factory.h index 508e9f6..b1b0aa38 100644 --- a/ios/chrome/browser/url_loading/url_loading_notifier_factory.h +++ b/ios/chrome/browser/url_loading/url_loading_notifier_factory.h
@@ -11,11 +11,11 @@ #include "base/no_destructor.h" #include "components/keyed_service/ios/browser_state_keyed_service_factory.h" -class UrlLoadingNotifier; - namespace ios { - class ChromeBrowserState; +} + +class UrlLoadingNotifier; // Singleton that owns all UrlLoadingNotifiers and associates them with // ios::ChromeBrowserState. @@ -40,6 +40,4 @@ DISALLOW_COPY_AND_ASSIGN(UrlLoadingNotifierFactory); }; -} // namespace ios - #endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_NOTIFIER_FACTORY_H_
diff --git a/ios/chrome/browser/url_loading/url_loading_service.h b/ios/chrome/browser/url_loading/url_loading_service.h new file mode 100644 index 0000000..7666d8d --- /dev/null +++ b/ios/chrome/browser/url_loading/url_loading_service.h
@@ -0,0 +1,60 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_ +#define IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_ + +#import <Foundation/Foundation.h> + +#include "components/keyed_service/core/keyed_service.h" +#import "ios/chrome/browser/ui/chrome_load_params.h" +#import "ios/web/public/navigation_manager.h" +#include "ui/base/page_transition_types.h" +#include "url/gurl.h" + +class Browser; +class UrlLoadingNotifier; + +@class OpenNewTabCommand; + +// TODO(crbug.com/907527): normalize all parameters to open a url in +// UrlLoadingService and URLLoadingServiceDelegate. + +// Objective-C delegate for UrlLoadingService. +@protocol URLLoadingServiceDelegate + +// Implementing delegate must switch to a tab that matches |params| or open in a +// new tab. +- (void)switchToTabWithParams: + (const web::NavigationManager::WebLoadParams&)params; + +// Implementing delegate must open the url in |command| in a new tab. +- (void)openURLInNewTabWithCommand:(OpenNewTabCommand*)command; + +@end + +// Observer used to update listeners of change of state in url loading. +class UrlLoadingService : public KeyedService { + public: + UrlLoadingService(UrlLoadingNotifier* notifier); + + void SetDelegate(id<URLLoadingServiceDelegate> delegate); + void SetBrowser(Browser* browser); + + // Opens a url based on |chrome_params|. + void LoadUrlInCurrentTab(const ChromeLoadParams& chrome_params); + + // Switches to a tab that matches |web_params| or opens in a new tab. + void SwitchToTab(const web::NavigationManager::WebLoadParams& web_params); + + // Opens a url based on |command| in a new tab. + void OpenUrlInNewTab(OpenNewTabCommand* command); + + private: + __weak id<URLLoadingServiceDelegate> delegate_; + Browser* browser_; + UrlLoadingNotifier* notifier_; +}; + +#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_H_
diff --git a/ios/chrome/browser/url_loading/url_loading_service.mm b/ios/chrome/browser/url_loading/url_loading_service.mm new file mode 100644 index 0000000..39106d6 --- /dev/null +++ b/ios/chrome/browser/url_loading/url_loading_service.mm
@@ -0,0 +1,65 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/url_loading/url_loading_service.h" + +#import "ios/chrome/browser/main/browser.h" +#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" +#import "ios/chrome/browser/url_loading/url_loading_notifier.h" +#import "ios/chrome/browser/url_loading/url_loading_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +UrlLoadingService::UrlLoadingService(UrlLoadingNotifier* notifier) + : notifier_(notifier) {} + +void UrlLoadingService::SetDelegate(id<URLLoadingServiceDelegate> delegate) { + delegate_ = delegate; +} + +void UrlLoadingService::SetBrowser(Browser* browser) { + browser_ = browser; +} + +void UrlLoadingService::LoadUrlInCurrentTab( + const ChromeLoadParams& chrome_params) { + URLLoadResult result = LoadURL(chrome_params, browser_, notifier_); + switch (result) { + case URLLoadResult::SWITCH_TO_TAB: { + SwitchToTab(chrome_params.web_params); + break; + } + case URLLoadResult::DISALLOWED_IN_INCOGNITO: { + OpenNewTabCommand* command = + [[OpenNewTabCommand alloc] initWithURL:chrome_params.web_params.url + referrer:web::Referrer() + inIncognito:NO + inBackground:NO + appendTo:kCurrentTab]; + OpenUrlInNewTab(command); + break; + } + case URLLoadResult::INDUCED_CRASH: + case URLLoadResult::LOADED_PRERENDER: + case URLLoadResult::RELOADED: + case URLLoadResult::NORMAL_LOAD: + // Page load was handled, so nothing else to do. + break; + } +} + +void UrlLoadingService::SwitchToTab( + const web::NavigationManager::WebLoadParams& web_params) { + DCHECK(delegate_); + // TODO(crbug.com/907527): chip at BVC::switchToTabWithParams by moving some + // of it here. + [delegate_ switchToTabWithParams:web_params]; +} + +void UrlLoadingService::OpenUrlInNewTab(OpenNewTabCommand* command) { + DCHECK(delegate_); + [delegate_ openURLInNewTabWithCommand:command]; +}
diff --git a/ios/chrome/browser/url_loading/url_loading_service_factory.h b/ios/chrome/browser/url_loading/url_loading_service_factory.h new file mode 100644 index 0000000..8c756e5 --- /dev/null +++ b/ios/chrome/browser/url_loading/url_loading_service_factory.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +namespace ios { +class ChromeBrowserState; +} + +class UrlLoadingService; + +// Singleton that owns all UrlLoadingServices and associates them with +// ios::ChromeBrowserState. +class UrlLoadingServiceFactory : public BrowserStateKeyedServiceFactory { + public: + static UrlLoadingService* GetForBrowserState( + ios::ChromeBrowserState* browser_state); + + static UrlLoadingServiceFactory* GetInstance(); + + private: + friend class base::NoDestructor<UrlLoadingServiceFactory>; + + UrlLoadingServiceFactory(); + ~UrlLoadingServiceFactory() override; + + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + web::BrowserState* GetBrowserStateToUse( + web::BrowserState* context) const override; + + DISALLOW_COPY_AND_ASSIGN(UrlLoadingServiceFactory); +}; + +#endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/url_loading/url_loading_service_factory.mm b/ios/chrome/browser/url_loading/url_loading_service_factory.mm new file mode 100644 index 0000000..bc82866a --- /dev/null +++ b/ios/chrome/browser/url_loading/url_loading_service_factory.mm
@@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/url_loading/url_loading_service_factory.h" + +#include "base/no_destructor.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/url_loading/url_loading_notifier_factory.h" +#include "ios/chrome/browser/url_loading/url_loading_service.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// static +UrlLoadingService* UrlLoadingServiceFactory::GetForBrowserState( + ios::ChromeBrowserState* browser_state) { + return static_cast<UrlLoadingService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +UrlLoadingServiceFactory* UrlLoadingServiceFactory::GetInstance() { + static base::NoDestructor<UrlLoadingServiceFactory> instance; + return instance.get(); +} + +UrlLoadingServiceFactory::UrlLoadingServiceFactory() + : BrowserStateKeyedServiceFactory( + "UrlLoadingService", + BrowserStateDependencyManager::GetInstance()) { + DependsOn(UrlLoadingNotifierFactory::GetInstance()); +} + +UrlLoadingServiceFactory::~UrlLoadingServiceFactory() {} + +std::unique_ptr<KeyedService> UrlLoadingServiceFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + return std::make_unique<UrlLoadingService>( + UrlLoadingNotifierFactory::GetForBrowserState(browser_state)); +} + +web::BrowserState* UrlLoadingServiceFactory::GetBrowserStateToUse( + web::BrowserState* context) const { + return GetBrowserStateOwnInstanceInIncognito(context); +}
diff --git a/ios/chrome/browser/url_loading/url_loading_util.h b/ios/chrome/browser/url_loading/url_loading_util.h index 57e4aed6..548799c 100644 --- a/ios/chrome/browser/url_loading/url_loading_util.h +++ b/ios/chrome/browser/url_loading/url_loading_util.h
@@ -19,7 +19,8 @@ namespace web { class WebState; } -class WebStateList; +class Browser; +class UrlLoadingNotifier; // Possible results from calling LoadURL(). enum class URLLoadResult { @@ -60,12 +61,11 @@ ios::ChromeBrowserState* browser_state); // Returns the result (as defined in the enum definition above) of initiating a -// URL load as defined in |chrome_params|, using |browser_state| and the active -// webState in |web_state_list|. |restorer| is provied for dependencies which -// may need to save the current session window. +// URL load as defined in |chrome_params|. +// TODO(crbug.com/907527): hoist into url_loading_service and remove +// URLLoadResult. URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, - ios::ChromeBrowserState* browser_state, - WebStateList* web_state_list, - id<SessionWindowRestoring> restorer); + Browser* browser, + UrlLoadingNotifier* notifier); #endif // IOS_CHROME_BROWSER_URL_LOADING_URL_LOADING_UTIL_H_
diff --git a/ios/chrome/browser/url_loading/url_loading_util.mm b/ios/chrome/browser/url_loading/url_loading_util.mm index ed31d50..3af451ae 100644 --- a/ios/chrome/browser/url_loading/url_loading_util.mm +++ b/ios/chrome/browser/url_loading/url_loading_util.mm
@@ -9,6 +9,7 @@ #include "components/sessions/core/tab_restore_service_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" +#import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/prerender/prerender_service.h" #import "ios/chrome/browser/prerender/prerender_service_factory.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" @@ -93,20 +94,17 @@ restoreService->RestoreEntryById(delegate, session_id, disposition); } -// TODO(crbug.com/907527): make this into a url loading service in this folder. URLLoadResult LoadURL(const ChromeLoadParams& chrome_params, - ios::ChromeBrowserState* browser_state, - WebStateList* web_state_list, - id<SessionWindowRestoring> restorer) { + Browser* browser, + UrlLoadingNotifier* notifier) { web::NavigationManager::WebLoadParams params = chrome_params.web_params; if (chrome_params.disposition == WindowOpenDisposition::SWITCH_TO_TAB) { return URLLoadResult::SWITCH_TO_TAB; } - UrlLoadingNotifier* urlLoadingNotifier = - ios::UrlLoadingNotifierFactory::GetForBrowserState(browser_state); + ios::ChromeBrowserState* browser_state = browser->GetBrowserState(); - urlLoadingNotifier->TabWillOpenUrl(params.url, params.transition_type); + notifier->TabWillOpenUrl(params.url, params.transition_type); // NOTE: This check for the Crash Host URL is here to avoid the URL from // ending up in the history causing the app to crash at every subsequent @@ -115,7 +113,7 @@ InduceBrowserCrash(params.url); // Under a debugger, the app can continue working even after the CHECK. // Adding a return avoids adding the crash url to history. - urlLoadingNotifier->TabFailedToOpenUrl(params.url, params.transition_type); + notifier->TabFailedToOpenUrl(params.url, params.transition_type); return URLLoadResult::INDUCED_CRASH; } @@ -123,17 +121,20 @@ // so. PrerenderService* prerenderService = PrerenderServiceFactory::GetForBrowserState(browser_state); + WebStateList* web_state_list = browser->GetWebStateList(); + id<SessionWindowRestoring> restorer = + (id<SessionWindowRestoring>)browser->GetTabModel(); if (prerenderService && prerenderService->MaybeLoadPrerenderedURL( params.url, params.transition_type, web_state_list, restorer)) { - urlLoadingNotifier->TabDidPrerenderUrl(params.url, params.transition_type); + notifier->TabDidPrerenderUrl(params.url, params.transition_type); return URLLoadResult::LOADED_PRERENDER; } // Some URLs are not allowed while in incognito. If we are in incognito and // load a disallowed URL, instead create a new tab not in the incognito state. if (browser_state->IsOffTheRecord() && !IsURLAllowedInIncognito(params.url)) { - urlLoadingNotifier->TabFailedToOpenUrl(params.url, params.transition_type); + notifier->TabFailedToOpenUrl(params.url, params.transition_type); return URLLoadResult::DISALLOWED_IN_INCOGNITO; } @@ -156,13 +157,13 @@ ui::PAGE_TRANSITION_RELOAD)) { current_web_state->GetNavigationManager()->Reload( web::ReloadType::NORMAL, true /* check_for_repost */); - urlLoadingNotifier->TabDidReloadUrl(params.url, params.transition_type); + notifier->TabDidReloadUrl(params.url, params.transition_type); return URLLoadResult::RELOADED; } current_web_state->GetNavigationManager()->LoadURLWithParams(params); - urlLoadingNotifier->TabDidOpenUrl(params.url, params.transition_type); + notifier->TabDidOpenUrl(params.url, params.transition_type); return URLLoadResult::NORMAL_LOAD; }
diff --git a/media/gpu/platform_video_frame.cc b/media/gpu/platform_video_frame.cc index ea89585..f3f345f 100644 --- a/media/gpu/platform_video_frame.cc +++ b/media/gpu/platform_video_frame.cc
@@ -39,34 +39,23 @@ const size_t num_planes = VideoFrame::NumPlanes(pixel_format); std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<size_t> buffer_sizes(num_planes); for (size_t i = 0; i < num_planes; ++i) { planes[i].stride = pixmap->GetDmaBufPitch(i); planes[i].offset = pixmap->GetDmaBufOffset(i); planes[i].modifier = pixmap->GetDmaBufModifier(i); + buffer_sizes[i] = planes[i].offset + + planes[i].stride * VideoFrame::Rows(i, pixel_format, + coded_size.height()); } - const size_t num_fds = pixmap->GetDmaBufFdCount(); - std::vector<size_t> buffer_sizes(num_fds, 0u); - // If the number of buffer sizes is less than number of planes, the buffer for - // plane #i (i > the number of fds) is the last buffer. - for (size_t i = 0; i < num_planes; ++i) { - size_t buffer_size = - planes[i].offset + - planes[i].stride * - VideoFrame::Rows(i, pixel_format, coded_size.height()); - if (i < num_fds) { - buffer_sizes[i] = buffer_size; - } else { - buffer_sizes.back() = std::max(buffer_sizes.back(), buffer_size); - } - } auto layout = VideoFrameLayout::CreateWithPlanes( pixel_format, coded_size, std::move(planes), std::move(buffer_sizes)); if (!layout) return nullptr; std::vector<base::ScopedFD> dmabuf_fds; - for (size_t i = 0; i < num_fds; ++i) { + for (size_t i = 0; i < num_planes; ++i) { int duped_fd = HANDLE_EINTR(dup(pixmap->GetDmaBufFd(i))); if (duped_fd == -1) { DLOG(ERROR) << "Failed duplicating dmabuf fd";
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index faa1af6..ce25aac 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -391,7 +391,7 @@ return; } - if (bytes_used >= GetPlaneSize(plane)) { + if (bytes_used > GetPlaneSize(plane)) { VLOGF(1) << "Set bytes used " << bytes_used << " larger than plane size " << GetPlaneSize(plane) << "."; return;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index 4336fd5..cfe2342e 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -1481,7 +1481,7 @@ return false; } - V4L2ReadableBufferRef buf = ret.second; + V4L2ReadableBufferRef buf(std::move(ret.second)); DCHECK_LT(buf->BufferId(), output_buffer_map_.size()); OutputRecord& output_record = output_buffer_map_[buf->BufferId()];
diff --git a/media/gpu/vaapi/h264_encoder.cc b/media/gpu/vaapi/h264_encoder.cc index 4367cbbb..242014e 100644 --- a/media/gpu/vaapi/h264_encoder.cc +++ b/media/gpu/vaapi/h264_encoder.cc
@@ -172,6 +172,8 @@ } if (pic->type == H264SliceHeader::kISlice) { + // We always generate SPS and PPS with I(DR) frame. This will help for Seek + // operation on the generated stream. if (!accelerator_->SubmitPackedHeaders(encode_job, packed_sps_, packed_pps_)) { DVLOGF(1) << "Failed submitting keyframe headers"; @@ -213,7 +215,19 @@ curr_params_.cpb_size_bits = curr_params_.bitrate_bps * curr_params_.cpb_window_size_ms / 1000; + bool previous_encoding_parameters_changed = encoding_parameters_changed_; + UpdateSPS(); + + // If SPS parameters are updated, it is required to send the SPS with IDR + // frame. However, as a special case, we do not generate IDR frame if only + // bitrate and framerate parameters are updated. This is safe because these + // will not make a difference on decoder processing. The updated SPS will be + // sent a next periodic or requested I(DR) frame. On the other hand, bitrate + // and framerate parameter + // changes must be affected for encoding. UpdateSPS()+SubmitFrameParameters() + // shall apply them to an encoder properly. + encoding_parameters_changed_ = previous_encoding_parameters_changed; return true; }
diff --git a/media/gpu/vaapi/h264_encoder.h b/media/gpu/vaapi/h264_encoder.h index 28bc033..ea0c24f 100644 --- a/media/gpu/vaapi/h264_encoder.h +++ b/media/gpu/vaapi/h264_encoder.h
@@ -147,8 +147,8 @@ // idr_pic_id (spec section 7.4.3) to be used for the next frame. unsigned int idr_pic_id_ = 0; - // True if encoding parameters have changed and we need to submit a keyframe - // with updated parameters. + // True if encoding parameters have changed that affect decoder process, then + // we need to submit a keyframe with updated parameters. bool encoding_parameters_changed_ = false; // Currently active reference frames.
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 93d7c98..28194690 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1010,32 +1010,23 @@ va_attrib_extbuf.width = size.width(); va_attrib_extbuf.height = size.height(); - size_t num_fds = pixmap->GetDmaBufFdCount(); size_t num_planes = gfx::NumberOfPlanesForBufferFormat(pixmap->GetBufferFormat()); - if (num_fds == 0 || num_fds > num_planes) { - LOG(ERROR) << "Invalid number of dmabuf fds: " << num_fds - << " , planes: " << num_planes; - return nullptr; - } - + std::vector<uintptr_t> fds(num_planes); for (size_t i = 0; i < num_planes; ++i) { va_attrib_extbuf.pitches[i] = pixmap->GetDmaBufPitch(i); va_attrib_extbuf.offsets[i] = pixmap->GetDmaBufOffset(i); - DVLOG(4) << "plane " << i << ": pitch: " << va_attrib_extbuf.pitches[i] - << " offset: " << va_attrib_extbuf.offsets[i]; - } - va_attrib_extbuf.num_planes = num_planes; - - std::vector<unsigned long> fds(num_fds); - for (size_t i = 0; i < num_fds; ++i) { int dmabuf_fd = pixmap->GetDmaBufFd(i); if (dmabuf_fd < 0) { LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap"; return nullptr; } - fds[i] = dmabuf_fd; + fds[i] = base::checked_cast<uintptr_t>(dmabuf_fd); + DVLOG(4) << "plane " << i << ": pitch: " << va_attrib_extbuf.pitches[i] + << " offset: " << va_attrib_extbuf.offsets[i]; } + + va_attrib_extbuf.num_planes = num_planes; va_attrib_extbuf.buffers = fds.data(); va_attrib_extbuf.num_buffers = fds.size();
diff --git a/services/identity/public/cpp/DEPS b/services/identity/public/cpp/DEPS index 1b82c02..0656b1e 100644 --- a/services/identity/public/cpp/DEPS +++ b/services/identity/public/cpp/DEPS
@@ -8,7 +8,6 @@ "+components/signin/core/browser/list_accounts_test_utils.h", "+components/signin/core/browser/account_consistency_method.h", "+components/signin/core/browser/signin_buildflags.h", - "+components/signin/core/browser/signin_internals_util.h", "+components/signin/core/browser/signin_metrics.h", "+components/signin/core/browser/signin_switches.h", "+components/signin/core/browser/ubertoken_fetcher_impl.h",
diff --git a/services/identity/public/cpp/accounts_mutator.h b/services/identity/public/cpp/accounts_mutator.h index 37a6bdd..414e143c 100644 --- a/services/identity/public/cpp/accounts_mutator.h +++ b/services/identity/public/cpp/accounts_mutator.h
@@ -61,6 +61,11 @@ const std::string& account_id) = 0; #endif + // Updates the refresh token for the supervised user. + // TODO(860492): Remove this once supervised user support is removed. + virtual void LegacySetRefreshTokenForSupervisedUser( + const std::string& refresh_token) = 0; + private: DISALLOW_COPY_AND_ASSIGN(AccountsMutator); };
diff --git a/services/identity/public/cpp/accounts_mutator_impl.cc b/services/identity/public/cpp/accounts_mutator_impl.cc index bd64f3f..b5808ad 100644 --- a/services/identity/public/cpp/accounts_mutator_impl.cc +++ b/services/identity/public/cpp/accounts_mutator_impl.cc
@@ -4,6 +4,8 @@ #include "services/identity/public/cpp/accounts_mutator_impl.h" +#include <string> + #include "base/logging.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" @@ -90,4 +92,11 @@ } #endif +void AccountsMutatorImpl::LegacySetRefreshTokenForSupervisedUser( + const std::string& refresh_token) { + token_service_->UpdateCredentials( + "managed_user@localhost", refresh_token, + signin_metrics::SourceForRefreshTokenOperation::kSupervisedUser_InitSync); +} + } // namespace identity
diff --git a/services/identity/public/cpp/accounts_mutator_impl.h b/services/identity/public/cpp/accounts_mutator_impl.h index 3fbe9743..f93ac01 100644 --- a/services/identity/public/cpp/accounts_mutator_impl.h +++ b/services/identity/public/cpp/accounts_mutator_impl.h
@@ -5,6 +5,8 @@ #ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_MUTATOR_IMPL_H_ #define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_MUTATOR_IMPL_H_ +#include <string> + #include "base/macros.h" #include "components/signin/core/browser/signin_metrics.h" #include "services/identity/public/cpp/accounts_mutator.h" @@ -63,6 +65,11 @@ const std::string& account_id) override; #endif + // Updates the refresh token for the supervised user. + // TODO(860492): Remove this once supervised user support is removed. + void LegacySetRefreshTokenForSupervisedUser( + const std::string& refresh_token) override; + private: ProfileOAuth2TokenService* token_service_; AccountTrackerService* account_tracker_service_;
diff --git a/services/identity/public/cpp/accounts_mutator_unittest.cc b/services/identity/public/cpp/accounts_mutator_unittest.cc index 9856444..2f725a50 100644 --- a/services/identity/public/cpp/accounts_mutator_unittest.cc +++ b/services/identity/public/cpp/accounts_mutator_unittest.cc
@@ -23,6 +23,7 @@ const char kTestEmail2[] = "test_user@test-2.com"; const char kRefreshToken[] = "refresh_token"; const char kRefreshToken2[] = "refresh_token_2"; +const char kSupervisedUserPseudoEmail[] = "managed_user@localhost"; // Class that observes updates from identity::IdentityManager. class TestIdentityManagerObserver : public identity::IdentityManager::Observer { @@ -607,4 +608,39 @@ } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) +TEST_F(AccountsMutatorTest, LegacySetRefreshTokenForSupervisedUser) { + // Abort the test if the current platform does not support accounts mutation. + if (!accounts_mutator()) + return; + + EXPECT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 0U); + + base::RunLoop run_loop; + identity_manager_observer()->set_on_refresh_token_updated_callback( + base::BindOnce( + [](base::OnceClosure quit_closure, const std::string& account_id) { + std::move(quit_closure).Run(); + }, + run_loop.QuitClosure())); + + accounts_mutator()->LegacySetRefreshTokenForSupervisedUser(kRefreshToken); + run_loop.Run(); + + // In the context of supervised users, the ProfileOAuth2TokenService is used + // without the AccountTrackerService being used, so we can't use any of the + // IdentityManager::FindAccountInfoForAccountWithRefreshTokenBy*() methods + // since they won't find any account. Use GetAccountsWithRefreshTokens() and + // HasAccountWithRefreshToken*() instead, that only relies in the PO2TS. + std::vector<AccountInfo> accounts = + identity_manager()->GetAccountsWithRefreshTokens(); + EXPECT_EQ(accounts.size(), 1U); + EXPECT_EQ(accounts[0].account_id, kSupervisedUserPseudoEmail); + EXPECT_EQ(accounts[0].email, kSupervisedUserPseudoEmail); + EXPECT_TRUE( + identity_manager()->HasAccountWithRefreshToken(accounts[0].account_id)); + EXPECT_FALSE( + identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState( + accounts[0].account_id)); +} + } // namespace identity
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index bf5dca6..1d535794 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -10,7 +10,6 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/ubertoken_fetcher.h" @@ -400,6 +399,9 @@ friend void DisableAccessTokenFetchRetries(IdentityManager* identity_manager); + friend void CancelAllOngoingGaiaCookieOperations( + IdentityManager* identity_manager); + friend void SetCookieAccounts( IdentityManager* identity_manager, network::TestURLLoaderFactory* test_url_loader_factory,
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index c5e0ecb..3a63914a 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -394,4 +394,8 @@ ->set_max_authorization_token_fetch_retries_for_testing(0); } +void CancelAllOngoingGaiaCookieOperations(IdentityManager* identity_manager) { + identity_manager->GetGaiaCookieManagerService()->CancelAll(); +} + } // namespace identity
diff --git a/services/identity/public/cpp/identity_test_utils.h b/services/identity/public/cpp/identity_test_utils.h index a3140b4..e238ff6 100644 --- a/services/identity/public/cpp/identity_test_utils.h +++ b/services/identity/public/cpp/identity_test_utils.h
@@ -154,6 +154,9 @@ // Disables internal retries of failed access token fetches. void DisableAccessTokenFetchRetries(IdentityManager* identity_manager); +// Cancels all ongoing operations related to the accounts in the Gaia cookie. +void CancelAllOngoingGaiaCookieOperations(IdentityManager* identity_manager); + } // namespace identity #endif // SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_TEST_UTILS_H_
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 15baa9b..08e0bfed 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1865,6 +1865,8 @@ session_params.http_09_on_non_default_ports_enabled = params_->http_09_on_non_default_ports_enabled; + session_params.disable_idle_sockets_close_on_memory_pressure = + params_->disable_idle_sockets_close_on_memory_pressure; builder->set_http_network_session_params(session_params);
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index c4b0b6e..1401e2c6 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -207,6 +207,9 @@ // Enables HTTP/0.9 on ports other than 80 for HTTP and 443 for HTTPS. bool http_09_on_non_default_ports_enabled = false; + // If true, idle sockets won't be closed when memory pressure happens. + bool disable_idle_sockets_close_on_memory_pressure = false; + // SSL configuration. |initial_proxy_config| is the initial SSL configuration // to use. If nullptr, uses the default configuration. Updated SSL // configurations can be passed in via |ssl_config_client_request|.
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index feda865..16c598c7 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/single_thread_task_runner.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" @@ -252,17 +253,19 @@ response_to_pass->socket_address = response->socket_address; size_t iter = 0; std::string name, value; + std::string headers_text = + base::StrCat({response->headers->GetStatusLine(), "\r\n"}); while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) { if (can_read_raw_cookies || !net::HttpResponseHeaders::IsCookieResponseHeader(name)) { // We drop cookie-related headers such as "set-cookie" when the // renderer doesn't have access. response_to_pass->headers.push_back(mojom::HttpHeader::New(name, value)); + base::StrAppend(&headers_text, {name, ": ", value, "\r\n"}); } } - response_to_pass->headers_text = - net::HttpUtil::ConvertHeadersBackToHTTPResponse( - response->headers->raw_headers()); + headers_text.append("\r\n"); + response_to_pass->headers_text = headers_text; impl_->client_->OnFinishOpeningHandshake(std::move(response_to_pass)); }
diff --git a/testing/buildbot/filters/webui_polymer2_browser_tests.filter b/testing/buildbot/filters/webui_polymer2_browser_tests.filter index 6cf3c55..3458bfb7 100644 --- a/testing/buildbot/filters/webui_polymer2_browser_tests.filter +++ b/testing/buildbot/filters/webui_polymer2_browser_tests.filter
@@ -158,6 +158,7 @@ CrSettingsMultideviceFeatureToggleTest.* CrSettingsMultidevicePageContainerTest.* CrSettingsMultidevicePageTest.* +CrSettingsMultideviceSmartLockSubpageTest.* CrSettingsMultideviceSubpageTest.* CrSettingsNonExistentRouteTest.* CrSettingsOnStartupPageTest.*
diff --git a/third_party/.gitignore b/third_party/.gitignore index 0801e31..be7b678 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -21,6 +21,7 @@ /android_tools/ /android_tools_internal/ /android_webview_glue/src +/androidx/lib/ /angle /angle_dx11 /apache-portable-runtime/src
diff --git a/third_party/blink/public/mojom/cache_storage/cache_storage.mojom b/third_party/blink/public/mojom/cache_storage/cache_storage.mojom index db98a3e..0d1387b 100644 --- a/third_party/blink/public/mojom/cache_storage/cache_storage.mojom +++ b/third_party/blink/public/mojom/cache_storage/cache_storage.mojom
@@ -39,9 +39,14 @@ // Controls how requests are matched in the Cache API. struct QueryParams { - bool ignore_search; - bool ignore_method; - bool ignore_vary; + bool ignore_search = false; + bool ignore_method = false; + bool ignore_vary = false; +}; + +// Controls how requests are matched in the CacheStorage API. +struct MultiQueryParams { + QueryParams query_params; mojo_base.mojom.String16? cache_name; }; @@ -135,7 +140,7 @@ // Returns the first cached response that matches |request| and // |match_params|. It can search on all caches if |cache_name| isn't provided // on |match_params|. - Match(blink.mojom.FetchAPIRequest request, QueryParams match_params) + Match(blink.mojom.FetchAPIRequest request, MultiQueryParams match_params) => (MatchResult result); // Opens and returns a mojo interface to a cache, it creates if doesn't exist.
diff --git a/third_party/blink/public/platform/modules/mediastream/OWNERS b/third_party/blink/public/platform/modules/mediastream/OWNERS new file mode 100644 index 0000000..c205d4f9 --- /dev/null +++ b/third_party/blink/public/platform/modules/mediastream/OWNERS
@@ -0,0 +1,6 @@ +file://third_party/blink/common/mediastream/OWNERS + +per-file media_stream_audio_processor*=aluebs@chromium.org + +# TEAM: media-capture-and-streams@grotations.appspotmail.com +# COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni index 9e3cff07..b4b12a1 100644 --- a/third_party/blink/renderer/core/core_idl_files.gni +++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -328,6 +328,8 @@ "streams/readable_stream.idl", "streams/transform_stream.idl", "streams/writable_stream.idl", + "streams/writable_stream_default_controller.idl", + "streams/writable_stream_default_writer.idl", "streams/underlying_source_base.idl", "svg/svg_a_element.idl", "svg/svg_angle.idl",
diff --git a/third_party/blink/renderer/core/dom/idle_deadline_test.cc b/third_party/blink/renderer/core/dom/idle_deadline_test.cc index 5c04f0f..865bb5e 100644 --- a/third_party/blink/renderer/core/dom/idle_deadline_test.cc +++ b/third_party/blink/renderer/core/dom/idle_deadline_test.cc
@@ -40,6 +40,10 @@ scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override { return nullptr; } + scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner() + override { + return nullptr; + } std::unique_ptr<RendererPauseHandle> PauseScheduler() override { return nullptr; }
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc index f910b5f..7ea93e71 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
@@ -34,6 +34,10 @@ scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override { return nullptr; } + scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner() + override { + return nullptr; + } void Shutdown() override {} bool ShouldYieldForHighPriorityWork() override { return should_yield_; } bool CanExceedIdleDeadlineIfRequired() const override { return false; }
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/third_party/blink/renderer/core/editing/finder/find_buffer.cc index 6030414..3208ecbf 100644 --- a/third_party/blink/renderer/core/editing/finder/find_buffer.cc +++ b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -38,7 +38,7 @@ // We need to own the |search_text| because |text_searcher_| only has a // StringView (doesn't own the search text). search_text_ = search_text; - text_searcher_.SetPattern(search_text_, !(options & kCaseInsensitive)); + text_searcher_.SetPattern(search_text_, options); text_searcher_.SetText(buffer.data(), buffer.size()); text_searcher_.SetOffset(0); }
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.h b/third_party/blink/renderer/core/editing/finder/find_buffer.h index 439627b..c2c184e 100644 --- a/third_party/blink/renderer/core/editing/finder/find_buffer.h +++ b/third_party/blink/renderer/core/editing/finder/find_buffer.h
@@ -73,9 +73,9 @@ unsigned CountForTesting(); private: - bool empty_result_ = false; String search_text_; TextSearcherICU text_searcher_; + bool empty_result_ = false; }; // Finds all the match for |search_text| in |buffer_|.
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc b/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc index 32f4c47..4776890 100644 --- a/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc +++ b/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc
@@ -441,6 +441,21 @@ buffer.FindMatches("ラキナ", kCaseInsensitive)->CountForTesting()); } +TEST_F(FindBufferTest, WholeWordTest) { + SetBodyContent("foo bar foobar 六本木"); + FindBuffer buffer(WholeDocumentRange()); + EXPECT_EQ(2u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting()); + EXPECT_EQ(1u, buffer.FindMatches("foo", kCaseInsensitive | kWholeWord) + ->CountForTesting()); + EXPECT_EQ(2u, buffer.FindMatches("bar", kCaseInsensitive)->CountForTesting()); + EXPECT_EQ(1u, buffer.FindMatches("bar", kCaseInsensitive | kWholeWord) + ->CountForTesting()); + EXPECT_EQ(1u, buffer.FindMatches("六", kCaseInsensitive | kWholeWord) + ->CountForTesting()); + EXPECT_EQ(1u, buffer.FindMatches("本木", kCaseInsensitive | kWholeWord) + ->CountForTesting()); +} + TEST_F(FindBufferTest, KanaDecomposed) { SetBodyContent("は ゛"); FindBuffer buffer(WholeDocumentRange());
diff --git a/third_party/blink/renderer/core/editing/iterators/search_buffer.cc b/third_party/blink/renderer/core/editing/iterators/search_buffer.cc index 4e85eb0..dc6a314 100644 --- a/third_party/blink/renderer/core/editing/iterators/search_buffer.cc +++ b/third_party/blink/renderer/core/editing/iterators/search_buffer.cc
@@ -86,7 +86,7 @@ text_searcher_ = std::make_unique<TextSearcherICU>(); text_searcher_->SetPattern(StringView(target_.data(), target_.size()), - !(options_ & kCaseInsensitive)); + options_); // The kana workaround requires a normalized copy of the target string. if (target_requires_kana_workaround_)
diff --git a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc index 4d16b13..58e387e 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.cc
@@ -29,6 +29,8 @@ #include <unicode/usearch.h> #include "base/macros.h" +#include "third_party/blink/renderer/platform/text/character.h" +#include "third_party/blink/renderer/platform/text/text_boundaries.h" #include "third_party/blink/renderer/platform/text/text_break_iterator_internal_icu.h" #include "third_party/blink/renderer/platform/text/unicode_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" @@ -96,6 +98,30 @@ } // namespace +static bool IsWholeWordMatch(const UChar* text, + int text_length, + MatchResultICU& result) { + DCHECK_LE((int)(result.start + result.length), text_length); + UChar32 first_character; + U16_GET(text, 0, result.start, result.length, first_character); + + // Chinese and Japanese lack word boundary marks, and there is no clear + // agreement on what constitutes a word, so treat the position before any CJK + // character as a word start. + if (Character::IsCJKIdeographOrSymbol(first_character)) + return true; + + wtf_size_t word_break_search_start = result.start + result.length; + while (word_break_search_start > result.start) { + word_break_search_start = + FindNextWordBackward(text, text_length, word_break_search_start); + } + if (word_break_search_start != result.start) + return false; + return static_cast<int>(result.start + result.length) == + FindWordEndBoundary(text, text_length, word_break_search_start); +} + // Grab the single global searcher. // If we ever have a reason to do more than once search buffer at once, we'll // have to move to multiple searchers. @@ -112,8 +138,9 @@ } void TextSearcherICU::SetPattern(const StringView& pattern, - bool case_sensitive) { - SetCaseSensitivity(case_sensitive); + FindOptions options) { + options_ = options; + SetCaseSensitivity(!(options & kCaseInsensitive)); SetPattern(pattern.Characters16(), pattern.length()); if (ContainsKanaLetters(pattern.ToString())) { NormalizeCharactersIntoNFCForm(pattern.Characters16(), pattern.length(), @@ -163,17 +190,25 @@ } bool TextSearcherICU::ShouldSkipCurrentMatch(MatchResultICU& result) const { - if (normalized_search_text_.IsEmpty()) - return false; - Vector<UChar> normalized_match; int32_t text_length; const UChar* text = usearch_getText(searcher_, &text_length); DCHECK_LE((int32_t)(result.start + result.length), text_length); + DCHECK_GT(result.length, 0u); + if (!normalized_search_text_.IsEmpty() && !IsCorrectKanaMatch(text, result)) + return true; + + if ((options_ & kWholeWord) && !IsWholeWordMatch(text, text_length, result)) + return true; + return false; +} + +bool TextSearcherICU::IsCorrectKanaMatch(const UChar* text, + MatchResultICU& result) const { + Vector<UChar> normalized_match; NormalizeCharactersIntoNFCForm(text + result.start, result.length, normalized_match); - - return !CheckOnlyKanaLettersInStrings( + return CheckOnlyKanaLettersInStrings( normalized_search_text_.data(), normalized_search_text_.size(), normalized_match.begin(), normalized_match.size()); }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h index 917a8ae..1e6cdf1 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h +++ b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/editing/finder/find_options.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h" @@ -24,7 +25,7 @@ TextSearcherICU(); ~TextSearcherICU(); - void SetPattern(const StringView& pattern, bool sensitive); + void SetPattern(const StringView& pattern, FindOptions options); void SetText(const UChar* text, wtf_size_t length); void SetOffset(wtf_size_t); bool NextMatchResult(MatchResultICU&); @@ -34,10 +35,12 @@ void SetCaseSensitivity(bool case_sensitive); bool ShouldSkipCurrentMatch(MatchResultICU&) const; bool NextMatchResultInternal(MatchResultICU&); + bool IsCorrectKanaMatch(const UChar* text, MatchResultICU&) const; UStringSearch* searcher_ = nullptr; wtf_size_t text_length_ = 0; Vector<UChar> normalized_search_text_; + FindOptions options_; DISALLOW_COPY_AND_ASSIGN(TextSearcherICU); };
diff --git a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc index 8041b0f2..336507c 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_searcher_icu_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/editing/finder/find_options.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -23,7 +24,7 @@ TEST(TextSearcherICUTest, FindSubstring) { TextSearcherICU searcher; const String& pattern = MakeUTF16("substring"); - searcher.SetPattern(pattern, true); + searcher.SetPattern(pattern, 0); const String& text = MakeUTF16("Long text with substring content."); searcher.SetText(text.Characters16(), text.length()); @@ -44,7 +45,7 @@ TEST(TextSearcherICUTest, FindIgnoreCaseSubstring) { TextSearcherICU searcher; const String& pattern = MakeUTF16("substring"); - searcher.SetPattern(pattern, false); + searcher.SetPattern(pattern, kCaseInsensitive); const String& text = MakeUTF16("Long text with SubStrinG content."); searcher.SetText(text.Characters16(), text.length()); @@ -57,7 +58,7 @@ EXPECT_EQ(pattern, text.Substring(result.start, result.length).DeprecatedLower()); - searcher.SetPattern(pattern, true); + searcher.SetPattern(pattern, 0); searcher.SetOffset(0u); EXPECT_FALSE(searcher.NextMatchResult(result)); EXPECT_EQ(0u, result.start); @@ -67,7 +68,7 @@ TEST(TextSearcherICUTest, FindSubstringWithOffset) { TextSearcherICU searcher; const String& pattern = MakeUTF16("substring"); - searcher.SetPattern(pattern, true); + searcher.SetPattern(pattern, 0); const String& text = MakeUTF16("Long text with substring content. Second substring");
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc index 1b56a06..1923757 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc +++ b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
@@ -80,7 +80,7 @@ formatter_.AppendAttributeValue(result, ToAttr(node).value(), false); break; default: - formatter_.AppendStartMarkup(result, node, namespaces); + formatter_.AppendStartMarkup(result, node); break; } } @@ -138,7 +138,12 @@ void MarkupAccumulator::AppendOpenTag(StringBuilder& result, const Element& element, Namespaces* namespaces) { - formatter_.AppendOpenTag(result, element, namespaces); + formatter_.AppendOpenTag(result, element); + if (!SerializeAsHTMLDocument(element) && namespaces && + ShouldAddNamespaceElement(element, *namespaces)) { + MarkupFormatter::AppendNamespace(result, element.prefix(), + element.namespaceURI(), *namespaces); + } } void MarkupAccumulator::AppendCloseTag(StringBuilder& result, @@ -161,6 +166,22 @@ return formatter_.SerializeAsHTMLDocument(node); } +bool MarkupAccumulator::ShouldAddNamespaceElement( + const Element& element, + Namespaces& namespaces) const { + // Don't add namespace attribute if it is already defined for this elem. + const AtomicString& prefix = element.prefix(); + if (prefix.IsEmpty()) { + if (element.hasAttribute(g_xmlns_atom)) { + namespaces.Set(g_empty_atom, element.namespaceURI()); + return false; + } + return true; + } + + return !element.hasAttribute(WTF::g_xmlns_with_colon + prefix); +} + std::pair<Node*, Element*> MarkupAccumulator::GetAuxiliaryDOMTree( const Element& element) const { return std::pair<Node*, Element*>();
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h index 54ed11c..fb81f82 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h +++ b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
@@ -84,6 +84,8 @@ virtual std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const; private: + bool ShouldAddNamespaceElement(const Element&, Namespaces&) const; + MarkupFormatter formatter_; StringBuilder markup_;
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc index 22362102..4ab2840 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc +++ b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
@@ -131,25 +131,28 @@ MarkupFormatter::~MarkupFormatter() = default; String MarkupFormatter::ResolveURLIfNeeded(const Element& element, - const String& url_string) const { + const Attribute& attribute) const { + String value = attribute.Value(); switch (resolve_urls_method_) { case kResolveAllURLs: - return element.GetDocument().CompleteURL(url_string).GetString(); + if (element.IsURLAttribute(attribute)) + return element.GetDocument().CompleteURL(value).GetString(); + break; case kResolveNonLocalURLs: - if (!element.GetDocument().Url().IsLocalFile()) - return element.GetDocument().CompleteURL(url_string).GetString(); + if (element.IsURLAttribute(attribute) && + !element.GetDocument().Url().IsLocalFile()) + return element.GetDocument().CompleteURL(value).GetString(); break; case kDoNotResolveURLs: break; } - return url_string; + return value; } void MarkupFormatter::AppendStartMarkup(StringBuilder& result, - const Node& node, - Namespaces* namespaces) { + const Node& node) { switch (node.getNodeType()) { case Node::kTextNode: NOTREACHED(); @@ -308,14 +311,9 @@ } void MarkupFormatter::AppendOpenTag(StringBuilder& result, - const Element& element, - Namespaces* namespaces) { + const Element& element) { result.Append('<'); result.Append(element.TagQName().ToString()); - if (!SerializeAsHTMLDocument(element) && namespaces && - ShouldAddNamespaceElement(element, *namespaces)) - AppendNamespace(result, element.prefix(), element.namespaceURI(), - *namespaces); } void MarkupFormatter::AppendCloseTag(StringBuilder& result, @@ -332,91 +330,124 @@ const Element& element, const Attribute& attribute, Namespaces* namespaces) { - bool document_is_html = SerializeAsHTMLDocument(element); - String value = attribute.Value(); - if (element.IsURLAttribute(attribute)) { - // FIXME: This does not fully match other browsers. Firefox percent-escapes - // non-ASCII characters for innerHTML. - value = ResolveURLIfNeeded(element, value); - } - - if (document_is_html) { - // https://html.spec.whatwg.org/multipage/parsing.html#attribute's-serialised-name - QualifiedName prefixed_name = attribute.GetName(); - if (attribute.NamespaceURI() == xmlns_names::kNamespaceURI) { - if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) - prefixed_name.SetPrefix(g_xmlns_atom); - } else if (attribute.NamespaceURI() == xml_names::kNamespaceURI) { - prefixed_name.SetPrefix(g_xml_atom); - } else if (attribute.NamespaceURI() == xlink_names::kNamespaceURI) { - prefixed_name.SetPrefix(g_xlink_atom); - } - AppendAttribute(result, prefixed_name.Prefix(), prefixed_name.LocalName(), - value, document_is_html); + String value = ResolveURLIfNeeded(element, attribute); + if (SerializeAsHTMLDocument(element)) { + AppendAttributeAsHTML(result, attribute, value); + } else if (!namespaces) { + AppendAttributeAsXMLWithoutNamespace(result, attribute, value); } else { - // https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes + AppendAttributeAsXMLWithNamespace(result, element, attribute, value, + *namespaces); + } +} - // 3.3. Let attribute namespace be the value of attr's namespaceURI value. - const AtomicString& attribute_namespace = attribute.NamespaceURI(); +void MarkupFormatter::AppendAttributeAsHTML(StringBuilder& result, + const Attribute& attribute, + const String& value) { + // https://html.spec.whatwg.org/multipage/parsing.html#attribute's-serialised-name + QualifiedName prefixed_name = attribute.GetName(); + if (attribute.NamespaceURI() == xmlns_names::kNamespaceURI) { + if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) + prefixed_name.SetPrefix(g_xmlns_atom); + } else if (attribute.NamespaceURI() == xml_names::kNamespaceURI) { + prefixed_name.SetPrefix(g_xml_atom); + } else if (attribute.NamespaceURI() == xlink_names::kNamespaceURI) { + prefixed_name.SetPrefix(g_xlink_atom); + } + AppendAttribute(result, prefixed_name.Prefix(), prefixed_name.LocalName(), + value, true); +} - // 3.4. Let candidate prefix be null. - AtomicString candidate_prefix; +void MarkupFormatter::AppendAttributeAsXMLWithoutNamespace( + StringBuilder& result, + const Attribute& attribute, + const String& value) { + const AtomicString& attribute_namespace = attribute.NamespaceURI(); + AtomicString candidate_prefix = attribute.Prefix(); + if (attribute_namespace == xmlns_names::kNamespaceURI) { + if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) + candidate_prefix = g_xmlns_atom; + } else if (attribute_namespace == xml_names::kNamespaceURI) { + if (!candidate_prefix) + candidate_prefix = g_xml_atom; + } else if (attribute_namespace == xlink_names::kNamespaceURI) { + if (!candidate_prefix) + candidate_prefix = g_xlink_atom; + } + AppendAttribute(result, candidate_prefix, attribute.LocalName(), value, + false); +} - // 3.5. If attribute namespace is not null, then run these sub-steps: +void MarkupFormatter::AppendAttributeAsXMLWithNamespace( + StringBuilder& result, + const Element& element, + const Attribute& attribute, + const String& value, + Namespaces& namespaces) { + // https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes - // 3.5.1. Let candidate prefix be the result of retrieving a preferred - // prefix string from map given namespace attribute namespace with preferred - // prefix being attr's prefix value. - // TODO(tkent): Implement it. crbug.com/906807 - candidate_prefix = attribute.Prefix(); + // 3.3. Let attribute namespace be the value of attr's namespaceURI value. + const AtomicString& attribute_namespace = attribute.NamespaceURI(); - // 3.5.2. If the value of attribute namespace is the XMLNS namespace, then - // run these steps: - if (attribute_namespace == xmlns_names::kNamespaceURI) { - if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) - candidate_prefix = g_xmlns_atom; - // Account for the namespace attribute we're about to append. - if (namespaces) { - const AtomicString& lookup_key = - (!attribute.Prefix()) ? g_empty_atom : attribute.LocalName(); - namespaces->Set(lookup_key, attribute.Value()); - } - } else if (attribute_namespace == xml_names::kNamespaceURI) { + // 3.4. Let candidate prefix be null. + AtomicString candidate_prefix; + + // 3.5. If attribute namespace is not null, then run these sub-steps: + + // 3.5.1. Let candidate prefix be the result of retrieving a preferred + // prefix string from map given namespace attribute namespace with preferred + // prefix being attr's prefix value. + // TODO(tkent): Implement it. crbug.com/906807 + candidate_prefix = attribute.Prefix(); + + // 3.5.2. If the value of attribute namespace is the XMLNS namespace, then + // run these steps: + if (attribute_namespace == xmlns_names::kNamespaceURI) { + if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) + candidate_prefix = g_xmlns_atom; + // Account for the namespace attribute we're about to append. + const AtomicString& lookup_key = + (!attribute.Prefix()) ? g_empty_atom : attribute.LocalName(); + namespaces.Set(lookup_key, attribute.Value()); + } else if (attribute_namespace == xml_names::kNamespaceURI) { + // TODO(tkent): Remove this block when we implement 'retrieving a + // preferred prefix string'. + if (!candidate_prefix) + candidate_prefix = g_xml_atom; + } else { + // TODO(tkent): Remove this block. The standard and Firefox don't + // have this behavior. + if (attribute_namespace == xlink_names::kNamespaceURI) { if (!candidate_prefix) - candidate_prefix = g_xml_atom; - } else { - if (attribute_namespace == xlink_names::kNamespaceURI) { - if (!candidate_prefix) - candidate_prefix = g_xlink_atom; - } + candidate_prefix = g_xlink_atom; + } - // 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. - // Run these steps: - if (namespaces && ShouldAddNamespaceAttribute(attribute, element)) { - if (!candidate_prefix) { - // This behavior is in process of being standardized. See - // crbug.com/248044 and - // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208 - String prefix_prefix("ns", 2u); - for (unsigned i = attribute_namespace.Impl()->ExistingHash();; ++i) { - AtomicString new_prefix(String(prefix_prefix + String::Number(i))); - AtomicString found_uri = namespaces->at(new_prefix); - if (found_uri == attribute_namespace || found_uri == g_null_atom) { - // We already generated a prefix for this namespace. - candidate_prefix = new_prefix; - break; - } + // 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. + // Run these steps: + if (ShouldAddNamespaceAttribute(attribute, element)) { + if (!candidate_prefix) { + // This behavior is in process of being standardized. See + // crbug.com/248044 and + // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208 + String prefix_prefix("ns", 2u); + for (unsigned i = attribute_namespace.Impl()->ExistingHash();; ++i) { + AtomicString new_prefix(String(prefix_prefix + String::Number(i))); + AtomicString found_uri = namespaces.at(new_prefix); + if (found_uri == attribute_namespace || found_uri == g_null_atom) { + // We already generated a prefix for this namespace. + candidate_prefix = new_prefix; + break; } } - // 3.5.3.2. Append the following to result, in the order listed: - DCHECK(candidate_prefix); - AppendNamespace(result, candidate_prefix, attribute_namespace, - *namespaces); } + // 3.5.3.2. Append the following to result, in the order listed: + DCHECK(candidate_prefix); + AppendNamespace(result, candidate_prefix, attribute_namespace, + namespaces); } - AppendAttribute(result, candidate_prefix, attribute.LocalName(), value, - document_is_html); } + AppendAttribute(result, candidate_prefix, attribute.LocalName(), value, + false); } void MarkupFormatter::AppendCDATASection(StringBuilder& result, @@ -428,24 +459,8 @@ result.Append("]]>"); } -bool MarkupFormatter::ShouldAddNamespaceElement(const Element& element, - Namespaces& namespaces) const { - // Don't add namespace attribute if it is already defined for this elem. - const AtomicString& prefix = element.prefix(); - if (prefix.IsEmpty()) { - if (element.hasAttribute(g_xmlns_atom)) { - namespaces.Set(g_empty_atom, element.namespaceURI()); - return false; - } - return true; - } - - return !element.hasAttribute(WTF::g_xmlns_with_colon + prefix); -} - -bool MarkupFormatter::ShouldAddNamespaceAttribute( - const Attribute& attribute, - const Element& element) const { +bool MarkupFormatter::ShouldAddNamespaceAttribute(const Attribute& attribute, + const Element& element) { // xmlns and xmlns:prefix attributes should be handled by another branch in // appendAttribute. DCHECK_NE(attribute.NamespaceURI(), xmlns_names::kNamespaceURI);
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_formatter.h b/third_party/blink/renderer/core/editing/serializers/markup_formatter.h index 78b1ca2..2da2657 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_formatter.h +++ b/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
@@ -99,26 +99,36 @@ SerializationType = SerializationType::kAsOwnerDocument); ~MarkupFormatter(); - void AppendStartMarkup(StringBuilder&, const Node&, Namespaces*); + void AppendStartMarkup(StringBuilder&, const Node&); void AppendEndMarkup(StringBuilder&, const Element&); bool SerializeAsHTMLDocument(const Node&) const; void AppendText(StringBuilder&, Text&); - void AppendOpenTag(StringBuilder&, const Element&, Namespaces*); + void AppendOpenTag(StringBuilder&, const Element&); void AppendCloseTag(StringBuilder&, const Element&); void AppendAttribute(StringBuilder&, const Element&, const Attribute&, Namespaces*); - bool ShouldAddNamespaceElement(const Element&, Namespaces&) const; - bool ShouldAddNamespaceAttribute(const Attribute&, const Element&) const; + static bool ShouldAddNamespaceAttribute(const Attribute&, const Element&); EntityMask EntityMaskForText(const Text&) const; bool ShouldSelfClose(const Element&) const; private: - String ResolveURLIfNeeded(const Element&, const String&) const; + String ResolveURLIfNeeded(const Element&, const Attribute& attribute) const; + static void AppendAttributeAsHTML(StringBuilder& result, + const Attribute& attribute, + const String& value); + static void AppendAttributeAsXMLWithoutNamespace(StringBuilder& result, + const Attribute& attribute, + const String& value); + static void AppendAttributeAsXMLWithNamespace(StringBuilder& result, + const Element& element, + const Attribute& attribute, + const String& value, + Namespaces& namespaces); const EAbsoluteURLs resolve_urls_method_; SerializationType serialization_type_;
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc index fb27d4ca..4c105bf 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc
@@ -70,7 +70,7 @@ } void StyledMarkupAccumulator::AppendStartMarkup(Node& node) { - formatter_.AppendStartMarkup(result_, node, nullptr); + formatter_.AppendStartMarkup(result_, node); } void StyledMarkupAccumulator::AppendEndMarkup(StringBuilder& result, @@ -139,7 +139,7 @@ const Element& element, EditingStyle* style) { const bool document_is_html = element.GetDocument().IsHTMLDocument(); - formatter_.AppendOpenTag(out, element, nullptr); + formatter_.AppendOpenTag(out, element); AttributeCollection attributes = element.Attributes(); for (const auto& attribute : attributes) { // We'll handle the style attribute separately, below. @@ -162,7 +162,7 @@ void StyledMarkupAccumulator::AppendElement(StringBuilder& out, const Element& element) { - formatter_.AppendOpenTag(out, element, nullptr); + formatter_.AppendOpenTag(out, element); AttributeCollection attributes = element.Attributes(); for (const auto& attribute : attributes) formatter_.AppendAttribute(out, element, attribute, nullptr);
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.cc b/third_party/blink/renderer/core/fileapi/file_reader.cc index 7b595c4..bbb53cb 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -316,7 +316,9 @@ DCHECK_EQ(loading_state_, kLoadingStatePending); loading_state_ = kLoadingStateLoading; - loader_ = FileReaderLoader::Create(read_type_, this); + loader_ = std::make_unique<FileReaderLoader>( + read_type_, this, + GetExecutionContext()->GetTaskRunner(TaskType::kFileReading)); loader_->SetEncoding(encoding_); loader_->SetDataType(blob_type_); loader_->Start(blob_data_handle_);
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc index 5a1cc40..c197684 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -62,21 +62,17 @@ namespace blink { -// static -std::unique_ptr<FileReaderLoader> FileReaderLoader::Create( +FileReaderLoader::FileReaderLoader( ReadType read_type, - FileReaderLoaderClient* client) { - return std::make_unique<FileReaderLoader>(read_type, client); -} - -FileReaderLoader::FileReaderLoader(ReadType read_type, - FileReaderLoaderClient* client) + FileReaderLoaderClient* client, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) : read_type_(read_type), client_(client), - // TODO(hajimehoshi): Pass an appropriate task runner to SimpleWatcher - // constructor. - handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC), + handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC, + task_runner), binding_(this), + task_runner_(std::move(task_runner)), weak_factory_(this) {} FileReaderLoader::~FileReaderLoader() { @@ -105,7 +101,7 @@ } mojom::blink::BlobReaderClientPtr client_ptr; - binding_.Bind(MakeRequest(&client_ptr)); + binding_.Bind(MakeRequest(&client_ptr, task_runner_), task_runner_); blob_data->ReadAll(std::move(producer_handle), std::move(client_ptr)); if (IsSyncLoad()) {
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.h b/third_party/blink/renderer/core/fileapi/file_reader_loader.h index 9f238c87..d06d13f4 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader.h +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.h
@@ -75,9 +75,9 @@ // If client is given, do the loading asynchronously. Otherwise, load // synchronously. - static std::unique_ptr<FileReaderLoader> Create(ReadType, - FileReaderLoaderClient*); - FileReaderLoader(ReadType, FileReaderLoaderClient*); + FileReaderLoader(ReadType, + FileReaderLoaderClient*, + scoped_refptr<base::SingleThreadTaskRunner>); ~FileReaderLoader() override; void Start(scoped_refptr<BlobDataHandle>); @@ -183,6 +183,8 @@ bool started_loading_ = false; #endif // DCHECK_IS_ON() + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + base::WeakPtrFactory<FileReaderLoader> weak_factory_; };
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_sync.cc b/third_party/blink/renderer/core/fileapi/file_reader_sync.cc index 4357025..b011ab2a 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_sync.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader_sync.cc
@@ -30,6 +30,8 @@ #include "third_party/blink/renderer/core/fileapi/file_reader_sync.h" +#include <memory> + #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" @@ -53,7 +55,8 @@ }; } // namespace -FileReaderSync::FileReaderSync(ExecutionContext* context) { +FileReaderSync::FileReaderSync(ExecutionContext* context) + : task_runner_(context->GetTaskRunner(TaskType::kFileReading)) { WorkerType type = WorkerType::OTHER; if (context->IsDedicatedWorkerGlobalScope()) type = WorkerType::DEDICATED_WORKER; @@ -72,8 +75,8 @@ ExceptionState& exception_state) { DCHECK(blob); - std::unique_ptr<FileReaderLoader> loader = - FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, nullptr); + std::unique_ptr<FileReaderLoader> loader = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsArrayBuffer, nullptr, task_runner_); StartLoading(*loader, *blob, exception_state); return loader->ArrayBufferResult(); @@ -83,8 +86,8 @@ ExceptionState& exception_state) { DCHECK(blob); - std::unique_ptr<FileReaderLoader> loader = - FileReaderLoader::Create(FileReaderLoader::kReadAsBinaryString, nullptr); + std::unique_ptr<FileReaderLoader> loader = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsBinaryString, nullptr, task_runner_); StartLoading(*loader, *blob, exception_state); return loader->StringResult(); } @@ -94,8 +97,8 @@ ExceptionState& exception_state) { DCHECK(blob); - std::unique_ptr<FileReaderLoader> loader = - FileReaderLoader::Create(FileReaderLoader::kReadAsText, nullptr); + std::unique_ptr<FileReaderLoader> loader = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsText, nullptr, task_runner_); loader->SetEncoding(encoding); StartLoading(*loader, *blob, exception_state); return loader->StringResult(); @@ -105,8 +108,8 @@ ExceptionState& exception_state) { DCHECK(blob); - std::unique_ptr<FileReaderLoader> loader = - FileReaderLoader::Create(FileReaderLoader::kReadAsDataURL, nullptr); + std::unique_ptr<FileReaderLoader> loader = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsDataURL, nullptr, task_runner_); loader->SetDataType(blob->type()); StartLoading(*loader, *blob, exception_state); return loader->StringResult();
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_sync.h b/third_party/blink/renderer/core/fileapi/file_reader_sync.h index 2c93cb71..5b313f5a 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_sync.h +++ b/third_party/blink/renderer/core/fileapi/file_reader_sync.h
@@ -35,6 +35,10 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace blink { class Blob; @@ -63,6 +67,8 @@ private: void StartLoading(FileReaderLoader&, const Blob&, ExceptionState&); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_link_element.idl b/third_party/blink/renderer/core/html/html_link_element.idl index 1524f8b7..da2890a9 100644 --- a/third_party/blink/renderer/core/html/html_link_element.idl +++ b/third_party/blink/renderer/core/html/html_link_element.idl
@@ -32,7 +32,7 @@ [CEReactions, Reflect] attribute DOMString media; [CEReactions, Reflect] attribute DOMString hreflang; [CEReactions, Reflect] attribute DOMString type; - [Reflect, ReflectOnly=("script","style","image","video", "audio", "track", "font", "fetch")] attribute DOMString as; + [Reflect, ReflectOnly=("script","style","image", "track", "font", "fetch")] attribute DOMString as; [CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy; [PutForwards=value] readonly attribute DOMTokenList sizes; [CEReactions, MeasureAs=PriorityHints, OriginTrialEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index 018eab6..e18252e 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -1051,7 +1051,12 @@ {"http://example.test", "<link rel=preload href=bla as=font type='font/bla'>", nullptr, "http://example.test/", ResourceType::kFont, 0}, - {"http://example.test", "<link rel=preload href=bla as=video>", "bla", + // Until the preload cache is defined in terms of range requests and media + // fetches we can't reliably preload audio/video content and expect it to + // be served from the cache correctly. Until + // https://github.com/w3c/preload/issues/97 is resolved and implemented we + // need to disable these preloads. + {"http://example.test", "<link rel=preload href=bla as=video>", nullptr, "http://example.test/", ResourceType::kVideo, 0}, {"http://example.test", "<link rel=preload href=bla as=track>", "bla", "http://example.test/", ResourceType::kTextTrack, 0},
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc index af929850..41d1dec 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
@@ -252,8 +252,10 @@ ScriptState* script_state, const ImageBitmapOptions* options) : ContextLifecycleObserver(ExecutionContext::From(script_state)), - loader_( - FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, this)), + loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsArrayBuffer, + this, + GetExecutionContext()->GetTaskRunner(TaskType::kFileReading))), factory_(&factory), resolver_(ScriptPromiseResolver::Create(script_state)), crop_rect_(crop_rect),
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 765fb6e..92951a1 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -77,6 +77,7 @@ #include "third_party/blink/renderer/platform/network/http_header_map.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" @@ -165,7 +166,11 @@ scoped_refptr<BlobDataHandle> blob, base::OnceCallback<void(scoped_refptr<SharedBuffer>)> callback) : blob_(std::move(blob)), callback_(std::move(callback)) { - loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this); + // TODO(hajimehoshi): Use a per-ExecutionContext task runner of + // TaskType::kFileReading + loader_ = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadByClient, this, + ThreadScheduler::Current()->DeprecatedDefaultTaskRunner()); } ~InspectorFileReaderLoaderClient() override = default;
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index e5e67c1..7fe2097 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -161,10 +161,16 @@ mojom::RequestContextType::STYLE, true}, // TODO(yoav): It doesn't seem like the audio context is ever used. That // should probably be fixed (or we can consolidate audio and video). + // + // Until the preload cache is defined in terms of range requests and media + // fetches we can't reliably preload audio/video content and expect it to be + // served from the cache correctly. Until + // https://github.com/w3c/preload/issues/97 is resolved and implemented we + // need to disable these preloads. {"http://example.test/cat.wav", "audio", ResourceLoadPriority::kLow, - mojom::RequestContextType::AUDIO, true}, + mojom::RequestContextType::AUDIO, false}, {"http://example.test/cat.mp4", "video", ResourceLoadPriority::kLow, - mojom::RequestContextType::VIDEO, true}, + mojom::RequestContextType::VIDEO, false}, {"http://example.test/cat.vtt", "track", ResourceLoadPriority::kLow, mojom::RequestContextType::TRACK, true}, {"http://example.test/cat.woff", "font", ResourceLoadPriority::kHigh, @@ -229,13 +235,18 @@ {"http://example.test/cat.css", "style", "text/sass", ResourceLoadPriority::kUnresolved, mojom::RequestContextType::STYLE, false}, + // Until the preload cache is defined in terms of range requests and media + // fetches we can't reliably preload audio/video content and expect it to be + // served from the cache correctly. Until + // https://github.com/w3c/preload/issues/97 is resolved and implemented we + // need to disable these preloads. {"http://example.test/cat.wav", "audio", "audio/wav", - ResourceLoadPriority::kLow, mojom::RequestContextType::AUDIO, true}, + ResourceLoadPriority::kLow, mojom::RequestContextType::AUDIO, false}, {"http://example.test/cat.wav", "audio", "audio/mp57", ResourceLoadPriority::kUnresolved, mojom::RequestContextType::AUDIO, false}, {"http://example.test/cat.webm", "video", "video/webm", - ResourceLoadPriority::kLow, mojom::RequestContextType::VIDEO, true}, + ResourceLoadPriority::kLow, mojom::RequestContextType::VIDEO, false}, {"http://example.test/cat.mp199", "video", "video/mp199", ResourceLoadPriority::kUnresolved, mojom::RequestContextType::VIDEO, false},
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc index 3fd0fd5..890c1bf 100644 --- a/third_party/blink/renderer/core/loader/preload_helper.cc +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -159,6 +159,11 @@ } } +// Until the preload cache is defined in terms of range requests and media +// fetches we can't reliably preload audio/video content and expect it to be +// served from the cache correctly. Until +// https://github.com/w3c/preload/issues/97 is resolved and implemented we need +// to disable these preloads. base::Optional<ResourceType> PreloadHelper::GetResourceTypeFromAsAttribute( const String& as) { DCHECK_EQ(as.DeprecatedLower(), as); @@ -168,10 +173,6 @@ return ResourceType::kScript; if (as == "style") return ResourceType::kCSSStyleSheet; - if (as == "video") - return ResourceType::kVideo; - if (as == "audio") - return ResourceType::kAudio; if (as == "track") return ResourceType::kTextTrack; if (as == "font")
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc b/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc index 5544a45b..a16feadb 100644 --- a/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc +++ b/third_party/blink/renderer/core/paint/nine_piece_image_grid.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/paint/nine_piece_image_grid.h" -#include "third_party/blink/renderer/core/style/nine_piece_image.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" @@ -35,8 +34,8 @@ bool include_rigt_edge) : border_image_area_(border_image_area), image_size_(image_size), - horizontal_tile_rule_((Image::TileRule)nine_piece_image.HorizontalRule()), - vertical_tile_rule_((Image::TileRule)nine_piece_image.VerticalRule()), + horizontal_tile_rule_(nine_piece_image.HorizontalRule()), + vertical_tile_rule_(nine_piece_image.VerticalRule()), fill_(nine_piece_image.Fill()) { top_.slice = ComputeEdgeSlice(nine_piece_image.ImageSlices().Top(), image_size.Height()); @@ -160,13 +159,13 @@ const NinePieceImageGrid::Edge& edge, const FloatRect& source, const FloatRect& destination, - Image::TileRule tile_rule) { + ENinePieceImageRule tile_rule) { draw_info.is_drawable = edge.IsDrawable() && source.Width() > 0; if (draw_info.is_drawable) { draw_info.source = source; draw_info.destination = destination; draw_info.tile_scale = FloatSize(edge.Scale(), edge.Scale()); - draw_info.tile_rule = {tile_rule, Image::kStretchTile}; + draw_info.tile_rule = {tile_rule, kStretchImageRule}; } } @@ -175,13 +174,13 @@ const NinePieceImageGrid::Edge& edge, const FloatRect& source, const FloatRect& destination, - Image::TileRule tile_rule) { + ENinePieceImageRule tile_rule) { draw_info.is_drawable = edge.IsDrawable() && source.Height() > 0; if (draw_info.is_drawable) { draw_info.source = source; draw_info.destination = destination; draw_info.tile_scale = FloatSize(edge.Scale(), edge.Scale()); - draw_info.tile_rule = {Image::kStretchTile, tile_rule}; + draw_info.tile_rule = {kStretchImageRule, tile_rule}; } } @@ -268,11 +267,11 @@ // factor unless they have a rule other than "stretch". The middle however // can have "stretch" specified in one axis but not the other, so we have to // correct the scale here. - if (horizontal_tile_rule_ == (Image::TileRule)kStretchImageRule) + if (horizontal_tile_rule_ == kStretchImageRule) middle_scale_factor.SetWidth((float)destination_size.Width() / source_size.Width()); - if (vertical_tile_rule_ == (Image::TileRule)kStretchImageRule) + if (vertical_tile_rule_ == kStretchImageRule) middle_scale_factor.SetHeight((float)destination_size.Height() / source_size.Height()); }
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_grid.h b/third_party/blink/renderer/core/paint/nine_piece_image_grid.h index a014db7..d260097 100644 --- a/third_party/blink/renderer/core/paint/nine_piece_image_grid.h +++ b/third_party/blink/renderer/core/paint/nine_piece_image_grid.h
@@ -6,17 +6,16 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NINE_PIECE_IMAGE_GRID_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/style/nine_piece_image.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" -#include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { class IntRectOutsets; -class NinePieceImage; enum NinePiece { kMinPiece = 0, @@ -82,8 +81,8 @@ // center pieces. FloatSize tile_scale; struct { - Image::TileRule horizontal; - Image::TileRule vertical; + ENinePieceImageRule horizontal; + ENinePieceImageRule vertical; } tile_rule; }; NinePieceDrawInfo GetNinePieceDrawInfo(NinePiece, float) const; @@ -103,8 +102,8 @@ IntRect border_image_area_; IntSize image_size_; - Image::TileRule horizontal_tile_rule_; - Image::TileRule vertical_tile_rule_; + ENinePieceImageRule horizontal_tile_rule_; + ENinePieceImageRule vertical_tile_rule_; bool fill_; Edge top_;
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc b/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc index f4bc6c6..ddee76a4 100644 --- a/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc +++ b/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc
@@ -145,8 +145,8 @@ IntRectOutsets border_widths; bool fill; LengthBox image_slices; - Image::TileRule horizontal_rule; - Image::TileRule vertical_rule; + ENinePieceImageRule horizontal_rule; + ENinePieceImageRule vertical_rule; struct { bool is_drawable; bool is_corner_piece; @@ -154,8 +154,8 @@ FloatRect source; float tile_scale_horizontal; float tile_scale_vertical; - Image::TileRule horizontal_rule; - Image::TileRule vertical_rule; + ENinePieceImageRule horizontal_rule; + ENinePieceImageRule vertical_rule; } pieces[9]; } test_cases[] = { {// Empty border and slices but with fill @@ -165,27 +165,27 @@ true, LengthBox(Length(0, kFixed), Length(0, kFixed), Length(0, kFixed), Length(0, kFixed)), - Image::kStretchTile, - Image::kStretchTile, + kStretchImageRule, + kStretchImageRule, { {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(0, 0, 100, 100), FloatRect(0, 0, 100, 100), - 1, 1, Image::kStretchTile, Image::kStretchTile}, + 1, 1, kStretchImageRule, kStretchImageRule}, }}, {// Single border and fill IntSize(100, 100), @@ -194,27 +194,27 @@ true, LengthBox(Length(20, kPercent), Length(20, kPercent), Length(20, kPercent), Length(20, kPercent)), - Image::kStretchTile, - Image::kStretchTile, + kStretchImageRule, + kStretchImageRule, { {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(0, 90, 100, 10), FloatRect(20, 80, 60, 20), - 0.5, 0.5, Image::kStretchTile, Image::kStretchTile}, + 0.5, 0.5, kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(0, 0, 100, 90), FloatRect(20, 20, 60, 60), - 1.666667, 1.5, Image::kStretchTile, Image::kStretchTile}, + 1.666667, 1.5, kStretchImageRule, kStretchImageRule}, }}, {// All borders, no fill IntSize(100, 100), @@ -223,27 +223,27 @@ false, LengthBox(Length(20, kPercent), Length(20, kPercent), Length(20, kPercent), Length(20, kPercent)), - Image::kStretchTile, - Image::kStretchTile, + kStretchImageRule, + kStretchImageRule, { {true, true, FloatRect(0, 0, 10, 10), FloatRect(0, 0, 20, 20), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {true, true, FloatRect(0, 90, 10, 10), FloatRect(0, 80, 20, 20), 1, - 1, Image::kStretchTile, Image::kStretchTile}, + 1, kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(0, 10, 10, 80), FloatRect(0, 20, 20, 60), - 0.5, 0.5, Image::kStretchTile, Image::kStretchTile}, + 0.5, 0.5, kStretchImageRule, kStretchImageRule}, {true, true, FloatRect(90, 0, 10, 10), FloatRect(80, 0, 20, 20), 1, - 1, Image::kStretchTile, Image::kStretchTile}, + 1, kStretchImageRule, kStretchImageRule}, {true, true, FloatRect(90, 90, 10, 10), FloatRect(80, 80, 20, 20), 1, - 1, Image::kStretchTile, Image::kStretchTile}, + 1, kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(90, 10, 10, 80), FloatRect(80, 20, 20, 60), - 0.5, 0.5, Image::kStretchTile, Image::kStretchTile}, + 0.5, 0.5, kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(10, 0, 80, 10), FloatRect(20, 0, 60, 20), - 0.5, 0.5, Image::kStretchTile, Image::kStretchTile}, + 0.5, 0.5, kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(10, 90, 80, 10), FloatRect(20, 80, 60, 20), - 0.5, 0.5, Image::kStretchTile, Image::kStretchTile}, + 0.5, 0.5, kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, }}, {// Single border, no fill IntSize(100, 100), @@ -252,27 +252,27 @@ false, LengthBox(Length(20, kPercent), Length(20, kPercent), Length(20, kPercent), Length(20, kPercent)), - Image::kStretchTile, - Image::kRoundTile, + kStretchImageRule, + kRoundImageRule, { {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {true, false, FloatRect(0, 0, 10, 100), FloatRect(0, 20, 20, 60), - 0.5, 0.5, Image::kStretchTile, Image::kRoundTile}, + 0.5, 0.5, kStretchImageRule, kRoundImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kRoundTile}, + kStretchImageRule, kRoundImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kRoundTile}, + kStretchImageRule, kRoundImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kRoundTile}, + kStretchImageRule, kRoundImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kRoundTile}, + kStretchImageRule, kRoundImageRule}, }}, {// All borders but no slices, with fill (stretch horizontally, space // vertically) @@ -282,27 +282,27 @@ true, LengthBox(Length(0, kFixed), Length(0, kFixed), Length(0, kFixed), Length(0, kFixed)), - Image::kStretchTile, - Image::kSpaceTile, + kStretchImageRule, + kSpaceImageRule, { {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kSpaceTile}, + kStretchImageRule, kSpaceImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, true, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 1, 1, - Image::kStretchTile, Image::kStretchTile}, + kStretchImageRule, kStretchImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kSpaceTile}, + kStretchImageRule, kSpaceImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kSpaceTile}, + kStretchImageRule, kSpaceImageRule}, {false, false, FloatRect(0, 0, 0, 0), FloatRect(0, 0, 0, 0), 0, 0, - Image::kStretchTile, Image::kSpaceTile}, + kStretchImageRule, kSpaceImageRule}, {true, false, FloatRect(10, 10, 80, 80), FloatRect(0, 0, 100, 100), - 0.800000, 1, Image::kStretchTile, Image::kSpaceTile}, + 0.800000, 1, kStretchImageRule, kSpaceImageRule}, }}, };
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 5c32e13..055f603 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
@@ -4,9 +4,7 @@ #include "third_party/blink/renderer/core/paint/nine_piece_image_painter.h" -#include "third_party/blink/renderer/core/layout/layout_box_model_object.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/paint/nine_piece_image_grid.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/nine_piece_image.h" @@ -19,6 +17,74 @@ namespace { +std::tuple<bool, float> CalculateSpaceNeeded(const float destination, + const float source) { + DCHECK_GT(source, 0); + DCHECK_GT(destination, 0); + + float repeat_tiles_count = floorf(destination / source); + if (!repeat_tiles_count) + return std::make_tuple(false, -1); + + float space = destination; + space -= source * repeat_tiles_count; + space /= repeat_tiles_count + 1.0; + + return std::make_tuple(true, space); +} + +struct TileParameters { + float scale_factor; + float phase; + float spacing; +}; + +bool ComputeTileParameters(ENinePieceImageRule tile_rule, + float dst_pos, + float dst_extent, + float src_pos, + float src_extent, + float provided_tile_scale_factor, + TileParameters& tile) { + tile.scale_factor = provided_tile_scale_factor; + switch (tile_rule) { + case kRoundImageRule: { + float repetitions = + std::max(1.0f, roundf(dst_extent / (src_extent * tile.scale_factor))); + tile.scale_factor = dst_extent / (src_extent * repetitions); + tile.phase = src_pos * tile.scale_factor; + tile.spacing = 0; + break; + } + case kRepeatImageRule: { + float scaled_tile_extent = src_extent * tile.scale_factor; + // We want to construct the phase such that the pattern is centered (when + // stretch is not set for a particular rule). + tile.phase = src_pos * tile.scale_factor; + tile.phase -= (dst_extent - scaled_tile_extent) / 2; + tile.spacing = 0; + break; + } + case kSpaceImageRule: { + std::tuple<bool, float> space = + CalculateSpaceNeeded(dst_extent, src_extent); + if (!std::get<0>(space)) + return false; + tile.spacing = std::get<1>(space); + tile.scale_factor = 1; + tile.phase = src_pos - tile.spacing; + break; + } + case kStretchImageRule: + tile.phase = src_pos * tile.scale_factor; + tile.spacing = 0; + break; + default: + NOTREACHED(); + } + return true; +} + void PaintPieces(GraphicsContext& context, const LayoutRect& border_image_rect, const ComputedStyle& style, @@ -44,11 +110,44 @@ // use kSync by default. context.DrawImage(image, Image::kSyncDecode, draw_info.destination, &draw_info.source); + } else if (draw_info.tile_rule.horizontal == kStretchImageRule && + draw_info.tile_rule.vertical == kStretchImageRule) { + // Just do a scale. + // Since there is no way for the developer to specify decode behavior, + // use kSync by default. + context.DrawImage(image, Image::kSyncDecode, draw_info.destination, + &draw_info.source); } else { - context.DrawTiledImage(image, draw_info.destination, draw_info.source, - draw_info.tile_scale, - draw_info.tile_rule.horizontal, - draw_info.tile_rule.vertical); + // TODO(cavalcantii): see crbug.com/662513. + TileParameters h_tile, v_tile; + if (!ComputeTileParameters( + draw_info.tile_rule.horizontal, draw_info.destination.X(), + draw_info.destination.Width(), draw_info.source.X(), + draw_info.source.Width(), draw_info.tile_scale.Width(), h_tile)) + continue; + if (!ComputeTileParameters( + draw_info.tile_rule.vertical, draw_info.destination.Y(), + draw_info.destination.Height(), draw_info.source.Y(), + draw_info.source.Height(), draw_info.tile_scale.Height(), + v_tile)) + continue; + + FloatSize tile_scale_factor(h_tile.scale_factor, v_tile.scale_factor); + FloatPoint tile_phase(draw_info.destination.X() - h_tile.phase, + draw_info.destination.Y() - v_tile.phase); + + // TODO(cavalcantii): see crbug.com/662507. + if (draw_info.tile_rule.horizontal == kRoundImageRule || + draw_info.tile_rule.vertical == kRoundImageRule) { + ScopedInterpolationQuality interpolation_quality_scope( + context, kInterpolationLow); + context.DrawImageTiled(image, draw_info.destination, draw_info.source, + tile_scale_factor, tile_phase, FloatSize()); + } else { + FloatSize tile_spacing(h_tile.spacing, v_tile.spacing); + context.DrawImageTiled(image, draw_info.destination, draw_info.source, + tile_scale_factor, tile_phase, tile_spacing); + } } } }
diff --git a/third_party/blink/renderer/core/streams/BUILD.gn b/third_party/blink/renderer/core/streams/BUILD.gn index 4040416..f4a85ea 100644 --- a/third_party/blink/renderer/core/streams/BUILD.gn +++ b/third_party/blink/renderer/core/streams/BUILD.gn
@@ -31,6 +31,12 @@ "underlying_source_base.h", "writable_stream.cc", "writable_stream.h", + "writable_stream_default_controller.cc", + "writable_stream_default_controller.h", + "writable_stream_default_writer.cc", + "writable_stream_default_writer.h", + "writable_stream_native.cc", + "writable_stream_native.h", "writable_stream_wrapper.cc", "writable_stream_wrapper.h", ]
diff --git a/third_party/blink/renderer/core/streams/miscellaneous_operations.cc b/third_party/blink/renderer/core/streams/miscellaneous_operations.cc index 3db17ae..6b8065d 100644 --- a/third_party/blink/renderer/core/streams/miscellaneous_operations.cc +++ b/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
@@ -225,48 +225,6 @@ TraceWrapperV8Reference<v8::Value> extra_arg_; }; -class JavaScriptStreamStartAlgorithm : public StreamStartAlgorithm { - public: - JavaScriptStreamStartAlgorithm(v8::Isolate* isolate, - v8::Local<v8::Object> recv, - const char* method_name_for_error, - v8::Local<v8::Value> controller) - : recv_(isolate, recv), - method_name_for_error_(method_name_for_error), - controller_(isolate, controller) {} - - v8::MaybeLocal<v8::Promise> Run(ScriptState* script_state, - ExceptionState& exception_state) override { - auto* isolate = script_state->GetIsolate(); - // https://streams.spec.whatwg.org/#set-up-writable-stream-default-controller-from-underlying-sink - // 3. Let startAlgorithm be the following steps: - // a. Return ? InvokeOrNoop(underlyingSink, "start", « controller »). - auto value_maybe = CallOrNoop1( - script_state, recv_.NewLocal(isolate), "start", method_name_for_error_, - controller_.NewLocal(isolate), exception_state); - if (exception_state.HadException()) { - return v8::MaybeLocal<v8::Promise>(); - } - v8::Local<v8::Value> value; - if (!value_maybe.ToLocal(&value)) { - exception_state.ThrowTypeError("internal error"); - return v8::MaybeLocal<v8::Promise>(); - } - return PromiseResolve(script_state, value); - } - - void Trace(Visitor* visitor) override { - visitor->Trace(recv_); - visitor->Trace(controller_); - StreamStartAlgorithm::Trace(visitor); - } - - private: - TraceWrapperV8Reference<v8::Object> recv_; - const char* const method_name_for_error_; - TraceWrapperV8Reference<v8::Value> controller_; -}; - } // namespace // TODO(ricea): For optimal performance, method_name should be cached as an @@ -313,16 +271,6 @@ isolate, method.As<v8::Function>(), extra_arg_local, underlying_object); } -CORE_EXPORT StreamStartAlgorithm* CreateStartAlgorithm( - ScriptState* script_state, - v8::Local<v8::Object> underlying_object, - const char* method_name_for_error, - v8::Local<v8::Value> controller) { - return MakeGarbageCollected<JavaScriptStreamStartAlgorithm>( - script_state->GetIsolate(), underlying_object, method_name_for_error, - controller); -} - CORE_EXPORT v8::MaybeLocal<v8::Value> CallOrNoop1( ScriptState* script_state, v8::Local<v8::Object> object,
diff --git a/third_party/blink/renderer/core/streams/miscellaneous_operations.h b/third_party/blink/renderer/core/streams/miscellaneous_operations.h index 3e0c42d..3c1458b2 100644 --- a/third_party/blink/renderer/core/streams/miscellaneous_operations.h +++ b/third_party/blink/renderer/core/streams/miscellaneous_operations.h
@@ -17,7 +17,6 @@ class ScriptState; class StrategySizeAlgorithm; class StreamAlgorithm; -class StreamStartAlgorithm; // This is slightly different than the version in the standard // https://streams.spec.whatwg.org/#create-algorithm-from-underlying-method as @@ -35,17 +34,6 @@ v8::MaybeLocal<v8::Value> extra_arg, ExceptionState&); -// Create a StreamStartAlgorithm from the "start" method on |underlying_object|. -// Unlike other algorithms, the lookup of the method on the object is done at -// execution time rather than algorithm creation time. |method_name_for_error| -// is used in exception messages. It is not copied so must remain valid until -// the algorithm is run. -CORE_EXPORT StreamStartAlgorithm* CreateStartAlgorithm( - ScriptState*, - v8::Local<v8::Object> underlying_object, - const char* method_name_for_error, - v8::Local<v8::Value> controller); - // Used in place of InvokeOrNoop in spec. Always takes 1 argument. // https://streams.spec.whatwg.org/#invoke-or-noop CORE_EXPORT v8::MaybeLocal<v8::Value> CallOrNoop1(ScriptState*,
diff --git a/third_party/blink/renderer/core/streams/miscellaneous_operations_test.cc b/third_party/blink/renderer/core/streams/miscellaneous_operations_test.cc index aaf5101..85c688e3 100644 --- a/third_party/blink/renderer/core/streams/miscellaneous_operations_test.cc +++ b/third_party/blink/renderer/core/streams/miscellaneous_operations_test.cc
@@ -169,86 +169,6 @@ extra_arg, 1, argv)); } -TEST(MiscellaneousOperationsTest, CreateStartAlgorithmNoMethod) { - V8TestingScope scope; - auto underlying_object = v8::Object::New(scope.GetIsolate()); - v8::Local<v8::Value> controller = v8::Undefined(scope.GetIsolate()); - auto* algo = CreateStartAlgorithm(scope.GetScriptState(), underlying_object, - "underlyingSink.start", controller); - ASSERT_TRUE(algo); - auto maybe_result = algo->Run(scope.GetScriptState(), ASSERT_NO_EXCEPTION); - ASSERT_FALSE(maybe_result.IsEmpty()); - auto result = maybe_result.ToLocalChecked(); - ASSERT_EQ(result->State(), v8::Promise::kFulfilled); - EXPECT_TRUE(result->Result()->IsUndefined()); -} - -TEST(MiscellaneousOperationsTest, CreateStartAlgorithmNullMethod) { - V8TestingScope scope; - auto underlying_object = v8::Object::New(scope.GetIsolate()); - underlying_object - ->Set(scope.GetContext(), V8String(scope.GetIsolate(), "start"), - v8::Null(scope.GetIsolate())) - .Check(); - v8::Local<v8::Value> controller = v8::Undefined(scope.GetIsolate()); - auto* algo = CreateStartAlgorithm(scope.GetScriptState(), underlying_object, - "underlyingSink.start", controller); - ASSERT_TRUE(algo); - ExceptionState exception_state(scope.GetIsolate(), - ExceptionState::kExecutionContext, "", ""); - auto maybe_result = algo->Run(scope.GetScriptState(), exception_state); - EXPECT_TRUE(exception_state.HadException()); - EXPECT_TRUE(maybe_result.IsEmpty()); -} - -TEST(MiscellaneousOperationsTest, CreateStartAlgorithmThrowingMethod) { - V8TestingScope scope; - ScriptValue underlying_value = EvalWithPrintingError(&scope, - R"(({ - start() { - throw new Error(); - } -}))"); - ASSERT_TRUE(underlying_value.IsObject()); - auto underlying_object = underlying_value.V8Value().As<v8::Object>(); - v8::Local<v8::Value> controller = v8::Undefined(scope.GetIsolate()); - auto* algo = CreateStartAlgorithm(scope.GetScriptState(), underlying_object, - "underlyingSink.start", controller); - ASSERT_TRUE(algo); - ExceptionState exception_state(scope.GetIsolate(), - ExceptionState::kExecutionContext, "", ""); - auto maybe_result = algo->Run(scope.GetScriptState(), exception_state); - EXPECT_TRUE(exception_state.HadException()); - EXPECT_TRUE(maybe_result.IsEmpty()); -} - -TEST(MiscellaneousOperationsTest, CreateStartAlgorithmReturningController) { - V8TestingScope scope; - ScriptValue underlying_value = EvalWithPrintingError(&scope, - R"(({ - start(controller) { - return controller; - } -}))"); - ASSERT_TRUE(underlying_value.IsObject()); - auto underlying_object = underlying_value.V8Value().As<v8::Object>(); - // In a real stream, |controller| is never a promise, but nothing in - // CreateStartAlgorithm() requires this. By making it a promise, we can verify - // that a promise returned from start is passed through as-is. - v8::Local<v8::Value> controller = - v8::Promise::Resolver::New(scope.GetContext()) - .ToLocalChecked() - ->GetPromise(); - auto* algo = CreateStartAlgorithm(scope.GetScriptState(), underlying_object, - "underlyingSink.start", controller); - ASSERT_TRUE(algo); - auto maybe_result = algo->Run(scope.GetScriptState(), ASSERT_NO_EXCEPTION); - EXPECT_FALSE(maybe_result.IsEmpty()); - v8::Local<v8::Value> result = maybe_result.ToLocalChecked(); - ASSERT_TRUE(result->IsPromise()); - ASSERT_EQ(result, controller); -} - TEST(MiscellaneousOperationsTest, CallOrNoop1NoMethod) { V8TestingScope scope; auto underlying_object = v8::Object::New(scope.GetIsolate());
diff --git a/third_party/blink/renderer/core/streams/stream_algorithms.h b/third_party/blink/renderer/core/streams/stream_algorithms.h index a0217a9..c4f2dd78 100644 --- a/third_party/blink/renderer/core/streams/stream_algorithms.h +++ b/third_party/blink/renderer/core/streams/stream_algorithms.h
@@ -34,23 +34,10 @@ virtual void Trace(Visitor*) {} }; -// Base class for start algorithms, ie. those that are derived from the start() -// method of the underlying object. These differ from other underlying -// algorithms in that they can throw synchronously. Objects of this -// type must always be reachable by V8's garbage collector. -class StreamStartAlgorithm : public GarbageCollectedFinalized<StreamAlgorithm> { - public: - virtual ~StreamStartAlgorithm() = default; - - virtual v8::MaybeLocal<v8::Promise> Run(ScriptState*, ExceptionState&) = 0; - - virtual void Trace(Visitor*) {} -}; - // Base class for algorithms which take one or more arguments and return a // Promise. This is used as the type for all the algorithms in the standard that -// do not use StrategySizeAlgorithm or StreamStartAlgorithm. Objects of this -// type must always be reachable by V8's garbage collector. +// do not use StrategySizeAlgorithm. Objects of this type must always be +// reachable by V8's garbage collector. class StreamAlgorithm : public GarbageCollectedFinalized<StreamAlgorithm> { public: virtual ~StreamAlgorithm() = default;
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc new file mode 100644 index 0000000..d5b24268 --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" + +namespace blink { + +void WritableStreamDefaultController::error(ScriptState* script_state) { + return; +} + +void WritableStreamDefaultController::error(ScriptState* script_state, + ScriptValue e) { + return; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.h b/third_party/blink/renderer/core/streams/writable_stream_default_controller.h new file mode 100644 index 0000000..63f55564 --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_CONTROLLER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_CONTROLLER_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" +#include "v8/include/v8.h" + +namespace blink { + +class ScriptState; +class ScriptValue; + +class WritableStreamDefaultController : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + void error(ScriptState*); + void error(ScriptState*, ScriptValue e); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_CONTROLLER_H_
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl new file mode 100644 index 0000000..96086b6a --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is only used when the new C++ implementation is enabled. + +// https://streams.spec.whatwg.org/#ws-default-controller-class-definition +[ + Exposed=(Window,Worker,Worklet), + NoInterfaceObject, + RaisesException=Constructor +] interface WritableStreamDefaultController { + [CallWith=ScriptState, NotEnumerable] void error(optional any e); +};
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc new file mode 100644 index 0000000..422ae1e9 --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
@@ -0,0 +1,91 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/stream_promise_resolver.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 { + +WritableStreamDefaultWriter* WritableStreamDefaultWriter::Create( + ScriptState* script_state, + WritableStream* stream, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); + return nullptr; +} + +WritableStreamDefaultWriter::WritableStreamDefaultWriter( + ScriptState* script_state, + WritableStreamNative* stream, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); + return; +} + +WritableStreamDefaultWriter::~WritableStreamDefaultWriter() = default; + +ScriptPromise WritableStreamDefaultWriter::closed( + ScriptState* script_state) const { + return RejectUnimplemented(script_state); +} + +ScriptValue WritableStreamDefaultWriter::desiredSize( + ScriptState* script_state, + ExceptionState& exception_state) const { + ThrowUnimplemented(exception_state); + return ScriptValue(); +} + +ScriptPromise WritableStreamDefaultWriter::ready( + ScriptState* script_state) const { + return RejectUnimplemented(script_state); +} + +ScriptPromise WritableStreamDefaultWriter::abort(ScriptState* script_state) { + return RejectUnimplemented(script_state); +} + +ScriptPromise WritableStreamDefaultWriter::abort(ScriptState* script_state, + ScriptValue reason) { + return RejectUnimplemented(script_state); +} + +ScriptPromise WritableStreamDefaultWriter::close(ScriptState* script_state) { + return RejectUnimplemented(script_state); +} + +void WritableStreamDefaultWriter::releaseLock(ScriptState* script_state) { + return; +} + +ScriptPromise WritableStreamDefaultWriter::write(ScriptState* script_state) { + return RejectUnimplemented(script_state); +} + +ScriptPromise WritableStreamDefaultWriter::write(ScriptState* script_state, + ScriptValue chunk) { + return RejectUnimplemented(script_state); +} + +void WritableStreamDefaultWriter::ThrowUnimplemented( + ExceptionState& exception_state) { + exception_state.ThrowTypeError("unimplemented"); +} + +ScriptPromise WritableStreamDefaultWriter::RejectUnimplemented( + ScriptState* script_state) { + return StreamPromiseResolver::CreateRejected( + script_state, v8::Exception::TypeError(V8String( + script_state->GetIsolate(), "unimplemented"))) + ->GetScriptPromise(script_state); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.h b/third_party/blink/renderer/core/streams/writable_stream_default_writer.h new file mode 100644 index 0000000..24fe82ef --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.h
@@ -0,0 +1,55 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_WRITER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_WRITER_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" +#include "v8/include/v8.h" + +namespace blink { + +class ExceptionState; +class ScriptPromise; +class ScriptState; +class ScriptValue; +class WritableStream; +class WritableStreamNative; + +class WritableStreamDefaultWriter : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static WritableStreamDefaultWriter* Create(ScriptState*, + WritableStream* stream, + ExceptionState&); + + WritableStreamDefaultWriter(ScriptState*, + WritableStreamNative* stream, + ExceptionState&); + ~WritableStreamDefaultWriter() override; + + ScriptPromise closed(ScriptState*) const; + ScriptValue desiredSize(ScriptState*, ExceptionState&) const; + ScriptPromise ready(ScriptState*) const; + + ScriptPromise abort(ScriptState*); + ScriptPromise abort(ScriptState*, ScriptValue reason); + + ScriptPromise close(ScriptState*); + + void releaseLock(ScriptState*); + + ScriptPromise write(ScriptState*); + ScriptPromise write(ScriptState*, ScriptValue chunk); + + private: + static void ThrowUnimplemented(ExceptionState& exception_state); + static ScriptPromise RejectUnimplemented(ScriptState* script_state); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_DEFAULT_WRITER_H_
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl b/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl new file mode 100644 index 0000000..0bed52d6 --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is only used when the new C++ implementation is enabled. + +// https://streams.spec.whatwg.org/#default-writer-class-definition +[ + Exposed=(Window,Worker,Worklet), + RuntimeEnabled=StreamsNative, + RaisesException=Constructor, + ConstructorCallWith=ScriptState, + Constructor(WritableStream stream) +] interface WritableStreamDefaultWriter { + [CallWith=ScriptState, NotEnumerable] readonly attribute Promise<void> + closed; + [RaisesException, CallWith=ScriptState, NotEnumerable] readonly attribute + any desiredSize; + [CallWith=ScriptState, NotEnumerable] readonly attribute Promise<void> + ready; + + [CallWith=ScriptState, NotEnumerable] Promise<void> abort( + optional any reason); + [CallWith=ScriptState, NotEnumerable] Promise<void> close(); + [CallWith=ScriptState, NotEnumerable] void releaseLock(); + [CallWith=ScriptState, NotEnumerable] Promise<void> write( + optional any chunk); +};
diff --git a/third_party/blink/renderer/core/streams/writable_stream_native.cc b/third_party/blink/renderer/core/streams/writable_stream_native.cc new file mode 100644 index 0000000..ab4fd0a --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_native.cc
@@ -0,0 +1,60 @@ +// 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 "third_party/blink/renderer/core/streams/writable_stream_native.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" + +namespace blink { + +WritableStreamNative::WritableStreamNative() = default; + +WritableStreamNative::WritableStreamNative(ScriptState* script_state, + ScriptValue raw_underlying_sink, + ScriptValue raw_strategy, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); +} + +WritableStreamNative::~WritableStreamNative() = default; + +bool WritableStreamNative::locked(ScriptState* script_state, + ExceptionState& exception_state) const { + ThrowUnimplemented(exception_state); + return false; +} + +ScriptPromise WritableStreamNative::abort(ScriptState* script_state, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); + return ScriptPromise(); +} + +ScriptPromise WritableStreamNative::abort(ScriptState* script_state, + ScriptValue reason, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); + return ScriptPromise(); +} + +ScriptValue WritableStreamNative::getWriter(ScriptState* script_state, + ExceptionState& exception_state) { + ThrowUnimplemented(exception_state); + return ScriptValue(); +} + +base::Optional<bool> WritableStreamNative::IsLocked( + ScriptState* script_state, + ExceptionState& exception_state) const { + ThrowUnimplemented(exception_state); + return base::nullopt; +} + +void WritableStreamNative::ThrowUnimplemented(ExceptionState& exception_state) { + exception_state.ThrowTypeError("unimplemented"); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/streams/writable_stream_native.h b/third_party/blink/renderer/core/streams/writable_stream_native.h new file mode 100644 index 0000000..211327c --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_native.h
@@ -0,0 +1,57 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_NATIVE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_NATIVE_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/streams/writable_stream.h" + +namespace blink { + +class ExceptionState; +class ScriptState; +class StrategySizeAlgorithm; +class StreamAlgorithm; +class StreamStartAlgorithm; + +class CORE_EXPORT WritableStreamNative : public WritableStream { + public: + static WritableStreamNative* Create(ScriptState*, + StreamStartAlgorithm* start_algorithm, + StreamAlgorithm* write_algorithm, + StreamAlgorithm* close_algorithm, + StreamAlgorithm* abort_algorithm, + double high_water_mark, + StrategySizeAlgorithm* size_algorithm, + ExceptionState&); + + WritableStreamNative(); + WritableStreamNative(ScriptState*, + ScriptValue raw_underlying_sink, + ScriptValue raw_strategy, + ExceptionState&); + ~WritableStreamNative() override; + + // IDL defined functions + bool locked(ScriptState*, ExceptionState&) const override; + ScriptPromise abort(ScriptState*, ExceptionState&) override; + ScriptPromise abort(ScriptState*, + ScriptValue reason, + ExceptionState&) override; + ScriptValue getWriter(ScriptState*, ExceptionState&) override; + + base::Optional<bool> IsLocked(ScriptState*, ExceptionState&) const override; + + void Serialize(ScriptState*, MessagePort*, ExceptionState&) override { + // TODO(ricea): Implement this. + } + + private: + static void ThrowUnimplemented(ExceptionState& exception_state); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_NATIVE_H_
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 54f79934..3efa437 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -236,8 +236,11 @@ BlobLoader(XMLHttpRequest* xhr, scoped_refptr<BlobDataHandle> handle) : xhr_(xhr), - loader_( - FileReaderLoader::Create(FileReaderLoader::kReadByClient, this)) { + loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadByClient, + this, + xhr->GetExecutionContext()->GetTaskRunner( + TaskType::kFileReading))) { loader_->Start(std::move(handle)); }
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index 8f8750f..11aaea6 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -662,7 +662,6 @@ query_params->ignore_search = options->ignoreSearch(); query_params->ignore_method = options->ignoreMethod(); query_params->ignore_vary = options->ignoreVary(); - query_params->cache_name = options->cacheName(); return query_params; }
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_query_options.idl b/third_party/blink/renderer/modules/cache_storage/cache_query_options.idl index 032ff177..2819737 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_query_options.idl +++ b/third_party/blink/renderer/modules/cache_storage/cache_query_options.idl
@@ -7,5 +7,4 @@ boolean ignoreSearch = false; boolean ignoreMethod = false; boolean ignoreVary = false; - DOMString cacheName; };
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc index 2f6303f..14527a0 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -21,6 +21,32 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/network/http_names.h" +namespace mojo { + +using blink::mojom::blink::MultiQueryParams; +using blink::mojom::blink::MultiQueryParamsPtr; +using blink::mojom::blink::QueryParams; +using blink::mojom::blink::QueryParamsPtr; + +template <> +struct TypeConverter<MultiQueryParamsPtr, + const blink::MultiCacheQueryOptions*> { + static MultiQueryParamsPtr Convert( + const blink::MultiCacheQueryOptions* input) { + QueryParamsPtr query_params = QueryParams::New(); + query_params->ignore_search = input->ignoreSearch(); + query_params->ignore_method = input->ignoreMethod(); + query_params->ignore_vary = input->ignoreVary(); + + MultiQueryParamsPtr output = MultiQueryParams::New(); + output->query_params = std::move(query_params); + output->cache_name = input->cacheName(); + return output; + } +}; + +} // namespace mojo + namespace blink { CacheStorage* CacheStorage::Create(ExecutionContext* context, @@ -164,7 +190,7 @@ ScriptPromise CacheStorage::match(ScriptState* script_state, const RequestInfo& request, - const CacheQueryOptions* options, + const MultiCacheQueryOptions* options, ExceptionState& exception_state) { DCHECK(!request.IsNull()); @@ -179,7 +205,7 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, const Request* request, - const CacheQueryOptions* options) { + const MultiCacheQueryOptions* options) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -192,10 +218,11 @@ // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. cache_storage_ptr_->Match( - request->CreateFetchAPIRequest(), Cache::ToQueryParams(options), + request->CreateFetchAPIRequest(), + mojom::blink::MultiQueryParams::From(options), WTF::Bind( [](ScriptPromiseResolver* resolver, TimeTicks start_time, - const CacheQueryOptions* options, CacheStorage* _, + const MultiCacheQueryOptions* options, CacheStorage* _, mojom::blink::MatchResultPtr result) { if (!resolver->GetExecutionContext() || resolver->GetExecutionContext()->IsContextDestroyed())
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.h b/third_party/blink/renderer/modules/cache_storage/cache_storage.h index 38bf54e..10aa58d 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.h +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.h
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/fetch/global_fetch.h" #include "third_party/blink/renderer/modules/cache_storage/cache.h" -#include "third_party/blink/renderer/modules/cache_storage/cache_query_options.h" +#include "third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" @@ -35,7 +35,7 @@ ScriptPromise keys(ScriptState*); ScriptPromise match(ScriptState*, const RequestInfo&, - const CacheQueryOptions*, + const MultiCacheQueryOptions*, ExceptionState&); void Trace(blink::Visitor*) override; @@ -43,7 +43,7 @@ private: ScriptPromise MatchImpl(ScriptState*, const Request*, - const CacheQueryOptions*); + const MultiCacheQueryOptions*); Member<GlobalFetch::ScopedFetcher> scoped_fetcher_;
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.idl b/third_party/blink/renderer/modules/cache_storage/cache_storage.idl index 9e0c78a..0094ffe 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.idl +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.idl
@@ -7,7 +7,7 @@ SecureContext, Exposed=(Window,Worker) ] interface CacheStorage { - [CallWith=ScriptState, RaisesException] Promise<any> match(RequestInfo request, optional CacheQueryOptions options); + [CallWith=ScriptState, RaisesException] Promise<any> match(RequestInfo request, optional MultiCacheQueryOptions options); [CallWith=ScriptState] Promise<boolean> has(DOMString cacheName); [CallWith=ScriptState] Promise<Cache> open(DOMString cacheName); [CallWith=ScriptState, ImplementedAs=Delete] Promise<boolean> delete(DOMString cacheName);
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc index 7a15862..b21d68d 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -246,7 +246,6 @@ EXPECT_EQ(expected_query_params->ignore_method, query_params->ignore_method); EXPECT_EQ(expected_query_params->ignore_vary, query_params->ignore_vary); - EXPECT_EQ(expected_query_params->cache_name, query_params->cache_name); } const mojom::blink::CacheStorageError error_; @@ -448,12 +447,10 @@ mojom::blink::QueryParamsPtr expected_query_params = mojom::blink::QueryParams::New(); expected_query_params->ignore_vary = true; - expected_query_params->cache_name = "this is a cache name"; test_cache()->SetExpectedQueryParams(&expected_query_params); CacheQueryOptions* options = CacheQueryOptions::Create(); options->setIgnoreVary(1); - options->setCacheName(expected_query_params->cache_name); Request* request = NewRequestFromUrl(url); DCHECK(request); @@ -518,11 +515,9 @@ mojom::blink::QueryParamsPtr expected_query_params = mojom::blink::QueryParams::New(); - expected_query_params->cache_name = "this is another cache name"; test_cache()->SetExpectedQueryParams(&expected_query_params); CacheQueryOptions* options = CacheQueryOptions::Create(); - options->setCacheName(expected_query_params->cache_name); const String url = "http://batch.operations.test/"; Request* request = NewRequestFromUrl(url);
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc index 96bd4952..a8e2148 100644 --- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc +++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/network/http_header_map.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -443,8 +444,12 @@ CachedResponseFileReaderLoaderClient( scoped_refptr<BlobDataHandle>&& blob, std::unique_ptr<RequestCachedResponseCallback>&& callback) - : loader_( - FileReaderLoader::Create(FileReaderLoader::kReadByClient, this)), + // TODO(hajimehoshi): Use a per-ExecutionContext task runner of + // TaskType::kFileReading + : loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadByClient, + static_cast<FileReaderLoaderClient*>(this), + ThreadScheduler::Current()->DeprecatedDefaultTaskRunner())), callback_(std::move(callback)), data_(SharedBuffer::Create()) { loader_->Start(std::move(blob)); @@ -654,8 +659,13 @@ auto request = mojom::blink::FetchAPIRequest::New(); request->url = KURL(request_url); request->method = String("GET"); + + auto multi_query_params = mojom::blink::MultiQueryParams::New(); + multi_query_params->query_params = mojom::blink::QueryParams::New(); + multi_query_params->cache_name = cache_name; + cache_storage->Match( - std::move(request), mojom::blink::QueryParams::New(), + std::move(request), std::move(multi_query_params), WTF::Bind( [](std::unique_ptr<RequestCachedResponseCallback> callback, mojom::blink::MatchResultPtr result) {
diff --git a/third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.idl b/third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.idl new file mode 100644 index 0000000..6718a68 --- /dev/null +++ b/third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.idl
@@ -0,0 +1,8 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3c.github.io/ServiceWorker/#cachestorage +dictionary MultiCacheQueryOptions : CacheQueryOptions { + DOMString cacheName; +};
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc index 84c6650..e752e1ab4 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc
@@ -4,13 +4,21 @@ #include "third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h" +#include <memory> +#include <utility> + #include "third_party/blink/renderer/core/fileapi/file_reader_loader.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h" namespace blink { -ClipboardFileReader::ClipboardFileReader(Blob* blob, ClipboardPromise* promise) - : loader_( - FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, this)), +ClipboardFileReader::ClipboardFileReader( + Blob* blob, + ClipboardPromise* promise, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsArrayBuffer, + this, + std::move(task_runner))), promise_(promise) { loader_->Start(blob->GetBlobDataHandle()); }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h index 0abd07a..11fc3fd 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h
@@ -26,7 +26,9 @@ // merge code and reduce duplicate code. class ClipboardFileReader final : public FileReaderLoaderClient { public: - ClipboardFileReader(Blob*, ClipboardPromise*); + ClipboardFileReader(Blob*, + ClipboardPromise*, + scoped_refptr<base::SingleThreadTaskRunner>); ~ClipboardFileReader() override; // FileReaderLoaderClient.
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index f6571686..6dbfabfc 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -112,7 +112,9 @@ : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)), script_state_(script_state), script_promise_resolver_(ScriptPromiseResolver::Create(script_state)), - buffer_(mojom::ClipboardBuffer::kStandard) {} + buffer_(mojom::ClipboardBuffer::kStandard), + file_reading_task_runner_( + GetExecutionContext()->GetTaskRunner(TaskType::kFileReading)) {} scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() { // TODO(garykac): Replace MiscPlatformAPI with TaskType specific to clipboard. @@ -292,7 +294,8 @@ return; } - file_reader_ = std::make_unique<ClipboardFileReader>(write_image_data_, this); + file_reader_ = std::make_unique<ClipboardFileReader>( + write_image_data_, this, file_reading_task_runner_); } void ClipboardPromise::HandleWriteTextWithPermission(PermissionStatus status) {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h index 061c691..fa4b7329b 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -87,6 +87,8 @@ String write_data_; Member<Blob> write_image_data_; + scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; + SEQUENCE_CHECKER(async_clipboard_sequence_checker); };
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc index 54ff849..fd801d28 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
@@ -299,7 +299,8 @@ GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); op_listeners_.AddBinding( std::make_unique<ReadDirectoryListener>(std::move(callbacks)), - std::move(request)); + std::move(request), + GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); GetFileSystemManager().ReadDirectory(path, std::move(ptr)); } @@ -394,7 +395,8 @@ WTF::Bind(&FileSystemDispatcher::WriteErrorCallback, WrapWeakPersistent(this), std::move(error_callback), operation_id)), - std::move(request)); + std::move(request), + GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); GetFileSystemManager().Write(path, blob_id, offset, std::move(op_request), std::move(listener_ptr));
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc index fc21d82..22ab631 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/modules/indexeddb/idb_value.h" #include "third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h" #include "third_party/blink/renderer/platform/histogram.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" namespace blink { @@ -74,7 +75,11 @@ DCHECK(!file_reader_loading_); file_reader_loading_ = true; #endif // DCHECK_IS_ON() - loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this); + // TODO(hajimehoshi): Use a per-ExecutionContext task runner of + // TaskType::kFileReading + loader_ = std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadByClient, this, + ThreadScheduler::Current()->IPCTaskRunner()); loader_->Start(unwrapper.WrapperBlobHandle()); }
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 54bb218..a5849ff 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -500,6 +500,7 @@ "bluetooth/bluetooth_le_scan_options.idl", "bluetooth/request_device_options.idl", "cache_storage/cache_query_options.idl", + "cache_storage/multi_cache_query_options.idl", "canvas/canvas2d/canvas_rendering_context_2d_settings.idl", "canvas/canvas2d/hit_region_options.idl", "canvas/htmlcanvas/canvas_context_creation_attributes_module.idl",
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/third_party/blink/renderer/modules/presentation/presentation_connection.cc index f1f1d433..f1570cc 100644 --- a/third_party/blink/renderer/modules/presentation/presentation_connection.cc +++ b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -123,10 +123,13 @@ public FileReaderLoaderClient { public: BlobLoader(scoped_refptr<BlobDataHandle> blob_data_handle, - PresentationConnection* presentation_connection) + PresentationConnection* presentation_connection, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) : presentation_connection_(presentation_connection), - loader_(FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, - this)) { + loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsArrayBuffer, + this, + std::move(task_runner))) { loader_->Start(std::move(blob_data_handle)); } ~BlobLoader() override = default; @@ -161,7 +164,8 @@ url_(url), state_(mojom::blink::PresentationConnectionState::CONNECTING), connection_binding_(this), - binary_type_(kBinaryTypeArrayBuffer) {} + binary_type_(kBinaryTypeArrayBuffer), + file_reading_task_runner_(frame.GetTaskRunner(TaskType::kFileReading)) {} PresentationConnection::~PresentationConnection() { DCHECK(!blob_loader_); @@ -498,8 +502,8 @@ break; case kMessageTypeBlob: DCHECK(!blob_loader_); - blob_loader_ = - MakeGarbageCollected<BlobLoader>(message->blob_data_handle, this); + blob_loader_ = MakeGarbageCollected<BlobLoader>( + message->blob_data_handle, this, file_reading_task_runner_); break; } }
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.h b/third_party/blink/renderer/modules/presentation/presentation_connection.h index 9ac31e4..32c363b2 100644 --- a/third_party/blink/renderer/modules/presentation/presentation_connection.h +++ b/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -153,6 +153,8 @@ HeapDeque<Member<Message>> messages_; BinaryType binary_type_; + + scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; }; // Represents the controller side of a connection of either a 1-UA or 2-UA
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 2440eaf..95f8444 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -80,7 +80,9 @@ : public GarbageCollectedFinalized<WebSocketChannelImpl::BlobLoader>, public FileReaderLoaderClient { public: - BlobLoader(scoped_refptr<BlobDataHandle>, WebSocketChannelImpl*); + BlobLoader(scoped_refptr<BlobDataHandle>, + WebSocketChannelImpl*, + scoped_refptr<base::SingleThreadTaskRunner>); ~BlobLoader() override = default; void Cancel(); @@ -123,10 +125,13 @@ WebSocketChannelImpl::BlobLoader::BlobLoader( scoped_refptr<BlobDataHandle> blob_data_handle, - WebSocketChannelImpl* channel) + WebSocketChannelImpl* channel, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) : channel_(channel), - loader_(FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, - this)) { + loader_(std::make_unique<FileReaderLoader>( + FileReaderLoader::kReadAsArrayBuffer, + this, + std::move(task_runner))) { loader_->Start(std::move(blob_data_handle)); } @@ -192,7 +197,9 @@ received_data_size_for_flow_control_(0), sent_size_of_top_message_(0), location_at_construction_(std::move(location)), - throttle_passed_(false) { + throttle_passed_(false), + file_reading_task_runner_( + execution_context->GetTaskRunner(TaskType::kFileReading)) { if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context_)) scope->EnsureFetcher(); } @@ -464,8 +471,8 @@ CHECK(!blob_loader_); CHECK(message); CHECK(message->blob_data_handle); - blob_loader_ = - MakeGarbageCollected<BlobLoader>(message->blob_data_handle, this); + blob_loader_ = MakeGarbageCollected<BlobLoader>( + message->blob_data_handle, this, file_reading_task_runner_); break; case kMessageTypeArrayBuffer: CHECK(message->array_buffer); @@ -793,6 +800,10 @@ return static_cast<BaseFetchContext*>(&resource_fetcher->Context()); } +ExecutionContext* WebSocketChannelImpl::GetExecutionContext() { + return execution_context_; +} + void WebSocketChannelImpl::Trace(blink::Visitor* visitor) { visitor->Trace(blob_loader_); visitor->Trace(messages_);
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index 88c0702..29368ce7 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -110,6 +110,8 @@ std::unique_ptr<SourceLocation>) override; void Disconnect() override; + ExecutionContext* GetExecutionContext(); + void Trace(blink::Visitor*) override; private: @@ -212,6 +214,8 @@ std::unique_ptr<ConnectInfo> connect_info_; bool throttle_passed_; + scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; + static const uint64_t kReceivedDataSizeForFlowControlHighWaterMark = 1 << 15; };
diff --git a/third_party/blink/renderer/platform/exported/mediastream/OWNERS b/third_party/blink/renderer/platform/exported/mediastream/OWNERS new file mode 100644 index 0000000..c205d4f9 --- /dev/null +++ b/third_party/blink/renderer/platform/exported/mediastream/OWNERS
@@ -0,0 +1,6 @@ +file://third_party/blink/common/mediastream/OWNERS + +per-file media_stream_audio_processor*=aluebs@chromium.org + +# TEAM: media-capture-and-streams@grotations.appspotmail.com +# COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index 197174a0..4889d7f6 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -1009,29 +1009,6 @@ paint_controller_.SetImagePainted(); } -void GraphicsContext::DrawTiledImage(Image* image, - const FloatRect& dest, - const FloatRect& src_rect, - const FloatSize& tile_scale_factor, - Image::TileRule h_rule, - Image::TileRule v_rule, - SkBlendMode op) { - if (ContextDisabled() || !image) - return; - - if (h_rule == Image::kStretchTile && v_rule == Image::kStretchTile) { - // Just do a scale. - // Since there is no way for the developer to specify decode behavior, use - // kSync by default. - DrawImage(image, Image::kSyncDecode, dest, &src_rect, op); - return; - } - - image->DrawTiledBorder(*this, dest, src_rect, tile_scale_factor, h_rule, - v_rule, op); - paint_controller_.SetImagePainted(); -} - void GraphicsContext::DrawOval(const SkRect& oval, const PaintFlags& flags) { if (ContextDisabled()) return;
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h index a8dcb080..5712a42 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.h +++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -230,14 +230,6 @@ const FloatPoint& phase, const FloatSize& repeat_spacing, SkBlendMode = SkBlendMode::kSrcOver); - // Used for border image - void DrawTiledImage(Image*, - const FloatRect& dest_rect, - const FloatRect& src_rect, - const FloatSize& tile_scale_factor, - Image::TileRule h_rule = Image::kStretchTile, - Image::TileRule v_rule = Image::kStretchTile, - SkBlendMode = SkBlendMode::kSrcOver); // These methods write to the canvas. // Also drawLine(const IntPoint& point1, const IntPoint& point2) and
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc index dba1d08..31aab16 100644 --- a/third_party/blink/renderer/platform/graphics/image.cc +++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -140,103 +140,6 @@ return String(); } -// TODO(schenney): Lift this code, with the calculations for subsetting the -// image and the like, up the stack into a border painting class. -void Image::DrawTiledBorder(GraphicsContext& ctxt, - const FloatRect& dst_rect, - const FloatRect& src_rect, - const FloatSize& provided_tile_scale_factor, - TileRule h_rule, - TileRule v_rule, - SkBlendMode op) { - // TODO(cavalcantii): see crbug.com/662513. - FloatSize tile_scale_factor = provided_tile_scale_factor; - if (v_rule == kRoundTile) { - float v_repetitions = std::max( - 1.0f, roundf(dst_rect.Height() / - (tile_scale_factor.Height() * src_rect.Height()))); - tile_scale_factor.SetHeight(dst_rect.Height() / - (src_rect.Height() * v_repetitions)); - } - - if (h_rule == kRoundTile) { - float h_repetitions = - std::max(1.0f, roundf(dst_rect.Width() / - (tile_scale_factor.Width() * src_rect.Width()))); - tile_scale_factor.SetWidth(dst_rect.Width() / - (src_rect.Width() * h_repetitions)); - } - - // We want to construct the phase such that the pattern is centered (when - // stretch is not set for a particular rule). - float v_phase = tile_scale_factor.Height() * src_rect.Y(); - float h_phase = tile_scale_factor.Width() * src_rect.X(); - if (v_rule == kRepeatTile) { - float scaled_tile_height = tile_scale_factor.Height() * src_rect.Height(); - v_phase -= (dst_rect.Height() - scaled_tile_height) / 2; - } - - if (h_rule == kRepeatTile) { - float scaled_tile_width = tile_scale_factor.Width() * src_rect.Width(); - h_phase -= (dst_rect.Width() - scaled_tile_width) / 2; - } - - FloatSize spacing; - auto calculate_space_needed = - [](const float destination, - const float source) -> std::tuple<bool, float> { - DCHECK_GT(source, 0); - DCHECK_GT(destination, 0); - - float repeat_tiles_count = floorf(destination / source); - if (!repeat_tiles_count) - return std::make_tuple(false, -1); - - float space = destination; - space -= source * repeat_tiles_count; - space /= repeat_tiles_count + 1.0; - - return std::make_tuple(true, space); - }; - - if (v_rule == kSpaceTile) { - std::tuple<bool, float> space = - calculate_space_needed(dst_rect.Height(), src_rect.Height()); - if (!std::get<0>(space)) - return; - - spacing.SetHeight(std::get<1>(space)); - tile_scale_factor.SetHeight(1.0); - v_phase = src_rect.Y(); - v_phase -= spacing.Height(); - } - - if (h_rule == kSpaceTile) { - std::tuple<bool, float> space = - calculate_space_needed(dst_rect.Width(), src_rect.Width()); - if (!std::get<0>(space)) - return; - - spacing.SetWidth(std::get<1>(space)); - tile_scale_factor.SetWidth(1.0); - h_phase = src_rect.X(); - h_phase -= spacing.Width(); - } - - FloatPoint pattern_phase(dst_rect.X() - h_phase, dst_rect.Y() - v_phase); - - // TODO(cavalcantii): see crbug.com/662507. - if ((h_rule == kRoundTile) || (v_rule == kRoundTile)) { - ScopedInterpolationQuality interpolation_quality_scope(ctxt, - kInterpolationLow); - DrawPattern(ctxt, src_rect, tile_scale_factor, pattern_phase, op, dst_rect, - FloatSize()); - } else { - DrawPattern(ctxt, src_rect, tile_scale_factor, pattern_phase, op, dst_rect, - spacing); - } -} - namespace { sk_sp<PaintShader> CreatePatternShader(const PaintImage& image,
diff --git a/third_party/blink/renderer/platform/graphics/image.h b/third_party/blink/renderer/platform/graphics/image.h index a6e42e8..af180fe 100644 --- a/third_party/blink/renderer/platform/graphics/image.h +++ b/third_party/blink/renderer/platform/graphics/image.h
@@ -165,8 +165,6 @@ image_observer_disabled_ = disabled; } - enum TileRule { kStretchTile, kRoundTile, kSpaceTile, kRepeatTile }; - virtual scoped_refptr<Image> ImageForDefaultFrame(); enum ImageDecodingMode { @@ -251,14 +249,6 @@ protected: Image(ImageObserver* = nullptr, bool is_multipart = false); - void DrawTiledBorder(GraphicsContext&, - const FloatRect& dst_rect, - const FloatRect& src_rect, - const FloatSize& tile_scale_factor, - TileRule h_rule, - TileRule v_rule, - SkBlendMode); - virtual void DrawPattern(GraphicsContext&, const FloatRect&, const FloatSize&,
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 6eaa00ff..d2b2f56 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1282,6 +1282,9 @@ status: "experimental", }, { + name: "StreamsNative", + }, + { name: "TextUnderlinePositionLeftRight", status: "stable", },
diff --git a/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc index 00a81c1..5bf0105 100644 --- a/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc
@@ -50,6 +50,11 @@ return base::ThreadTaskRunnerHandle::Get(); } +scoped_refptr<base::SingleThreadTaskRunner> +SimpleThreadScheduler::DeprecatedDefaultTaskRunner() { + return base::ThreadTaskRunnerHandle::Get(); +} + std::unique_ptr<PageScheduler> SimpleThreadScheduler::CreatePageScheduler( PageScheduler::Delegate* delegate) { return nullptr;
diff --git a/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h index ad97b8b..9aa1a6b 100644 --- a/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h
@@ -47,6 +47,8 @@ scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override; + scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner() + override; // Unsupported. Return nullptr, and it may cause a crash. std::unique_ptr<PageScheduler> CreatePageScheduler(
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc index afcd0c2..218aa3a 100644 --- a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
@@ -47,5 +47,10 @@ ukm_task_sampling_rate_ = sampling_rate; } +scoped_refptr<base::SingleThreadTaskRunner> +ThreadSchedulerImpl::DeprecatedDefaultTaskRunner() { + return DefaultTaskRunner(); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h index 9b36e583..5a14d5c3 100644 --- a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
@@ -52,6 +52,9 @@ virtual const base::TickClock* GetTickClock() = 0; + scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner() + override; + protected: ThreadSchedulerImpl(); ~ThreadSchedulerImpl() override;
diff --git a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h index 6e979d5..c0f808b9 100644 --- a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
@@ -80,6 +80,15 @@ // Returns a task runner for handling IPC messages. virtual scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() = 0; + // Returns a default task runner. This is basically same as the default task + // runner, but is explicitly allowed to run JavaScript. We plan to forbid V8 + // execution on per-thread task runners (crbug.com/913912). If you need to + // replace a default task runner usages that executes JavaScript but it is + // hard to replace with an appropriate (per-context) task runner, use this as + // a temporal step. + virtual scoped_refptr<base::SingleThreadTaskRunner> + DeprecatedDefaultTaskRunner() = 0; + // Creates a new PageScheduler for a given Page. Must be called from the // associated WebThread. virtual std::unique_ptr<PageScheduler> CreatePageScheduler(
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc index 267e2e6..66b11ea0 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -306,6 +306,9 @@ return true; } + // This is needed to ensure an origin can access to itself under nullified + // document.domain. + // TODO(tzik): Update the nulled domain handling and remove this condition. if (this == other) { detail = AccessResultDomainDetail::kDomainNotRelevant; return true; @@ -313,7 +316,7 @@ if (IsOpaque() || other->IsOpaque()) { detail = AccessResultDomainDetail::kDomainNotRelevant; - return false; + return nonce_if_opaque_ == other->nonce_if_opaque_; } // document.domain handling, as per @@ -545,14 +548,15 @@ } bool SecurityOrigin::IsSameSchemeHostPort(const SecurityOrigin* other) const { + // This is needed to ensure a local origin considered to have the same scheme, + // host, and port to itself. + // TODO(tzik): Make the local origin unique but not opaque, and remove this + // condition. if (this == other) return true; - if (IsOpaque() || other->IsOpaque()) { - // TODO(dcheng|nasko): Add nonce equality check here, such that opaque - // origins that are copy of each other can be equal. - return false; - } + if (IsOpaque() || other->IsOpaque()) + return nonce_if_opaque_ == other->nonce_if_opaque_; if (host_ != other->host_) return false;
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h index 5242b79..648e2c4 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.h +++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -47,6 +47,7 @@ class KURL; class URLSecurityOriginMap; +struct SecurityOriginHash; // An identifier which defines the source of content (e.g. a document) and // restricts what other objects it is permitted to access (based on their @@ -306,6 +307,7 @@ constexpr static const int kInvalidPort = 0; friend struct mojo::UrlOriginAdapter; + friend struct blink::SecurityOriginHash; // Creates a new opaque SecurityOrigin using the supplied |precursor| origin // and |nonce|.
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_hash.h b/third_party/blink/renderer/platform/weborigin/security_origin_hash.h index 2e13bff..1a9bd66 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin_hash.h +++ b/third_party/blink/renderer/platform/weborigin/security_origin_hash.h
@@ -30,6 +30,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_SECURITY_ORIGIN_HASH_H_ #include "base/memory/scoped_refptr.h" +#include "build/build_config.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -43,10 +44,23 @@ struct SecurityOriginHash { STATIC_ONLY(SecurityOriginHash); static unsigned GetHash(const SecurityOrigin* origin) { - unsigned hash_codes[3] = { - origin->Protocol().Impl() ? origin->Protocol().Impl()->GetHash() : 0, - origin->Host().Impl() ? origin->Host().Impl()->GetHash() : 0, - origin->Port()}; + base::Optional<base::UnguessableToken> nonce = + origin->GetNonceForSerialization(); + size_t nonce_hash = nonce ? base::UnguessableTokenHash()(*nonce) : 0; + + unsigned hash_codes[] = { + origin->Protocol().Impl() ? origin->Protocol().Impl()->GetHash() : 0, + origin->Host().Impl() ? origin->Host().Impl()->GetHash() : 0, + origin->Port(), +#if ARCH_CPU_32_BITS + nonce_hash, +#elif ARCH_CPU_64_BITS + static_cast<unsigned>(nonce_hash), + static_cast<unsigned>(nonce_hash >> 32), +#else +#error "Unknown bits" +#endif + }; return StringHasher::HashMemory<sizeof(hash_codes)>(hash_codes); } static unsigned GetHash(const scoped_refptr<const SecurityOrigin>& origin) {
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc index 0e4b717..e315186 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -808,4 +809,27 @@ url::Shutdown(); } +TEST_F(SecurityOriginTest, OpaqueIsolatedCopy) { + scoped_refptr<const SecurityOrigin> origin = + SecurityOrigin::CreateUniqueOpaque(); + scoped_refptr<const SecurityOrigin> copied = origin->IsolatedCopy(); + EXPECT_TRUE(origin->CanAccess(copied.get())); + EXPECT_TRUE(origin->IsSameSchemeHostPort(copied.get())); + EXPECT_EQ(SecurityOriginHash::GetHash(origin), + SecurityOriginHash::GetHash(copied)); + EXPECT_TRUE(SecurityOriginHash::Equal(origin, copied)); +} + +TEST_F(SecurityOriginTest, EdgeCases) { + scoped_refptr<SecurityOrigin> nulled_domain = + SecurityOrigin::CreateFromString("http://localhost"); + nulled_domain->SetDomainFromDOM("null"); + EXPECT_TRUE(nulled_domain->CanAccess(nulled_domain.get())); + + scoped_refptr<SecurityOrigin> local = + SecurityOrigin::CreateFromString("file:///foo/bar"); + local->BlockLocalAccessFromLocalOrigin(); + EXPECT_TRUE(local->IsSameSchemeHostPort(local.get())); +} + } // namespace blink
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 a1003bc..3c04388 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
@@ -57,6 +57,7 @@ 'base::TimeTicks', 'base::ThreadTicks', 'base::UnguessableToken', + 'base::UnguessableTokenHash', 'base::UnsafeSharedMemoryRegion', 'base::WeakPtr', 'base::WeakPtrFactory',
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG index 6e837b61..47dc540 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -262,7 +262,7 @@ crbug.com/591099 external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] crbug.com/591099 external/wpt/fullscreen/api/element-ready-check-containing-iframe-manual.html [ Pass ] crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] -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 [ Pass ] crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_top [ Pass ] crbug.com/591099 external/wpt/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html [ Pass ] @@ -278,6 +278,7 @@ crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ] crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ] crbug.com/591099 fast/canvas/OffscreenCanvas-copyImage.html [ Failure Pass ] +crbug.com/591099 fast/css-intrinsic-dimensions/height-css-tables-collapsed.html [ Failure Pass ] crbug.com/591099 fast/css-intrinsic-dimensions/height-positioned.html [ Pass ] crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ] crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ] @@ -287,7 +288,7 @@ crbug.com/591099 fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ] crbug.com/591099 fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/889721 fast/inline/outline-continuations.html [ Failure ] -crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure ] +crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure Pass ] crbug.com/591099 fast/text/descent-clip-in-scaled-page.html [ Failure ] crbug.com/899902 fast/text/ellipsis-with-self-painting-layer.html [ Pass ] crbug.com/796943 fast/text/international/shape-across-elements-simple.html [ Pass ] @@ -295,15 +296,22 @@ crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ] crbug.com/591099 fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ] crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Pass ] -crbug.com/591099 http/tests/devtools/tracing-session-id.js [ Failure Pass ] -crbug.com/591099 http/tests/devtools/tracing/console-timeline.js [ Crash Pass Timeout ] -crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure Pass Timeout ] -crbug.com/591099 http/tests/html/validation-bubble-oopif-clip.html [ Failure Pass ] +crbug.com/927467 http/tests/devtools/elements/navigate-styles-sidebar-with-arrow-keys.js [ Crash ] +crbug.com/927467 http/tests/devtools/elements/styles-1/commit-selector.js [ Crash ] +crbug.com/927467 http/tests/devtools/elements/styles-3/styles-disable-property-after-selector-edit.js [ Crash ] +crbug.com/927467 http/tests/devtools/elements/styles-4/styles-do-not-detach-sourcemap-on-edits.js [ Crash ] +crbug.com/927467 http/tests/devtools/elements/styles-4/styles-update-links-2.js [ Crash ] +crbug.com/927467 http/tests/devtools/elements/styles/undo-set-selector-text.js [ Crash ] +crbug.com/591099 http/tests/devtools/tracing-session-id.js [ Pass ] +crbug.com/591099 http/tests/devtools/tracing/console-timeline.js [ Pass ] +crbug.com/591099 http/tests/html/validation-bubble-oopif-clip.html [ Pass ] crbug.com/591099 http/tests/images/feature-policy-unoptimized-images-cached-image.html [ Failure 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/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure Pass ] +crbug.com/591099 images/feature-policy-oversized-images-resize.html [ Pass ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ] +crbug.com/591099 inspector-protocol/input/dispatchTouchEvent.js [ Failure Pass ] crbug.com/591099 media/autoplay/webaudio-audio-context-resume.html [ Failure Pass ] crbug.com/591099 paint/invalidation/flexbox/scrollbars-changed.html [ Failure ] crbug.com/835484 paint/invalidation/outline/inline-focus.html [ Failure ] @@ -314,7 +322,9 @@ crbug.com/591099 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ] crbug.com/591099 printing/iframe-svg-in-object-print.html [ Failure ] crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ] +crbug.com/927467 svg/dom/parent-view-layout-crash.html [ Crash Pass ] crbug.com/591099 svg/zoom/page/zoom-svg-float-border-padding.xml [ Pass ] +crbug.com/927467 tables/mozilla/bugs/bug113235-3.html [ Crash Pass ] crbug.com/591099 tables/mozilla/bugs/bug14159-1.html [ Pass ] crbug.com/591099 virtual/android/rootscroller/set-root-scroller.html [ Pass ] crbug.com/591099 virtual/android/rootscroller/set-rootscroller-before-load.html [ Pass ] @@ -322,11 +332,11 @@ crbug.com/591099 virtual/composite-after-paint/paint/invalidation/box/margin.html [ Failure Pass ] crbug.com/591099 virtual/display-lock/display-lock/lock-after-append/measure-forced-layout.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-after-append/measure-updated-layout.html [ Failure ] +crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ] +crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update.html [ Timeout ] crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/acquire-update-measure-remove.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-forced-layout.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-updated-layout.html [ Failure ] -crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update.html [ Timeout ] -crbug.com/926276 virtual/display-lock/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ] crbug.com/591099 virtual/exotic-color-space/ [ Skip ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-copyImage.html [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index fb37c03..3f0cb43 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -5979,6 +5979,8 @@ crbug.com/926311 external/wpt/wasm/webapi/instantiateStreaming.any.serviceworker.html [ Failure ] crbug.com/926311 external/wpt/wasm/webapi/instantiateStreaming.any.sharedworker.html [ Failure ] crbug.com/926311 external/wpt/wasm/webapi/instantiateStreaming.any.worker.html [ Failure ] +crbug.com/926311 external/wpt/wasm/jsapi/constructor/compile.any.html [ Pass Failure ] +crbug.com/926311 external/wpt/wasm/jsapi/constructor/compile.any.worker.html [ Pass Failure ] crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.html [ Pass Failure ] crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.worker.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index cc638a3f..661eae1e 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -144556,11 +144556,6 @@ {} ] ], - "css/css-transforms/animation/matrix-interpolation-expected.txt": [ - [ - {} - ] - ], "css/css-transforms/animation/resources/interpolation-testcommon.js": [ [ {} @@ -148201,6 +148196,11 @@ {} ] ], + "css/css-values/calc-numbers-expected.txt": [ + [ + {} + ] + ], "css/css-values/calc-rem-lang-ref.html": [ [ {} @@ -176896,6 +176896,16 @@ {} ] ], + "portals/resources/portal-cross-origin.sub.html": [ + [ + {} + ] + ], + "portals/resources/portal-forward-with-broadcast.html": [ + [ + {} + ] + ], "portals/resources/portals-rendering-portal.html": [ [ {} @@ -176916,6 +176926,11 @@ {} ] ], + "preload/download-resources-expected.txt": [ + [ + {} + ] + ], "preload/dynamic-adding-preload-nonce.html.headers": [ [ {} @@ -176941,6 +176956,26 @@ {} ] ], + "preload/onerror-event-expected.txt": [ + [ + {} + ] + ], + "preload/onload-event-expected.txt": [ + [ + {} + ] + ], + "preload/preload-with-type-expected.txt": [ + [ + {} + ] + ], + "preload/reflected-as-value-expected.txt": [ + [ + {} + ] + ], "preload/resources/A4.ogv": [ [ {} @@ -217870,6 +217905,12 @@ {} ] ], + "css/css-values/calc-numbers.html": [ + [ + "/css/css-values/calc-numbers.html", + {} + ] + ], "css/css-values/calc-rounding-001.html": [ [ "/css/css-values/calc-rounding-001.html", @@ -263474,6 +263515,16 @@ {} ] ], + "performance-timeline/po-observe-type.any.js": [ + [ + "/performance-timeline/po-observe-type.any.html", + {} + ], + [ + "/performance-timeline/po-observe-type.any.worker.html", + {} + ] + ], "performance-timeline/po-observe.any.js": [ [ "/performance-timeline/po-observe.any.html", @@ -263894,6 +263945,12 @@ {} ] ], + "portals/portals-cross-origin-load.sub.html": [ + [ + "/portals/portals-cross-origin-load.sub.html", + {} + ] + ], "portals/portals-host-null.html": [ [ "/portals/portals-host-null.html", @@ -362312,17 +362369,13 @@ "support" ], "css/css-transforms/animation/list-interpolation-expected.txt": [ - "7d67a780f508d185f7b9b8b310c15d126a57813a", + "55e208ac415e018a43fa34cc1dbba0e59664dd5b", "support" ], "css/css-transforms/animation/list-interpolation.html": [ - "af221e5feaee92734f89185a413e3cd2dc57bc29", + "4755279d73cc32b6396d332bdbbfdcbcc3624f52", "testharness" ], - "css/css-transforms/animation/matrix-interpolation-expected.txt": [ - "eb3376c94c031860e711c49844eb8ecc674b0da5", - "support" - ], "css/css-transforms/animation/matrix-interpolation.html": [ "4becea079d78e16479e3d12e6310e69f8444dadf", "testharness" @@ -372863,6 +372916,14 @@ "444785ba14c21faefe56c22de0c23766ddb26c95", "testharness" ], + "css/css-values/calc-numbers-expected.txt": [ + "e02b66126c0211872a1f954602d7ac187ab61499", + "support" + ], + "css/css-values/calc-numbers.html": [ + "5c2c91d7a8c97c2dd5dda2d0736660b5134469a5", + "testharness" + ], "css/css-values/calc-parenthesis-stack.html": [ "1d9033d7eecd14066ee9e4f9c52bf1a39e6ddd1b", "reftest" @@ -402308,7 +402369,7 @@ "testharness" ], "html/dom/reflection-metadata-expected.txt": [ - "4ad790f7bbcc92896a07598549b0ea8587983cb1", + "408ab6f3d2a70f6d4bae4242d28a982354f002d8", "support" ], "html/dom/reflection-metadata.html": [ @@ -418544,7 +418605,7 @@ "support" ], "interfaces/netinfo.idl": [ - "c39293d5c7f8b78dd9ce3e1c7916d11f5e1b8caf", + "a4876c9991069b48ff037e8105f05ebbd31202b1", "support" ], "interfaces/notifications.idl": [ @@ -431095,8 +431156,12 @@ "0b205e094c75e10bc1b93ff966aea0fd23a586f8", "testharness" ], + "performance-timeline/po-observe-type.any.js": [ + "5cdac973becb727d849c2e2c984de483dec73748", + "testharness" + ], "performance-timeline/po-observe.any.js": [ - "8520c26e504d1fc036e90f76aeb37ccb628db132", + "6a673dbe784ed53302c28861871bb7fb2adb06ff", "testharness" ], "performance-timeline/po-observe.html": [ @@ -431675,6 +431740,10 @@ "9a822e9238a938e48c5c1bc6d76669d48962ee65", "testharness" ], + "portals/portals-cross-origin-load.sub.html": [ + "f860ac54dc9dc6578fa1a66c25da70bc3262d995", + "testharness" + ], "portals/portals-host-null.html": [ "e0f1d63743c54c687d62f86abe278873fa823430", "testharness" @@ -431699,6 +431768,14 @@ "cf09caebc0ff9ac38facde84075a7af5be19fd48", "support" ], + "portals/resources/portal-cross-origin.sub.html": [ + "145ab5a2d21295f615d3ecd5d36f9e3034a4202a", + "support" + ], + "portals/resources/portal-forward-with-broadcast.html": [ + "39bda69b0eef9b0062809507bfb91d9fc3401d95", + "support" + ], "portals/resources/portals-rendering-portal.html": [ "1b6f23f512da5bb7d1c7b5b85e48277470d2e146", "support" @@ -431723,6 +431800,10 @@ "095d89ad90ca15eac57a142d051f60207cf94f92", "testharness" ], + "preload/download-resources-expected.txt": [ + "9721540846bbec4bdc596864ed86643a354c72e8", + "support" + ], "preload/download-resources.html": [ "dc2b4693cf11fe224e599b97ba8556894a9e0240", "testharness" @@ -431783,10 +431864,18 @@ "8950daf1f87403e8799570cb8019a2af03bda0c6", "testharness" ], + "preload/onerror-event-expected.txt": [ + "0ef49adc0471fcfc600c2519c9ab49469349353f", + "support" + ], "preload/onerror-event.html": [ "5fae70d3bcab22bf50448c817f856c4b90f110a0", "testharness" ], + "preload/onload-event-expected.txt": [ + "d14478b9833ead86643e65b07eb757ad78104d7b", + "support" + ], "preload/onload-event.html": [ "6af2d64a1c1d73adb8a6504a300cb35de9807038", "testharness" @@ -431803,10 +431892,18 @@ "76395656f9b359e05ae1aeace5ad05a6f338cb5e", "testharness" ], + "preload/preload-with-type-expected.txt": [ + "f6065260355808bddc6f5ff8cb8b343d5ca30583", + "support" + ], "preload/preload-with-type.html": [ "8578143a23495e1828d313ddc6a9310df75fcdb0", "testharness" ], + "preload/reflected-as-value-expected.txt": [ + "19cda42e91a917a1a30141aaf5a39de3c57b6b66", + "support" + ], "preload/reflected-as-value.html": [ "728f6ec464560caa69081dee14b0792bac86a375", "testharness" @@ -443340,7 +443437,7 @@ "support" ], "service-workers/cache-storage/script-tests/cache-match.js": [ - "ba359fed142cb4a3ff281a44e8a2b9ec8a7a656a", + "b2b731cc6546529770c20a0bb5a30168d60b0ec6", "support" ], "service-workers/cache-storage/script-tests/cache-matchAll.js": [ @@ -452092,7 +452189,7 @@ "support" ], "webaudio/js/helpers.js": [ - "5970b7ba031e320083d6f1c551499e8920792d0e", + "fbbfc8e00444dce1440fdbe8e28e11c5b064ce3d", "support" ], "webaudio/js/worklet-recorder.js": [ @@ -452212,7 +452309,7 @@ "testharness" ], "webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html": [ - "1b5531bd228c32f3d9d7e79ca053e480a599f311", + "62d90da1c7fd66599bd2d5b542c939efb8886f93", "testharness" ], "webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers-expected.txt new file mode 100644 index 0000000..e02b6612 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers-expected.txt
@@ -0,0 +1,14 @@ +This is a testharness.js-based test. +PASS testing tab-size: calc(2 * 3) +PASS testing tab-size: calc(2 * -4) +PASS testing opacity: calc(2 / 4) +FAIL testing tab-size: calc(2 / 4) assert_equals: calc(2 / 4) should compute to 0.5 expected "0.5" but got "12345" +PASS testing opacity: calc(2 / 4) * 1px +PASS testing tab-size: calc(1 + 1px) +PASS testing tab-size: calc(1 + 100%) +PASS testing tab-size: calc(100%) +PASS testing tab-size: calc(10px) bla +PASS testing tab-size: calc(bla) 10px +PASS testing tab-size: calc(10px) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers.html b/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers.html new file mode 100644 index 0000000..5c2c91d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/calc-numbers.html
@@ -0,0 +1,88 @@ +<!DOCTYPE html> + + <meta charset="UTF-8"> + + <title>CSS Values and Units Test: computed value of 'tab-size' and 'opacity' when specified with calc() function</title> + + <!-- + + Original test is: + +https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-numbers.html + + --> + + <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> + <link rel="help" href="https://www.w3.org/TR/css-color-3/#transparency"> + <link rel="help" href="https://www.w3.org/TR/css-text-3/#tab-size-property"> + <link rel="help" href="https://www.w3.org/TR/css3-values/#calc-computed-value"> + + <meta name="flags" content="invalid"> + <meta content="This test verifies how 12 calc() functions are computed for 'opacity' and 'tab-size'." name="assert"> + + <script src="/resources/testharness.js"></script> + + <script src="/resources/testharnessreport.js"></script> + + <div id="target"></div> + + <script> + function startTesting() + { + + function verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) + { + + var elemTarget = document.getElementById("target"); + + test(function() + { + + elemTarget.style.setProperty(property_name, initial_value); + + /* + In exactly 9 out of the 12 sub-tests, the initial_value will + act as a fallback value because the calc() function in the + specified value generates an invalid value. Since we are + running 12 consecutive tests on the same element, then + it is necessary to 'reset' its property to an initial + value. + */ + + elemTarget.style.setProperty(property_name, specified_value); + + assert_equals(getComputedStyle(elemTarget)[property_name], expected_value, specified_value + ' should compute to ' + expected_value); + + }, description); + } + + /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */ + + verifyComputedStyle("tab-size", "initial", "calc(2 * 3)", "6", "testing tab-size: calc(2 * 3)"); + + verifyComputedStyle("tab-size", "12345", "calc(2 * -4)", "12345", "testing tab-size: calc(2 * -4)"); + + verifyComputedStyle("opacity", "initial", "calc(2 / 4)", "0.5", "testing opacity: calc(2 / 4)"); + + verifyComputedStyle("tab-size", "12345", "calc(2 / 4)", "0.5", "testing tab-size: calc(2 / 4)"); + + verifyComputedStyle("opacity", "0.9", "calc(2 / 4) * 1px", "0.9", "testing opacity: calc(2 / 4) * 1px"); + + verifyComputedStyle("tab-size", "12345", "calc(1 + 1px)", "12345", "testing tab-size: calc(1 + 1px)"); + + verifyComputedStyle("tab-size", "12345", "calc(1 + 100%)", "12345", "testing tab-size: calc(1 + 100%)"); + + verifyComputedStyle("tab-size", "12345", "calc(100%)", "12345", "testing tab-size: calc(100%)"); + + verifyComputedStyle("tab-size", "12345", "calc(10px) bla", "12345", "testing tab-size: calc(10px) bla"); + + verifyComputedStyle("tab-size", "12345", "calc(bla) 10px", "12345", "testing tab-size: calc(bla) 10px"); + + verifyComputedStyle("tab-size", "initial", "calc(10px)", "10px", "testing tab-size: calc(10px)"); + + /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */ + } + + startTesting(); + + </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt index 4ad790f..408ab6f 100644 --- a/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/dom/reflection-metadata-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 2446 tests; 2373 PASS, 73 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 2446 tests; 2365 PASS, 81 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS head.title: 32 tests PASS head.lang: 32 tests PASS head.dir: 62 tests @@ -35,7 +35,10 @@ PASS link.href: 38 tests PASS link.crossOrigin: 52 tests PASS link.rel: 32 tests -PASS link.as: 27 tests +PASS link.as: 22 tests +FAIL link.as: setAttribute() to "audio" assert_equals: IDL get expected "audio" but got "" +PASS link.as: 3 tests +FAIL link.as: setAttribute() to "AUDIO" assert_equals: IDL get expected "audio" but got "" FAIL link.as: setAttribute() to "document" assert_equals: IDL get expected "document" but got "" PASS link.as: 3 tests FAIL link.as: setAttribute() to "DOCUMENT" assert_equals: IDL get expected "document" but got "" @@ -56,7 +59,10 @@ FAIL link.as: setAttribute() to "sharedworker" assert_equals: IDL get expected "sharedworker" but got "" PASS link.as: 3 tests FAIL link.as: setAttribute() to "SHAREDWORKER" assert_equals: IDL get expected "sharedworker" but got "" -PASS link.as: 17 tests +PASS link.as: 12 tests +FAIL link.as: setAttribute() to "video" assert_equals: IDL get expected "video" but got "" +PASS link.as: 3 tests +FAIL link.as: setAttribute() to "VIDEO" assert_equals: IDL get expected "video" but got "" FAIL link.as: setAttribute() to "worker" assert_equals: IDL get expected "worker" but got "" PASS link.as: 3 tests FAIL link.as: setAttribute() to "WORKER" assert_equals: IDL get expected "worker" but got "" @@ -64,7 +70,10 @@ FAIL link.as: setAttribute() to "xslt" assert_equals: IDL get expected "xslt" but got "" PASS link.as: 3 tests FAIL link.as: setAttribute() to "XSLT" assert_equals: IDL get expected "xslt" but got "" -PASS link.as: 25 tests +PASS link.as: 20 tests +FAIL link.as: IDL set to "audio" assert_equals: IDL get expected "audio" but got "" +PASS link.as: 3 tests +FAIL link.as: IDL set to "AUDIO" assert_equals: IDL get expected "audio" but got "" FAIL link.as: IDL set to "document" assert_equals: IDL get expected "document" but got "" PASS link.as: 3 tests FAIL link.as: IDL set to "DOCUMENT" assert_equals: IDL get expected "document" but got "" @@ -85,7 +94,10 @@ FAIL link.as: IDL set to "sharedworker" assert_equals: IDL get expected "sharedworker" but got "" PASS link.as: 3 tests FAIL link.as: IDL set to "SHAREDWORKER" assert_equals: IDL get expected "sharedworker" but got "" -PASS link.as: 17 tests +PASS link.as: 12 tests +FAIL link.as: IDL set to "video" assert_equals: IDL get expected "video" but got "" +PASS link.as: 3 tests +FAIL link.as: IDL set to "VIDEO" assert_equals: IDL get expected "video" but got "" FAIL link.as: IDL set to "worker" assert_equals: IDL get expected "worker" but got "" PASS link.as: 3 tests FAIL link.as: IDL set to "WORKER" assert_equals: IDL get expected "worker" but got ""
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/netinfo.idl b/third_party/blink/web_tests/external/wpt/interfaces/netinfo.idl index c39293d..a4876c9 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/netinfo.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/netinfo.idl
@@ -22,7 +22,6 @@ "slow-2g" }; -[NoInterfaceObject, Exposed=(Window,Worker)] interface mixin NavigatorNetworkInformation { readonly attribute NetworkInformation connection; };
diff --git a/third_party/blink/web_tests/external/wpt/preload/download-resources-expected.txt b/third_party/blink/web_tests/external/wpt/preload/download-resources-expected.txt new file mode 100644 index 0000000..9721540 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/download-resources-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Makes sure that preloaded resources are downloaded assert_equals: resources/white.mp4 expected 1 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/preload/onerror-event-expected.txt b/third_party/blink/web_tests/external/wpt/preload/onerror-event-expected.txt new file mode 100644 index 0000000..0ef49ad --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/onerror-event-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Makes sure that preloaded resources trigger the onerror event assert_true: video triggered error event expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/preload/onload-event-expected.txt b/third_party/blink/web_tests/external/wpt/preload/onload-event-expected.txt new file mode 100644 index 0000000..d14478b9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/onload-event-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Makes sure that preloaded resources trigger the onload event assert_true: video triggered load event expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/preload/preload-with-type-expected.txt b/third_party/blink/web_tests/external/wpt/preload/preload-with-type-expected.txt new file mode 100644 index 0000000..f606526 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/preload-with-type-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Makes sure that preloaded resources with a type attribute trigger the onload event assert_true: video triggered load event expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/preload/reflected-as-value-expected.txt b/third_party/blink/web_tests/external/wpt/preload/reflected-as-value-expected.txt new file mode 100644 index 0000000..19cda42 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/preload/reflected-as-value-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Make sure that the `as` value reflects only known values assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js index ba359fed..b2b731c 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js
@@ -144,6 +144,25 @@ }); }, 'Cache.match supports ignoreVary'); +cache_test(function(cache) { + let has_cache_name = false; + const opts = { + get cacheName() { + has_cache_name = true; + return undefined; + } + }; + return self.caches.open('foo') + .then(function() { + return cache.match('bar', opts); + }) + .then(function() { + assert_false(has_cache_name, + 'Cache.match does not support cacheName option ' + + 'which was removed in CacheQueryOptions.'); + }); + }, 'Cache.match does not support cacheName option'); + prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.match(entries.cat.request.url + '#mouse') .then(function(result) {
diff --git a/third_party/blink/web_tests/http/tests/contacts/resources/helpers.js b/third_party/blink/web_tests/http/tests/contacts/resources/helpers.js new file mode 100644 index 0000000..5ab07e3 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/contacts/resources/helpers.js
@@ -0,0 +1,10 @@ +'use strict'; + +// Creates a "user gesture" using Blink's test-only eventSender. +function triggerUserGesture() { + if (!window.eventSender) + throw new Error('The `eventSender` must be available for this test'); + + eventSender.mouseDown(); + eventSender.mouseUp(); +}
diff --git a/third_party/blink/web_tests/http/tests/contacts/resources/non-main-frame-select.html b/third_party/blink/web_tests/http/tests/contacts/resources/non-main-frame-select.html new file mode 100644 index 0000000..c75186909 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/contacts/resources/non-main-frame-select.html
@@ -0,0 +1,14 @@ +<script> +'use strict'; + +window.onload = function() { + navigator.contacts.select({ + multiple: "true", + properties: ['name', 'email'] + }).then(results => { + parent.postMessage({ errorMsg: '' }, '*'); + }).catch(exception => { + parent.postMessage({ errorMsg: exception.toString() }, '*'); + }); +} +</script>
diff --git a/third_party/blink/web_tests/http/tests/contacts/select-function.html b/third_party/blink/web_tests/http/tests/contacts/select-function.html index 263dd147f..8a85615 100644 --- a/third_party/blink/web_tests/http/tests/contacts/select-function.html +++ b/third_party/blink/web_tests/http/tests/contacts/select-function.html
@@ -5,19 +5,11 @@ <script src="/gen/third_party/blink/public/mojom/contacts/contacts_manager.mojom.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> <script src="resources/mock_contacts_manager.js"></script> <script> 'use strict'; -// Creates a "user gesture" using Blink's test-only eventSender. -function triggerUserGesture() { - if (!window.eventSender) - throw new Error('The `eventSender` must be available for this test'); - - eventSender.mouseDown(); - eventSender.mouseUp(); -} - // Verifies that |func|, when invoked, throws a TypeError exception. async function expectTypeError(func) { try {
diff --git a/third_party/blink/web_tests/http/tests/contacts/select-restricted-to-main-frame.html b/third_party/blink/web_tests/http/tests/contacts/select-restricted-to-main-frame.html new file mode 100644 index 0000000..24edb6b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/contacts/select-restricted-to-main-frame.html
@@ -0,0 +1,27 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Contact API: select() restricted to main frame</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> + +<iframe></iframe> + +<script> +'use strict'; + +promise_test(async () => { + triggerUserGesture(); + + var iframe = document.getElementsByTagName('iframe')[0]; + iframe.src = "resources/non-main-frame-select.html"; + return new Promise(function(resolve, reject) { + window.addEventListener('message', event => resolve(event.data)); + }).then(data => { + assert_equals(data.errorMsg, + 'TypeError: Unable to open a contact selector'); + }); + +}, 'Test contacts.select() on a sub-frame') + +</script>
diff --git a/third_party/blink/web_tests/http/tests/preload/preload-media-disabled.html b/third_party/blink/web_tests/http/tests/preload/preload-media-disabled.html new file mode 100644 index 0000000..0ced5ee --- /dev/null +++ b/third_party/blink/web_tests/http/tests/preload/preload-media-disabled.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<link rel=preload href="../resources/test.oga" as=audio> +<link rel=preload href="../resources/test.mp4" as=video> + +<script> +var t = async_test("Ensure preloads don't respect as 'video' or 'audio' until https://github.com/w3c/preload/issues/97 is resolved and implemented."); +window.addEventListener("load", t.step_func(function() { + if (window.internals) { + assert_false(internals.isPreloaded('../resources/test.oga'), "audio should not be preloaded."); + assert_false(internals.isPreloaded('../resources/test.mp4'), "videos should not be preloaded."); + t.done(); + } +})); +</script> +
diff --git a/third_party/blink/web_tests/http/tests/priorities/resource-load-priorities.html b/third_party/blink/web_tests/http/tests/priorities/resource-load-priorities.html index 139487e3..4c4917f 100644 --- a/third_party/blink/web_tests/http/tests/priorities/resource-load-priorities.html +++ b/third_party/blink/web_tests/http/tests/priorities/resource-load-priorities.html
@@ -73,14 +73,6 @@ 'Preloaded fonts should be loaded with kHigh priority'); resource_load_priority_test( - 'preload/as-audio.html', kLow, - 'Preloaded audio files should be loaded with kLow priority'); - -resource_load_priority_test( - 'preload/as-video.html', kLow, - 'Preloaded videos should be loaded with kLow priority'); - -resource_load_priority_test( 'preload/as-fetch.html', kHigh, 'Preloaded fetches should be loaded with kHigh priority');
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 99c531c..f74ce0c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -30485,6 +30485,7 @@ <int value="6" label="IME tray"/> <int value="7" label="Notification tray"/> <int value="8" label="Lock screen note action button"/> + <int value="9" label="Parent access button"/> </enum> <enum name="LoginConsumerWhitelist">
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index c76a84b..4e2795c 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -637,6 +637,46 @@ } }; +/** + * Set up eject button if needed. + * @param {HTMLElement} rowElement The parent element for eject button. + * @private + */ +DirectoryItem.prototype.setupEjectButton_ = function(rowElement) { + const ejectButton = cr.doc.createElement('button'); + // Block other mouse handlers. + ejectButton.addEventListener('mouseup', (event) => { + event.stopPropagation(); + }); + ejectButton.addEventListener('up', (event) => { + event.stopPropagation(); + }); + ejectButton.addEventListener('mousedown', (event) => { + event.stopPropagation(); + }); + ejectButton.addEventListener('down', (event) => { + event.stopPropagation(); + }); + ejectButton.className = 'root-eject'; + ejectButton.setAttribute('aria-label', str('UNMOUNT_DEVICE_BUTTON_LABEL')); + ejectButton.setAttribute('tabindex', '0'); + ejectButton.addEventListener('click', (event) => { + event.stopPropagation(); + const unmountCommand = cr.doc.querySelector('command#unmount'); + // Let's make sure 'canExecute' state of the command is properly set for + // the root before executing it. + unmountCommand.canExecuteChange(this); + unmountCommand.execute(this); + }); + rowElement.appendChild(ejectButton); + + // Add paper-ripple effect on the eject button. + const ripple = cr.doc.createElement('paper-ripple'); + ripple.setAttribute('fit', ''); + ripple.className = 'circle recenteringTouch'; + ejectButton.appendChild(ripple); +}; + //////////////////////////////////////////////////////////////////////////////// // SubDirectoryItem @@ -1035,46 +1075,6 @@ }; /** - * Set up eject button if needed. - * @param {HTMLElement} rowElement The parent element for eject button. - * @private - */ -VolumeItem.prototype.setupEjectButton_ = function(rowElement) { - const ejectButton = cr.doc.createElement('button'); - // Block other mouse handlers. - ejectButton.addEventListener('mouseup', (event) => { - event.stopPropagation(); - }); - ejectButton.addEventListener('up', (event) => { - event.stopPropagation(); - }); - ejectButton.addEventListener('mousedown', (event) => { - event.stopPropagation(); - }); - ejectButton.addEventListener('down', (event) => { - event.stopPropagation(); - }); - ejectButton.className = 'root-eject'; - ejectButton.setAttribute('aria-label', str('UNMOUNT_DEVICE_BUTTON_LABEL')); - ejectButton.setAttribute('tabindex', '0'); - ejectButton.addEventListener('click', (event) => { - event.stopPropagation(); - const unmountCommand = cr.doc.querySelector('command#unmount'); - // Let's make sure 'canExecute' state of the command is properly set for - // the root before executing it. - unmountCommand.canExecuteChange(this); - unmountCommand.execute(this); - }); - rowElement.appendChild(ejectButton); - - // Add paper-ripple effect on the eject button. - const ripple = cr.doc.createElement('paper-ripple'); - ripple.setAttribute('fit', ''); - ripple.className = 'circle recenteringTouch'; - ejectButton.appendChild(ripple); -}; - -/** * Set up rename input textbox placeholder if needed. * @param {HTMLElement} rowElement The parent element for placeholder. * @private
diff --git a/ui/gfx/linux/native_pixmap_dmabuf.cc b/ui/gfx/linux/native_pixmap_dmabuf.cc index ec9592a..c60d9631 100644 --- a/ui/gfx/linux/native_pixmap_dmabuf.cc +++ b/ui/gfx/linux/native_pixmap_dmabuf.cc
@@ -12,6 +12,7 @@ gfx::BufferFormat format, const gfx::NativePixmapHandle& handle) : size_(size), format_(format), planes_(handle.planes) { + DCHECK_EQ(handle.planes.size(), handle.fds.size()); for (auto& fd : handle.fds) { fds_.emplace_back(fd.fd); } @@ -30,10 +31,6 @@ return true; } -size_t NativePixmapDmaBuf::GetDmaBufFdCount() const { - return fds_.size(); -} - int NativePixmapDmaBuf::GetDmaBufFd(size_t plane) const { DCHECK_LT(plane, fds_.size()); return fds_[plane].get();
diff --git a/ui/gfx/linux/native_pixmap_dmabuf.h b/ui/gfx/linux/native_pixmap_dmabuf.h index ce7f17a..0a59aed7 100644 --- a/ui/gfx/linux/native_pixmap_dmabuf.h +++ b/ui/gfx/linux/native_pixmap_dmabuf.h
@@ -29,7 +29,6 @@ // NativePixmap: bool AreDmaBufFdsValid() const override; - size_t GetDmaBufFdCount() const override; int GetDmaBufFd(size_t plane) const override; int GetDmaBufPitch(size_t plane) const override; int GetDmaBufOffset(size_t plane) const override;
diff --git a/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc b/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc index c6759702..a22ab64 100644 --- a/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc +++ b/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc
@@ -5,15 +5,19 @@ #include "ui/gfx/linux/native_pixmap_dmabuf.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/buffer_format_util.h" namespace gfx { -class NativePixmapDmabufTest : public testing::Test { +class NativePixmapDmaBufTest + : public ::testing::TestWithParam<gfx::BufferFormat> { protected: - gfx::NativePixmapHandle CreateMockNativePixmapHandle(gfx::Size image_size) { + gfx::NativePixmapHandle CreateMockNativePixmapHandle( + gfx::Size image_size, + const gfx::BufferFormat format) { gfx::NativePixmapHandle handle; - - for (int i = 0; i < 4; ++i) { + const int num_planes = gfx::NumberOfPlanesForBufferFormat(format); + for (int i = 0; i < num_planes; ++i) { // These values are arbitrarily chosen to be different from each other. const int stride = (i + 1) * image_size.width(); const int offset = i * image_size.width() * image_size.height(); @@ -30,13 +34,18 @@ } }; +INSTANTIATE_TEST_CASE_P(ConvertTest, + NativePixmapDmaBufTest, + ::testing::Values(gfx::BufferFormat::RGBX_8888, + gfx::BufferFormat::YVU_420)); + // Verifies NativePixmapDmaBuf conversion from and to NativePixmapHandle. -TEST_F(NativePixmapDmabufTest, Convert) { +TEST_P(NativePixmapDmaBufTest, Convert) { + const gfx::BufferFormat format = GetParam(); const gfx::Size image_size(128, 64); - const gfx::BufferFormat format = gfx::BufferFormat::RGBX_8888; gfx::NativePixmapHandle origin_handle = - CreateMockNativePixmapHandle(image_size); + CreateMockNativePixmapHandle(image_size, format); // NativePixmapHandle to NativePixmapDmabuf scoped_refptr<gfx::NativePixmap> native_pixmap_dmabuf( @@ -45,7 +54,9 @@ // NativePixmap to NativePixmapHandle. gfx::NativePixmapHandle handle; - for (size_t i = 0; i < native_pixmap_dmabuf->GetDmaBufFdCount(); ++i) { + const size_t num_planes = gfx::NumberOfPlanesForBufferFormat( + native_pixmap_dmabuf->GetBufferFormat()); + for (size_t i = 0; i < num_planes; ++i) { handle.fds.emplace_back(base::FileDescriptor( native_pixmap_dmabuf->GetDmaBufFd(i), true /* auto_close */));
diff --git a/ui/gfx/native_pixmap.h b/ui/gfx/native_pixmap.h index a4cbe0b0..f8ba1fd 100644 --- a/ui/gfx/native_pixmap.h +++ b/ui/gfx/native_pixmap.h
@@ -26,9 +26,6 @@ NativePixmap() {} virtual bool AreDmaBufFdsValid() const = 0; - // TODO(crbug.com/911370): Remove this because the number of fds will always - // be equal to the number of planes. - virtual size_t GetDmaBufFdCount() const = 0; virtual int GetDmaBufFd(size_t plane) const = 0; virtual int GetDmaBufPitch(size_t plane) const = 0; virtual int GetDmaBufOffset(size_t plane) const = 0;
diff --git a/ui/login/account_picker/md_screen_account_picker.js b/ui/login/account_picker/md_screen_account_picker.js index 146f4b2..c7f0fb9 100644 --- a/ui/login/account_picker/md_screen_account_picker.js +++ b/ui/login/account_picker/md_screen_account_picker.js
@@ -31,7 +31,6 @@ 'showAppError', 'updateUserImage', 'setCapsLockState', - 'forceLockedUserPodFocus', 'removeUser', 'showBannerMessage', 'showUserPodCustomIcon', @@ -105,20 +104,6 @@ $('pod-row').togglePodBackground(showPodBackground); }, - /** - * When the account picker is being used to lock the screen, pressing the - * exit accelerator key will sign out the active user as it would when - * they are signed in. - */ - exit: function() { - // Check and disable the sign out button so that we can never have two - // sign out requests generated in a row. - if ($('pod-row').lockedPod && !$('sign-out-user-button').disabled) { - $('sign-out-user-button').disabled = true; - chrome.send('signOutUser'); - } - }, - /* Cancel user adding if ESC was pressed. */ cancel: function() { @@ -347,15 +332,6 @@ }, /** - * Enforces focus on user pod of locked user. - */ - forceLockedUserPodFocus: function() { - var row = $('pod-row'); - if (row.lockedPod) - row.focusPod(row.lockedPod, true); - }, - - /** * Remove given user from pod row if it is there. * @param {string} user name. */
diff --git a/ui/login/account_picker/md_user_pod_row.js b/ui/login/account_picker/md_user_pod_row.js index 8729f799..ef413054 100644 --- a/ui/login/account_picker/md_user_pod_row.js +++ b/ui/login/account_picker/md_user_pod_row.js
@@ -4595,18 +4595,6 @@ }, /** - * The pod of the signed-in user, if any; null otherwise. - * @type {?UserPod} - */ - get lockedPod() { - for (var i = 0, pod; pod = this.pods[i]; ++i) { - if (pod.user.signedIn) - return pod; - } - return null; - }, - - /** * The pod that is preselected on user pod row show. * @type {?UserPod} */ @@ -4629,9 +4617,6 @@ return null; } - var lockedPod = this.lockedPod; - if (lockedPod) - return lockedPod; for (i = 0; pod = this.pods[i]; ++i) { if (!pod.multiProfilesPolicyApplied) return pod;
diff --git a/ui/login/account_picker/screen_account_picker.js b/ui/login/account_picker/screen_account_picker.js index ed42b4a..7867bd4 100644 --- a/ui/login/account_picker/screen_account_picker.js +++ b/ui/login/account_picker/screen_account_picker.js
@@ -30,7 +30,6 @@ 'showAppError', 'updateUserImage', 'setCapsLockState', - 'forceLockedUserPodFocus', 'removeUser', 'showBannerMessage', 'showUserPodCustomIcon', @@ -89,20 +88,6 @@ this.preferredHeight_ = height; }, - /** - * When the account picker is being used to lock the screen, pressing the - * exit accelerator key will sign out the active user as it would when - * they are signed in. - */ - exit: function() { - // Check and disable the sign out button so that we can never have two - // sign out requests generated in a row. - if ($('pod-row').lockedPod && !$('sign-out-user-button').disabled) { - $('sign-out-user-button').disabled = true; - chrome.send('signOutUser'); - } - }, - /* Cancel user adding if ESC was pressed. */ cancel: function() { @@ -340,15 +325,6 @@ }, /** - * Enforces focus on user pod of locked user. - */ - forceLockedUserPodFocus: function() { - var row = $('pod-row'); - if (row.lockedPod) - row.focusPod(row.lockedPod, true); - }, - - /** * Remove given user from pod row if it is there. * @param {string} user name. */
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js index 14a00d3b..4c3ff254 100644 --- a/ui/login/account_picker/user_pod_row.js +++ b/ui/login/account_picker/user_pod_row.js
@@ -3577,18 +3577,6 @@ }, /** - * The pod of the signed-in user, if any; null otherwise. - * @type {?UserPod} - */ - get lockedPod() { - for (var i = 0, pod; pod = this.pods[i]; ++i) { - if (pod.user.signedIn) - return pod; - } - return null; - }, - - /** * The pod that is preselected on user pod row show. * @type {?UserPod} */ @@ -3611,9 +3599,6 @@ return null; } - var lockedPod = this.lockedPod; - if (lockedPod) - return lockedPod; for (i = 0; pod = this.pods[i]; ++i) { if (!pod.multiProfilesPolicyApplied) return pod;
diff --git a/ui/ozone/common/linux/gbm_buffer.h b/ui/ozone/common/linux/gbm_buffer.h index e72b531..cad6f6b 100644 --- a/ui/ozone/common/linux/gbm_buffer.h +++ b/ui/ozone/common/linux/gbm_buffer.h
@@ -23,9 +23,6 @@ virtual uint32_t GetFormat() const = 0; virtual uint64_t GetFormatModifier() const = 0; virtual uint32_t GetFlags() const = 0; - // TODO(crbug.com/911370): Remove this because the number of fds will always - // be equal to the number of planes. - virtual size_t GetFdCount() const = 0; // TODO(reveman): This should not be needed once crbug.com/597932 is // fixed, as the size would be queried directly from the underlying bo. virtual gfx::Size GetSize() const = 0;
diff --git a/ui/ozone/common/linux/gbm_wrapper.cc b/ui/ozone/common/linux/gbm_wrapper.cc index 0e0a9b56..b5d8d40 100644 --- a/ui/ozone/common/linux/gbm_wrapper.cc +++ b/ui/ozone/common/linux/gbm_wrapper.cc
@@ -50,7 +50,6 @@ uint32_t GetFormat() const override { return format_; } uint64_t GetFormatModifier() const override { return format_modifier_; } uint32_t GetFlags() const override { return flags_; } - size_t GetFdCount() const override { return fds_.size(); } // TODO(reveman): This should not be needed once crbug.com/597932 is fixed, // as the size would be queried directly from the underlying bo. gfx::Size GetSize() const override { return size_; }
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index 18093f9..3bca913 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -49,7 +49,6 @@ CastPixmap() {} bool AreDmaBufFdsValid() const override { return false; } - size_t GetDmaBufFdCount() const override { return 0; } int GetDmaBufFd(size_t plane) const override { return -1; } int GetDmaBufPitch(size_t plane) const override { return 0; } int GetDmaBufOffset(size_t plane) const override { return 0; }
diff --git a/ui/ozone/platform/drm/gpu/gbm_pixmap.cc b/ui/ozone/platform/drm/gpu/gbm_pixmap.cc index a79897a7..17463810 100644 --- a/ui/ozone/platform/drm/gpu/gbm_pixmap.cc +++ b/ui/ozone/platform/drm/gpu/gbm_pixmap.cc
@@ -30,10 +30,6 @@ return buffer_->AreFdsValid(); } -size_t GbmPixmap::GetDmaBufFdCount() const { - return buffer_->GetFdCount(); -} - int GbmPixmap::GetDmaBufFd(size_t plane) const { return buffer_->GetPlaneFd(plane); }
diff --git a/ui/ozone/platform/drm/gpu/gbm_pixmap.h b/ui/ozone/platform/drm/gpu/gbm_pixmap.h index 91b9b93..6646759 100644 --- a/ui/ozone/platform/drm/gpu/gbm_pixmap.h +++ b/ui/ozone/platform/drm/gpu/gbm_pixmap.h
@@ -25,7 +25,6 @@ // NativePixmap: bool AreDmaBufFdsValid() const override; - size_t GetDmaBufFdCount() const override; int GetDmaBufFd(size_t plane) const override; int GetDmaBufPitch(size_t plane) const override; int GetDmaBufOffset(size_t plane) const override;
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc index c9c5c56..55a2d8f 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -172,7 +172,7 @@ } DCHECK(buffer->AreFdsValid()); - DCHECK_EQ(buffer->GetFdCount(), 1U); + DCHECK_EQ(buffer->GetNumPlanes(), 1U); base::ScopedFD vk_image_fd(dup(buffer->GetPlaneFd(0))); DCHECK(vk_image_fd.is_valid());
diff --git a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc index dc640dd1..713478e2 100644 --- a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc
@@ -37,7 +37,6 @@ uint32_t GetFormat() const override { return format_; } uint64_t GetFormatModifier() const override { return format_modifier_; } uint32_t GetFlags() const override { return flags_; } - size_t GetFdCount() const override { return 0; } gfx::Size GetSize() const override { return size_; } gfx::BufferFormat GetBufferFormat() const override { return ui::GetBufferFormatFromFourCCFormat(format_);
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index 0c1e1187..d1ef15f 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -80,7 +80,6 @@ explicit TestPixmap(gfx::BufferFormat format) : format_(format) {} bool AreDmaBufFdsValid() const override { return false; } - size_t GetDmaBufFdCount() const override { return 0; } int GetDmaBufFd(size_t plane) const override { return -1; } int GetDmaBufPitch(size_t plane) const override { return 0; } int GetDmaBufOffset(size_t plane) const override { return 0; }
diff --git a/ui/ozone/platform/scenic/scenic_surface_factory.cc b/ui/ozone/platform/scenic/scenic_surface_factory.cc index 5bca937..ed0c5e4 100644 --- a/ui/ozone/platform/scenic/scenic_surface_factory.cc +++ b/ui/ozone/platform/scenic/scenic_surface_factory.cc
@@ -73,7 +73,6 @@ } bool AreDmaBufFdsValid() const override { return false; } - size_t GetDmaBufFdCount() const override { return 0; } int GetDmaBufFd(size_t plane) const override { return -1; } int GetDmaBufPitch(size_t plane) const override { return 0; } int GetDmaBufOffset(size_t plane) const override { return 0; }
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 29a47cd..e19abd7 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -29,6 +29,8 @@ "wayland_connection_connector.h", "wayland_cursor.cc", "wayland_cursor.h", + "wayland_cursor_position.cc", + "wayland_cursor_position.h", "wayland_data_device.cc", "wayland_data_device.h", "wayland_data_device_manager.cc",
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc index 8c662b9..ad8f454f 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
@@ -80,10 +80,6 @@ return gbm_bo_->AreFdsValid(); } -size_t GbmPixmapWayland::GetDmaBufFdCount() const { - return gbm_bo_->GetFdCount(); -} - int GbmPixmapWayland::GetDmaBufFd(size_t plane) const { return gbm_bo_->GetPlaneFd(plane); } @@ -134,17 +130,19 @@ // TODO(dcastagna): Use gbm_bo_get_num_planes once all the formats we use are // supported by gbm. - for (size_t i = 0; i < gfx::NumberOfPlanesForBufferFormat(format); ++i) { - // Some formats (e.g: YVU_420) might have less than one fd per plane. - if (i < GetDmaBufFdCount()) { - base::ScopedFD scoped_fd(HANDLE_EINTR(dup(GetDmaBufFd(i)))); - if (!scoped_fd.is_valid()) { - PLOG(ERROR) << "dup"; - return gfx::NativePixmapHandle(); - } - handle.fds.emplace_back( - base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); + const size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); + std::vector<base::ScopedFD> scoped_fds(num_planes); + for (size_t i = 0; i < num_planes; ++i) { + scoped_fds[i] = base::ScopedFD(HANDLE_EINTR(dup(GetDmaBufFd(i)))); + if (!scoped_fds[i].is_valid()) { + PLOG(ERROR) << "dup"; + return gfx::NativePixmapHandle(); } + } + + for (size_t i = 0; i < num_planes; ++i) { + handle.fds.emplace_back( + base::FileDescriptor(scoped_fds[i].release(), true /* auto_close */)); handle.planes.emplace_back(GetDmaBufPitch(i), GetDmaBufOffset(i), gbm_bo_->GetPlaneSize(i), GetDmaBufModifier(i)); }
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h index 6998041..3c191ce 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
@@ -31,7 +31,6 @@ // gfx::NativePixmap overrides: bool AreDmaBufFdsValid() const override; - size_t GetDmaBufFdCount() const override; int GetDmaBufFd(size_t plane) const override; int GetDmaBufPitch(size_t plane) const override; int GetDmaBufOffset(size_t plane) const override;
diff --git a/ui/ozone/platform/wayland/wayland_connection.cc b/ui/ozone/platform/wayland/wayland_connection.cc index 7b1f5bf..e963c49 100644 --- a/ui/ozone/platform/wayland/wayland_connection.cc +++ b/ui/ozone/platform/wayland/wayland_connection.cc
@@ -125,6 +125,20 @@ return it == window_map_.end() ? nullptr : it->second; } +WaylandWindow* WaylandConnection::GetWindowWithLargestBounds() { + WaylandWindow* window_with_largest_bounds = nullptr; + for (auto entry : window_map_) { + if (!window_with_largest_bounds) { + window_with_largest_bounds = entry.second; + continue; + } + WaylandWindow* window = entry.second; + if (window_with_largest_bounds->GetBounds() < window->GetBounds()) + window_with_largest_bounds = window; + } + return window_with_largest_bounds; +} + WaylandWindow* WaylandConnection::GetCurrentFocusedWindow() { for (auto entry : window_map_) { WaylandWindow* window = entry.second; @@ -507,9 +521,13 @@ pointer, base::BindRepeating(&WaylandConnection::DispatchUiEvent, base::Unretained(connection))); connection->pointer_->set_connection(connection); + + connection->wayland_cursor_position_ = + std::make_unique<WaylandCursorPosition>(); } } else if (connection->pointer_) { connection->pointer_.reset(); + connection->wayland_cursor_position_.reset(); } if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { if (!connection->keyboard_) {
diff --git a/ui/ozone/platform/wayland/wayland_connection.h b/ui/ozone/platform/wayland/wayland_connection.h index f7e0962..61c6940 100644 --- a/ui/ozone/platform/wayland/wayland_connection.h +++ b/ui/ozone/platform/wayland/wayland_connection.h
@@ -13,6 +13,7 @@ #include "ui/events/platform/platform_event_source.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/wayland/wayland_cursor_position.h" #include "ui/ozone/platform/wayland/wayland_data_device.h" #include "ui/ozone/platform/wayland/wayland_data_device_manager.h" #include "ui/ozone/platform/wayland/wayland_data_source.h" @@ -86,6 +87,7 @@ } WaylandWindow* GetWindow(gfx::AcceleratedWidget widget); + WaylandWindow* GetWindowWithLargestBounds(); WaylandWindow* GetCurrentFocusedWindow(); WaylandWindow* GetCurrentKeyboardFocusedWindow(); void AddWindow(gfx::AcceleratedWidget widget, WaylandWindow* window); @@ -108,6 +110,11 @@ return wayland_output_manager_.get(); } + // Returns the cursor position, which may be null. + WaylandCursorPosition* wayland_cursor_position() { + return wayland_cursor_position_.get(); + } + // Clipboard implementation. PlatformClipboard* GetPlatformClipboard(); void DataSourceCancelled(); @@ -214,6 +221,7 @@ std::unique_ptr<WaylandOutputManager> wayland_output_manager_; std::unique_ptr<WaylandPointer> pointer_; std::unique_ptr<WaylandTouch> touch_; + std::unique_ptr<WaylandCursorPosition> wayland_cursor_position_; // Objects that are using when GPU runs in own process. std::unique_ptr<WaylandBufferManager> buffer_manager_;
diff --git a/ui/ozone/platform/wayland/wayland_cursor_position.cc b/ui/ozone/platform/wayland/wayland_cursor_position.cc new file mode 100644 index 0000000..97cb640 --- /dev/null +++ b/ui/ozone/platform/wayland/wayland_cursor_position.cc
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/wayland/wayland_cursor_position.h" + +#include "ui/ozone/platform/wayland/wayland_connection.h" + +namespace ui { + +WaylandCursorPosition::WaylandCursorPosition() = default; + +WaylandCursorPosition::~WaylandCursorPosition() = default; + +void WaylandCursorPosition::OnCursorPositionChanged( + const gfx::Point& cursor_position) { + cursor_surface_point_ = cursor_position; +} + +gfx::Point WaylandCursorPosition::GetCursorSurfacePoint() const { + return cursor_surface_point_; +} + +} // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_cursor_position.h b/ui/ozone/platform/wayland/wayland_cursor_position.h new file mode 100644 index 0000000..123ed9c --- /dev/null +++ b/ui/ozone/platform/wayland/wayland_cursor_position.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CURSOR_POSITION_H_ +#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CURSOR_POSITION_H_ + +#include "base/macros.h" +#include "ui/gfx/geometry/point.h" + +namespace ui { + +// Stores last known cursor pointer position in regards to top-level windows' +// coordinates and returns it on request. +class WaylandCursorPosition { + public: + WaylandCursorPosition(); + ~WaylandCursorPosition(); + + void OnCursorPositionChanged(const gfx::Point& cursor_position); + + // Returns last known cursor position in regards to top-level surface local + // coordinates. It is unknown what surface receives that cursor position. + gfx::Point GetCursorSurfacePoint() const; + + private: + gfx::Point cursor_surface_point_; + + DISALLOW_COPY_AND_ASSIGN(WaylandCursorPosition); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CURSOR_POSITION_H_
diff --git a/ui/ozone/platform/wayland/wayland_screen.cc b/ui/ozone/platform/wayland/wayland_screen.cc index a3561bf..a7a0b8b 100644 --- a/ui/ozone/platform/wayland/wayland_screen.cc +++ b/ui/ozone/platform/wayland/wayland_screen.cc
@@ -10,6 +10,7 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" #include "ui/ozone/platform/wayland/wayland_connection.h" +#include "ui/ozone/platform/wayland/wayland_cursor_position.h" #include "ui/ozone/platform/wayland/wayland_window.h" namespace ui { @@ -129,8 +130,23 @@ } gfx::Point WaylandScreen::GetCursorScreenPoint() const { - NOTIMPLEMENTED_LOG_ONCE(); - return gfx::Point(); + // Wayland does not provide either location of surfaces in global space + // coordinate system or location of a pointer. Instead, only locations of + // mouse/touch events are known. Given that Chromium assumes top-level windows + // are located at origin, always provide a cursor point in regards to + // surfaces' location. + // + // If a pointer is located in any of the existing wayland windows, return the + // last known cursor position. Otherwise, return such a point, which is not + // contained by any of the windows. + auto* cursor_position = connection_->wayland_cursor_position(); + if (connection_->GetCurrentFocusedWindow() && cursor_position) + return cursor_position->GetCursorSurfacePoint(); + + WaylandWindow* window = connection_->GetWindowWithLargestBounds(); + DCHECK(window); + const gfx::Rect bounds = window->GetBounds(); + return gfx::Point(bounds.width() + 10, bounds.height() + 10); } gfx::AcceleratedWidget WaylandScreen::GetAcceleratedWidgetAtScreenPoint( @@ -150,12 +166,13 @@ display::Display WaylandScreen::GetDisplayMatching( const gfx::Rect& match_rect) const { + if (match_rect.IsEmpty()) + return GetDisplayNearestPoint(match_rect.origin()); + const display::Display* display_matching = display::FindDisplayWithBiggestIntersection(display_list_.displays(), match_rect); - if (!display_matching) - return display::Display(); - return *display_matching; + return display_matching ? *display_matching : GetPrimaryDisplay(); } void WaylandScreen::AddObserver(display::DisplayObserver* observer) {
diff --git a/ui/ozone/platform/wayland/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/wayland_screen_unittest.cc index 9055e383..723b2e68 100644 --- a/ui/ozone/platform/wayland/wayland_screen_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_screen_unittest.cc
@@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include <wayland-server.h> #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display_observer.h" #include "ui/ozone/platform/wayland/fake_server.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" +#include "ui/ozone/platform/wayland/test/test_pointer.h" #include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_output_manager.h" #include "ui/ozone/platform/wayland/wayland_screen.h" @@ -341,9 +344,10 @@ Sync(); - // The match rect is located outside the displays. + // The match rect is located outside the displays. Primary display must be + // returned. EXPECT_EQ( - display::kInvalidDisplayId, + primary_display.id(), platform_screen_->GetDisplayMatching(gfx::Rect(1024, 0, 10, 10)).id()); // At least some of the pixels are located on the display. @@ -356,6 +360,10 @@ second_display.id(), platform_screen_->GetDisplayMatching(gfx::Rect(1023, 695, 10, 10)).id()); + // Empty rect results in primary display. + EXPECT_EQ(primary_display.id(), + platform_screen_->GetDisplayMatching(gfx::Rect(0, 0, 0, 0)).id()); + platform_screen_->RemoveObserver(&observer); } @@ -425,6 +433,154 @@ ValidateTheDisplayForWidget(widget, secondary_display.id()); } +TEST_P(WaylandScreenTest, GetCursorScreenPoint) { + MockPlatformWindowDelegate delegate; + std::unique_ptr<WaylandWindow> second_window = + CreateWaylandWindowWithProperties(gfx::Rect(0, 0, 1920, 1080), + PlatformWindowType::kWindow, + gfx::kNullAcceleratedWidget, &delegate); + + auto* surface = server_.GetObject<wl::MockSurface>(window_->GetWidget()); + ASSERT_TRUE(surface); + + // Announce pointer capability so that WaylandPointer is created on the client + // side. + wl_seat_send_capabilities(server_.seat()->resource(), + WL_SEAT_CAPABILITY_POINTER); + + Sync(); + + wl::TestPointer* pointer = server_.seat()->pointer(); + ASSERT_TRUE(pointer); + + uint32_t serial = 0; + uint32_t time = 1002; + wl_pointer_send_enter(pointer->resource(), ++serial, surface->resource(), 0, + 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(10), + wl_fixed_from_int(20)); + + Sync(); + + // WaylandScreen must return the last pointer location. + EXPECT_EQ(gfx::Point(10, 20), platform_screen_->GetCursorScreenPoint()); + + auto* second_surface = + server_.GetObject<wl::MockSurface>(second_window->GetWidget()); + ASSERT_TRUE(second_surface); + // Now, leave the first surface and enter second one. + wl_pointer_send_leave(pointer->resource(), ++serial, surface->resource()); + wl_pointer_send_enter(pointer->resource(), ++serial, + second_surface->resource(), 0, 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(20), + wl_fixed_from_int(10)); + + Sync(); + + // WaylandScreen must return the last pointer location. + EXPECT_EQ(gfx::Point(20, 10), platform_screen_->GetCursorScreenPoint()); + + // Clear pointer focus. + wl_pointer_send_leave(pointer->resource(), ++serial, + second_surface->resource()); + + Sync(); + + // WaylandScreen must return a point, which is located outside of bounds of + // any window. Basically, it means that it takes the largest window and adds + // 10 pixels to its width and height, and returns the value. + const gfx::Rect second_window_bounds = second_window->GetBounds(); + // A second window has largest bounds. Thus, these bounds must be taken as a + // ground for the point outside any of the surfaces. + ASSERT_TRUE(window_->GetBounds() < second_window_bounds); + EXPECT_EQ(gfx::Point(second_window_bounds.width() + 10, + second_window_bounds.height() + 10), + platform_screen_->GetCursorScreenPoint()); + + // Create a menu window now and ensure cursor position is always sent in + // regards to that window bounds. + std::unique_ptr<WaylandWindow> menu_window = + CreateWaylandWindowWithProperties( + gfx::Rect(second_window_bounds.width() - 10, + second_window_bounds.height() - 10, 10, 20), + PlatformWindowType::kPopup, second_window->GetWidget(), &delegate); + + Sync(); + + auto* menu_surface = + server_.GetObject<wl::MockSurface>(menu_window->GetWidget()); + ASSERT_TRUE(menu_surface); + + wl_pointer_send_enter(pointer->resource(), ++serial, menu_surface->resource(), + 0, 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2), + wl_fixed_from_int(1)); + + Sync(); + + // The cursor screen point must be converted to the top-level window + // coordinates as long as Wayland doesn't provide global coordinates of + // surfaces and Chromium assumes those windows are always located at origin + // (0,0). For more information, check the comment in + // WaylandWindow::UpdateCursorPositionFromEvent. + EXPECT_EQ(gfx::Point(1912, 1071), platform_screen_->GetCursorScreenPoint()); + + // Leave the menu window and enter the top level window. + wl_pointer_send_leave(pointer->resource(), ++serial, + menu_surface->resource()); + wl_pointer_send_enter(pointer->resource(), ++serial, + second_surface->resource(), 0, 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(1912), + wl_fixed_from_int(1071)); + + Sync(); + + // WaylandWindow::UpdateCursorPositionFromEvent mustn't convert this point, + // because it has already been located on the top-level window. + EXPECT_EQ(gfx::Point(1912, 1071), platform_screen_->GetCursorScreenPoint()); + + wl_pointer_send_leave(pointer->resource(), ++serial, + second_surface->resource()); + + // Now, create a nested menu window and make sure that the cursor screen point + // still has been correct. The location of the window is on the right side of + // the main menu window. + const gfx::Rect menu_window_bounds = menu_window->GetBounds(); + std::unique_ptr<WaylandWindow> nested_menu_window = + CreateWaylandWindowWithProperties( + gfx::Rect(menu_window_bounds.x() + menu_window_bounds.width(), + menu_window_bounds.y() + 2, 10, 20), + PlatformWindowType::kPopup, second_window->GetWidget(), &delegate); + + Sync(); + + auto* nested_menu_surface = + server_.GetObject<wl::MockSurface>(nested_menu_window->GetWidget()); + ASSERT_TRUE(nested_menu_surface); + + wl_pointer_send_enter(pointer->resource(), ++serial, + nested_menu_surface->resource(), 0, 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2), + wl_fixed_from_int(3)); + + Sync(); + + EXPECT_EQ(gfx::Point(1922, 1075), platform_screen_->GetCursorScreenPoint()); + + // Leave the nested surface and enter main menu surface. The cursor screen + // point still must be reported correctly. + wl_pointer_send_leave(pointer->resource(), ++serial, + nested_menu_surface->resource()); + wl_pointer_send_enter(pointer->resource(), ++serial, menu_surface->resource(), + 0, 0); + wl_pointer_send_motion(pointer->resource(), ++time, wl_fixed_from_int(2), + wl_fixed_from_int(1)); + + Sync(); + + EXPECT_EQ(gfx::Point(1912, 1071), platform_screen_->GetCursorScreenPoint()); +} + INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test, WaylandScreenTest, ::testing::Values(kXdgShellV5));
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc index 82d6c016..32bf9bf 100644 --- a/ui/ozone/platform/wayland/wayland_window.cc +++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -4,6 +4,8 @@ #include "ui/ozone/platform/wayland/wayland_window.h" +#include <memory> + #include <wayland-client.h> #include "base/bind.h" @@ -16,6 +18,7 @@ #include "ui/events/ozone/events_ozone.h" #include "ui/gfx/geometry/point_f.h" #include "ui/ozone/platform/wayland/wayland_connection.h" +#include "ui/ozone/platform/wayland/wayland_cursor_position.h" #include "ui/ozone/platform/wayland/wayland_output_manager.h" #include "ui/ozone/platform/wayland/wayland_pointer.h" #include "ui/ozone/platform/wayland/xdg_popup_wrapper_v5.h" @@ -112,7 +115,6 @@ DCHECK(xdg_shell_objects_factory_); bounds_ = properties.bounds; - parent_window_ = GetParentWindow(properties.parent_widget); surface_.reset(wl_compositor_create_surface(connection_->compositor())); if (!surface_) { @@ -126,6 +128,8 @@ switch (ui_window_type) { case ui::PlatformWindowType::kMenu: case ui::PlatformWindowType::kPopup: + parent_window_ = GetParentWindow(properties.parent_widget); + // TODO(msisov, jkim): Handle notification windows, which are marked // as popup windows as well. Those are the windows that do not have // parents and pop up when the browser receives a notification. @@ -478,6 +482,12 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) { Event* event = static_cast<Event*>(native_event); + + if (event->IsLocatedEvent()) { + auto copied_event = Event::Clone(*event); + UpdateCursorPositionFromEvent(std::move(copied_event)); + } + // If the window does not have a pointer focus, but received this event, it // means the window is a popup window with a child popup window. In this case, // the location of the event must be converted from the nested popup to the @@ -679,6 +689,47 @@ entered_outputs_ids_.erase(entered_output_id_it); } +void WaylandWindow::UpdateCursorPositionFromEvent( + std::unique_ptr<Event> event) { + DCHECK(event->IsLocatedEvent()); + auto* window = connection_->GetCurrentFocusedWindow(); + // This is a tricky part. Initially, Wayland sends events to surfaces the + // events are targeted for. But, in order to fulfill Chromium's assumptions + // about event targets, some of the events are rerouted and their locations + // are converted. + // + // The event we got here is rerouted, but it hasn't had its location fixed + // yet. Passing an event with fixed location won't help as well - its location + // is converted in a different way: if mouse is moved outside a menu window + // to the left, the location of such event includes negative values. + // + // In contrast, this method must translate coordinates of all events + // in regards to top-level windows' coordinates as it's always located at + // origin (0,0) from Chromium point of view (remember that Wayland doesn't + // provide global coordinates to its clients). And it's totally fine to use it + // as the target. Thus, the location of the |event| is always converted using + // the top-level window's bounds as the target excluding cases, when the + // mouse/touch is over a top-level window. + if (parent_window_ && parent_window_ != window) { + const gfx::Rect target_bounds = parent_window_->GetBounds(); + gfx::Rect own_bounds = GetBounds(); + // This is a bit trickier, and concerns nested menu windows. Whenever an + // event is sent to the nested menu window, it's rerouted to a parent menu + // window. Thus, in order to correctly translate its location, we must + // choose correct values for the |own_bounds|. In this case, it must the + // nested menu window, because |this| is the parent of that window. + if (window == child_window_) + own_bounds = child_window_->GetBounds(); + ConvertEventLocationToTargetWindowLocation( + target_bounds.origin(), own_bounds.origin(), event->AsLocatedEvent()); + } + auto* cursor_position = connection_->wayland_cursor_position(); + if (cursor_position) { + cursor_position->OnCursorPositionChanged( + event->AsLocatedEvent()->location()); + } +} + // static void WaylandWindow::Enter(void* data, struct wl_surface* wl_surface,
diff --git a/ui/ozone/platform/wayland/wayland_window.h b/ui/ozone/platform/wayland/wayland_window.h index 4176c6a..dc5fa34 100644 --- a/ui/ozone/platform/wayland/wayland_window.h +++ b/ui/ozone/platform/wayland/wayland_window.h
@@ -170,6 +170,8 @@ void AddEnteredOutputId(struct wl_output* output); void RemoveEnteredOutputId(struct wl_output* output); + void UpdateCursorPositionFromEvent(std::unique_ptr<Event> event); + // wl_surface_listener static void Enter(void* data, struct wl_surface* wl_surface,